Opened 9 years ago

Closed 9 years ago

#213 closed defect (fixed)

UIC hogs CPU

Reported by: rudi Owned by:
Priority: minor Milestone: Qt Enhanced
Component: Tools Version: 4.6.3
Severity: low Keywords:


When an UI file with CR+LF line endings is piped to UIC, UIC will hang eating 100% CPU. It looks like UIC generally doesn't like DOS-style line endings when used in pipe mode (see #212). However, while in Windows it simply does nothing in this scenario, in OS/2 the behavior is nasty.

Attachments (1)

driver.diff (507 bytes) - added by rudi 9 years ago.
Temporary fix

Download all attachments as: .zip

Change History (6)

comment:1 Changed 9 years ago by Dmitry A. Kuminov

Please give an exact command line that demonstrates the above behavior.

Running uic.exe test.ui (where test.ui is all CRLFs) doesn't demonstrate any hogging. Probably because #212 was fixed?

Last edited 9 years ago by Dmitry A. Kuminov (previous) (diff)

comment:2 Changed 9 years ago by rudi

Yes, this comment puzzles me as well. But given that they workaround this issue in UIC (and we added it for OS/2 as well in r917) they don't change the stdin/out/err mode on Windows. So I wonder why there is no hogging there. Did you actually find the exact line of code (or loop) in Qt sources that creates this hogging?

Yes. It's caused by
QFile::atEnd() will not return true, since d->cachedSize contains the size of the file including CRs, while pos() returns the size without counting CRs. Due to this mismatch, QFile::bytesAvailable() will return the number of CRs in the file. So we end up in the same tight loop we were in with the pipe closing.

IMHO, the file handle used by a QFile should never be in text mode. If text mode is required, then QIODevice::Text must be set.

As stated initially, this is broken in Windows as well and r917 only addresses the output, not the input stream. And now I understand why. Since stdout is in text mode as well, QIODevice::Text adds another CR/LF translation. IMHO they should have switched stdin and stderr to binary mode in order to provide consistent data to QFile instead of removing the QIODevice::Text flag...

I don't know, why we don't see the CPU hogging in Windows. BTW, there is some other strange difference:

uic < nul

On OS/2 UIC returns immediately with an "Premature end of document" error. On Windows, UIC just hangs and needs to be killed. I think we do it right...

Changed 9 years ago by rudi

Attachment: driver.diff added

Temporary fix

comment:3 Changed 9 years ago by Dmitry A. Kuminov

Nice finding.

And now I can explain this strange comment in the QFile::atEnd() documentation. The trick is that the real console device on Windows performs all kinds of CRLF fixup and normalization on its own. This means that if you write "line1\nline2\n", "line1\r\nline2\r\n"} or even "line1\r\r\nline2\r\r\n"} to fileno(stdout) when stdout is attached to the console, you will always get this:


This is why they say "Sequential devices, such as stdin and stdout, are unaffected by this limitation". This is true but only partly -- as long as these devices are not redirected to a file. If they are, the situation changes dramatically since noone performs CRLF normalization any longer.

Given this, in r932 I changed QFile docs and in r933 -- UIC.

Please check on your side.

comment:4 Changed 9 years ago by rudi

It's fine for me. Ticket can be closed.

comment:5 Changed 9 years ago by Dmitry A. Kuminov

Resolution: fixed
Status: newclosed
Note: See TracTickets for help on using tickets.