|
From: sfeam (E. Merritt) <eam...@gm...> - 2012-01-05 05:20:34
|
On Wednesday, 04 January 2012, Daniel J Sebald wrote: > On 01/04/2012 04:46 PM, Mojca Miklavec wrote: > > On Wed, Jan 4, 2012 at 23:09, Ethan A Merritt wrote: > >> Mojca Miklavec wrote> > >> I've just been debugging configuration problems with Qt 4.7.4, where it turns > >> out that I need to do the same thing in order to pick up locations for > >> the rcc and lrelease utilities. > >> > >>> - if I fix the two above, qt terminal compiles fine, but I cannot plot anything: > >>> > >>> gnuplot> plot sin(x) > >>> The process has forked and you cannot use this CoreFoundation > >>> functionality safely. You MUST exec(). > >>> Break on __THE_PROCESS_HAS_FORKED_AND_YOU_CANNOT_USE_THIS_COREFOUNDATION_FUNCTIONALITY___YOU_MUST_EXEC__() > >>> to debug.> > > > Last time I didn't find anything useful either. However google now > > pointed me to the following: > > > > http://gitorious.org/~friesoft/dinjam/friesoft-development/blobs/master/src/sources/data/standarddirs_mac.cpp > > > > /** > > Calling CoreFoundation APIs (which is unavoidable in Qt/Mac) has > > always had issues > > on Mac OS X, but as of 10.5 is explicitly disallowed with an exception. As a > > result, in the case where we would normally fork and then dlopen > > code, or continue > > to run other code, we must now fork-and-exec. > > So what you are seeing is the exception that OS X is now throwing when > it sees you fork() and then not exec(), apparently. My guess is this > might be a security measure in some way. (How? I don't know, just > guessing.) > > > > I would be willing to debug, but I have no idea how to do so. I > > created a ticket: > > https://sourceforge.net/tracker/?func=detail&aid=3469233&group_id=2055&atid=102055 > > where I attached crash report (I just realized where systems stores > > crash reports) if that is of any help, but I'm not sure neither how to > > debug nor how to fix anything. > > > > If you tell me how exactly to "exec()" after fork in qt_term.cpp, I > > can test it, but I don't fully understand the code, so I'm not sure > > what exactly to change and how. > > It appears that the fork() is in the qt_init() routine: > > 236 pid = fork(); > 237 if (pid < 0) > 238 fprintf(stderr, "Forking error\n"); > 239 else if (pid == 0) // Child: start the GUI > 240 { > 241 signal(SIGINT, SIG_IGN); // Do not listen to SIGINT > signals anymore > 242 > 243 #ifndef HAVE_QT_47 > 244 /* > 245 * FIXME: EAM Nov 2011 > 246 * It is better to use environmental variable > 247 * QT_GRAPHICSSYSTEM but this requires qt >= 4.7 > 248 * "raster" is ~5x faster than "native" (default). > 249 * Unfortunately "opengl" isn't recognized on my > test systems :-( > 250 */ > 251 // This makes a huge difference to the speed of > polygon rendering. > 252 // Alternatives are "native", "raster", "opengl" > 253 QApplication::setGraphicsSystem("raster"); > 254 #endif > 255 > 256 QtGnuplotApplication application(argc, (char**)( NULL)); > > > > It is pretty clear that problems start at this line in qt_term.cpp: > > QtGnuplotApplication application(argc, (char**)( NULL)); > > but after this line gets executed, I cannot even printf (whatever I > > put into print, it doesn't get displayed until something semi-crashes > > and printf sometimes starts working afer QApplication* application = > > new QApplication(argc, (char**)( NULL)); again). > > I would guess that the line Ethan conditioned isn't active when you > compile. That leaves "signal(SIGINT, SIG_IGN);" as the first line after > the fork, and that is probably a CoreFunction routine itself so doesn't > throw the exception or odd behavior. Thus "QtGnuplotApplication > application(argc, (char**)( NULL));" is the first line of code to follow > the fork and probably throws the exception. According to what you have > found exec() should nearly follow fork() and you can't have all that > code in between. Thus as a first test, perhaps try moving the fork > before the exec(), e.g., > > #ifndef HAVE_QT_47 > /* > * FIXME: EAM Nov 2011 > * It is better to use environmental variable > * QT_GRAPHICSSYSTEM but this requires qt >= 4.7 > * "raster" is ~5x faster than "native" (default). > * Unfortunately "opengl" isn't recognized on my test > systems :-( > */ > // This makes a huge difference to the speed of polygon > rendering. > // Alternatives are "native", "raster", "opengl" > QApplication::setGraphicsSystem("raster"); > #endif > > QtGnuplotApplication application(argc, (char**)( NULL)); > > // Make sure the forked copy doesn't trash the history > file > cancel_history(); > > // Load translations for the qt library > QTranslator qtTranslator; > qtTranslator.load("qt_" + QLocale::system().name(), > QLibraryInfo::location(QLibraryInfo::TranslationsPath)); > application.installTranslator(&qtTranslator); > > // Load translations for the qt terminal > QTranslator translator; > translator.load("qtgnuplot_" + > QLocale::system().name(), QTGNUPLOT_DATA_DIR); > application.installTranslator(&translator); > > pid = fork(); > > if (pid < 0) > fprintf(stderr, "Forking error\n"); > else if (pid == 0) // Child: start the GUI > { > signal(SIGINT, SIG_IGN); // Do not listen to SIGINT > signals anymore > // Start > application.exec(); > exit(0); > } > > > That may fail because of dependence on the fork() being called before > some of those other routines, but it's a start. (If it fails, try > moving the application.exec() up near the fork, but you'll have to leave > behind the exit(0) otherwise the translations will be missing.) > > Dan Dan: I could be wrong, but I don't think that "application.exec()" is actually an exec() call in the normal linux sense. See for example http://stackoverflow.com/questions/3880693/qapplication-exec-creates-new-thread-process In this case it just means "start looping over the draw commands until I tell you to stop". So your idea would be spot on if this were a real exec(), but I'm afraid it's not going to help in this case. But hey, I could be wrong. It's simple enough to give it a try. Ethan |