Before going to the scribus and qt mailing lists with this, I would like to run it by you C++ and qt-savvy fellows. Perhaps I overlooked something simple.
OK, here is the story: In qt, an empty string is defined by QString::null, and this object is statically defined somewhere in the qt lib (although I don't really see where it's defined, but it is empty, after all ;-) ). QString::null is used everywhere inside qt, for example for initializing optional string arguments of functions. It is legal to use empty strings in all qt string methods.
Now comes the catch: If QString::null is used inside a static object, one can get a bus error. According to some qt guys, this is not a bug and it happens because the order of initialization of static objects is undefined: When QString::null is used, for instance in a line like
src/tools/qdir.cpp:213: nameFilt = nameFilter;
(nameFilter is initialized to QString::null when QDir is called with only one argument)
before it is initialized, a bus error can result.
I am not buying this explanation completely, because on Darwin, this bus error happens *every time*, and on Linux, *never*. So it doesn't look like a problem involving randomly filled memory locations.
In any case, Scribus is using static objects to read in some character translation tables from some small text files before the main program starts up. For this, it uses qt file operations, which according to the above explanations should be a no-no in this situation. But "it works on Linux" (TM), so the scribus guys have no reason to change it. It "is not a bug in qt" (TM), so it will not be fixed there, either. Bad luck for Fink and the Mac users.
I attach a small program that shows 3 versions of this crash. Crash3 is related to the Scribus bus error. It happens, because it internally uses something equivalent to Crash2 (if LANG is set to something non-empty), and Crash2 happens, because internally it uses Crash1 (see the example I gave above). FWIW, on Linux none of the 3 examples gives bus errors.
Any comments welcome.
-- Martin
/*** File qcrash.cc (C) Martin Costabel 2003 Uncomment one of the lines with "int c? = crash?" Compile with c++ -o qcrash qcrash.cc -I/sw/include/qt -L/sw/lib -lqt-mt ***/
#include <qstring.h> #include <qdir.h> #include <qfile.h> #include <qtextcodec.h> #include <iostream> int crash1(){ std::cout << "\n This is crashtest No 1\n"; QString Crash1 = QString::null; } int crash2(QString name){ std::cout << "\n This is crashtest No 2\n"; QDir Crash2 = QDir(name); } int crash3(QString fname, char* lang){ QFile f(fname); setenv("LANG",lang,1); std::cout << "\n This is crashtest No 3 with locale \""\ << QTextCodec::locale() << "\"\n"; return f.open(IO_ReadOnly); } int c1 = crash1(); //int c2 = crash2("/foo"); //int c3 = crash3("/bar","en_US"); //int c3 = crash3("/bar","KOI8-R"); int main() { std::cout << "\n No crash this time...\n"; } /*** End file qcrash.cc ***/