From: Daniel J S. <dan...@ie...> - 2014-02-09 18:20:04
|
On 02/09/2014 05:29 AM, Mojca Miklavec wrote: > On Sun, Feb 9, 2014 at 12:11 PM, Mojca Miklavec wrote: >> On Sun, Feb 9, 2014 at 1:19 AM, sfeam wrote: >>> On Sunday, 09 February 2014 01:01:20 AM Mojca Miklavec wrote: >>>>> Another possible test: >>>>> Change the timeout value on line 259 from >>>>> qt->socket.waitForConnected(200); >>>>> to >>>>> qt->socket.waitForConnected(-1); >>>>> >>>>> This could potentially cause gnuplot to hang, but it also might work >>>> >>>> Gnuplot runs at 99% CPU with or without that change (just gnuplot, >>>> gnuplot_qt doesn't consume any CPU at all after the first few >>>> seconds). >>> >>> gnuplot is spinning CPU cycles while waiting for a timeout? >>> The OSX implementation must really suck. >>> Anyhow if you can see the gnuplot_qt process but the waitForConnected >>> fails to return that's probably a huge clue to what's gone wrong. >>> Let me think about this for a while. >>> >>> I'm cc-ing Jérôme Lodewyck. Maybe he can decipher the clue. >> >> I don't know if that's a clue or not, but if I run gdb and manually >> press "n", only a single gnuplot_qt is started and gnuplot actually >> returns to the console (if I simply run gnuplot, it runs at 99% CPU >> "forever"). The first "plot sin(x)" doesn't show anything, but when I >> plot something for the second time, the plot is actually shown. >> >> So maybe there's just a problem of wrong >> timing/synchronisation/initialisation somewhere after all. >> >> The fact is that if I actually get to this point (by manually stepping >> inside gdb), it works a lot better than it did with forking: >> - printing doesn't crash >> - there is no need for the dirty hack removeDockIcon() >> TransformProcessType(&psn, kProcessTransformToBackgroundApplication); >> to hide the nofunctional window > > And indeed if I change the timeout: > > --- a/src/qtterminal/qt_term.cpp > +++ b/src/qtterminal/qt_term.cpp > @@ -251,7 +252,7 > > // The QLocalSocket::waitForConnected does not respect the > time out argument when the > // gnuplot_qt application is not yet started. To wait for it, > we need to implement the timeout ourselves > - QDateTime timeout = QDateTime::currentDateTime().addMSecs(1000); > + QDateTime timeout = QDateTime::currentDateTime().addMSecs(10000); > do > { > qt->socket.connectToServer(server); > > it suddenly almost starts working. I'm saying almost because the first > plot doesn't work, but the second one does. > > Terminal type set to 'qt' > gnuplot> plot sin(x) # nothing can be seen > started detached process "qtgnuplot31706" > gnuplot> plot cos(x) # works > gnuplot> > > It seems that gnuplot gives up too quickly. And if it does give up, > the second attempt to connect doesn't work properly, ends up with two > instances of gnuplot_qt running (none of them gets closed etc). > > According to a gdb a lot of that "infinite cycling" (when not properly > connected) happens with > > while (!receivedFontPropos) > qt->socket.waitForReadyRead(1000); > while (qt->socket.bytesAvailable()>= (int)sizeof(gp_event_t)) > } > > The following is "sampling" of the running gnuplot at 99% CPU: Trying my best to decipher, but I think it's getting close now. In a post that didn't make it here you added that you see this error: "Incorrect NSStringEncoding value 0x0000 detected." Looking at the debugger results below, it seems that qt_term.cpp is having problems at or near lines 423-424: > 748,772,... [0x1001da24c,0x1001da264,...] qt_term.cpp:424 > + 118 qt_sendFont() (in gnuplot) + > 737,713,... [0x1001da241,0x1001da229,...] qt_term.cpp:423 > + 110 and the code hunk around there is: while (!receivedFontPropos) { qt->socket.waitForReadyRead(1000); 423 while (qt->socket.bytesAvailable() >= (int)sizeof(gp_event_t)) 424 { gp_event_t event; qt->socket.read((char*) &event, sizeof(gp_event_t)); // Here, we discard other events than fontprops. if ((event.type == GE_fontprops) && (event.par1 > 0) && (event.par2 > 0)) { receivedFontPropos = true; metric = QPair<int, int>(event.par1, event.par2); fontMetricCache[currentFont] = metric; break; } } } So, some comments: 1) Ethan was likely correct about the timeout. The Qt documentation indicates the default timeout is 30 seconds. 1 second seems rather short. Especially in this case, as font setting/info is a system library and it is quite common for system level features to take up to five seconds or so to complete especially the first time the are called and loaded resident. Mojca, for a temporary measure to take this issue out of the picture, consider setting the timeout to the default 30 seconds (i.e., remove the argument 1000 from the function or change 1000 to 30000). 2) With the error you pointed out regarding NSStringEncoding, it would seem there might be an added delay because something isn't correct about qt_term's requested font info string. Perhaps the system font library can't find the metric information that is being sought and it takes a while to prep/search the system database. 3) On the other hand, that error you indicated could be what happens when qt->socket.waitForReadyRead(1000); while (qt->socket.bytesAvailable() >= (int)sizeof(gp_event_t)) fails. (Are you seeing that error when you add the really long wait period?) 4) When the above does fail (i.e., times out), what happens? It looks like QPair<int, int> metric; is uninitialized, or at least defaults to a zero pair. So, if the font info times out, what is the value of metric when used here? term->v_char = qt_oversampling*metric.first; term->h_char = qt_oversampling*metric.second; 5) Timeout should generally be treated a little more robustly especially given that Qt has some ready-made tools for displaying dialog boxes. Perhaps when timeout happens, display a warning dialog about canceling or continuing onward. Of course, that creates issues for gnuplot in non-interactive mode. In any case, this probably isn't critical with regard to the problems in functionality you are seeing. Dan > > Call graph: > 2510 Thread_2393718 DispatchQueue_1: com.apple.main-thread (serial) > + 2510 start (in gnuplot) + 52 [0x100011244] > + 2510 main (in gnuplot) + 2796 [0x1000aa62c] plot.c:672 > + 2510 com_line (in gnuplot) + 144 [0x100025140] command.c:323 > + 2510 do_line (in gnuplot) + 1066 [0x10002559a] command.c:411 > + 2510 command (in gnuplot) + 131 [0x100026283] command.c:616 > + 2510 plot_command (in gnuplot) + 206 [0x100028d1e] > command.c:1559 > + 2510 plotrequest (in gnuplot) + 1763 [0x1000abf83] > plot2d.c:273 > + 2510 eval_plots (in gnuplot) + 27828 > [0x1000c00c4] plot2d.c:3259 > + 2510 do_plot (in gnuplot) + 131 [0x100062843] > graphics.c:517 > + 2510 term_start_plot (in gnuplot) + 63 > [0x10011476f] term.c:557 > + 2510 qt_graphics (in gnuplot) + 669 > [0x1001da68d] qt_term.cpp:480 > + 1582 qt_sendFont() (in gnuplot) + 772 > [0x1001da264] qt_term.cpp:424 > + ! 962 QLocalSocket::bytesAvailable() const > (in QtNetwork) + 42 [0x1022520fa] > + ! : 646 QAbstractSocket::bytesAvailable() > const (in QtNetwork) + 16 [0x102245210] > + ! : | 646 QIODevice::bytesAvailable() > const (in QtCore) + 0,20,... [0x1030389a0,0x1030389b4,...] > + ! : 248 QAbstractSocket::bytesAvailable() > const (in QtNetwork) + 0,16,... [0x102245200,0x102245210,...] > + ! : 68 > DYLD-STUB$$QIODevice::bytesAvailable() const (in QtNetwork) + 0 > [0x10226ca8a] > + ! 295 QLocalSocket::bytesAvailable() const > (in QtNetwork) + 16 [0x1022520e0] > + ! : 295 QIODevice::bytesAvailable() const > (in QtCore) + 0,85,... [0x1030389a0,0x1030389f5,...] > + ! 236 QLocalSocket::bytesAvailable() const > (in QtNetwork) + 6,16,... [0x1022520d6,0x1022520e0,...] > + ! 89 > DYLD-STUB$$QIODevice::bytesAvailable() const (in QtNetwork) + 0 > [0x10226ca8a] > + 342 qt_sendFont() (in gnuplot) + 737 > [0x1001da241] qt_term.cpp:423 > + ! 195 QLocalSocket::waitForReadyRead(int) > (in QtNetwork) + 6,51,... [0x1022526c6,0x1022526f3,...] > + ! 147 QLocalSocket::waitForReadyRead(int) > (in QtNetwork) + 18 [0x1022526d2] > + ! 147 QLocalSocket::state() const (in > QtNetwork) + 0,8 [0x10224aed0,0x10224aed8] > + 180 qt_sendFont() (in gnuplot) + > 748,772,... [0x1001da24c,0x1001da264,...] qt_term.cpp:424 > + 118 qt_sendFont() (in gnuplot) + > 737,713,... [0x1001da241,0x1001da229,...] qt_term.cpp:423 > + 110 > DYLD-STUB$$QLocalSocket::waitForReadyRead(int) (in gnuplot) + 0 > [0x1001e38b6] > + 97 > DYLD-STUB$$QLocalSocket::bytesAvailable() const (in gnuplot) + 0 > [0x1001e38ec] > + 47 qt_sendFont() (in gnuplot) + 695 > [0x1001da217] qt_term.cpp:421 > + 34 qt_sendFont() (in gnuplot) + 999 > [0x1001da347] qt_term.cpp:437 > 2510 Thread_2393731 DispatchQueue_2: > com.apple.libdispatch-manager (serial) > + 2510 _dispatch_mgr_thread (in libdispatch.dylib) + 54 [0x7fff8c328316] > + 2510 _dispatch_mgr_invoke (in libdispatch.dylib) + 923 > [0x7fff8c329786] > + 2510 kevent (in libsystem_kernel.dylib) + 10 [0x7fff8b5e27e6] > 2510 Thread_2393735: QProcessManager > 2510 thread_start (in libsystem_c.dylib) + 13 [0x7fff89671b75] > 2510 _pthread_start (in libsystem_c.dylib) + 335 [0x7fff8966e8bf] > 2510 QThreadPrivate::start(void*) (in QtCore) + 504 [0x102fad238] > 2510 QProcessManager::run() (in QtCore) + 168 [0x10307d7b8] > 2510 __select (in libsystem_kernel.dylib) + 10 [0x7fff8b5e1df2] > > Total number in stack (recursive counted multiple, when>=5): > > Sort by top of stack, same collapsed (when>= 5): > __select (in libsystem_kernel.dylib) 2510 > kevent (in libsystem_kernel.dylib) 2510 > QIODevice::bytesAvailable() const (in QtCore) 941 > qt_sendFont() (in gnuplot) 379 > QAbstractSocket::bytesAvailable() const (in QtNetwork) 248 > QLocalSocket::bytesAvailable() const (in QtNetwork) 236 > QLocalSocket::waitForReadyRead(int) (in QtNetwork) 195 > DYLD-STUB$$QIODevice::bytesAvailable() const (in QtNetwork) 157 > QLocalSocket::state() const (in QtNetwork) 147 > DYLD-STUB$$QLocalSocket::waitForReadyRead(int) (in gnuplot) 110 > DYLD-STUB$$QLocalSocket::bytesAvailable() const (in gnuplot) 97 > > Mojca > |