Hi, everyone,

Thanks for all your help and ideas.  I think I have solved this  
mystery.  The symptoms are very misleading and confusing, but the  
underlying cause turns out to be fairly easy to understand.

The problem is actually related to command line parsing.  It turns  
out that C programs  on Mac OS X have access to global variables  
NXArgc and NXArgv.  They are used by one of the system libraries (I  
think it's CoreFoundation, but I could be wrong) that "eventually"  
gets loaded when using the xcairo driver.

If c_plparseopts is called without the PL_OPT_NODELETE option AND it  
"deletes" arguments *before* this library gets loaded/initialized,  
then the program crashes (presumably when the library accesses the  
modified contents of NXArgv using the unmodified value of NXArgc).

If c_plparseopts is called with the PL_OPT_NODELETE option OR if it  
"deletes" no arguments, OR if it "deletes" arguments *after* this  
library gets loaded/initialized, then the program does not crash.

Using "WITH_FREETYPE=ON" causes the freetype library to be linked in  
(via `pkg-config --libs plplotd`) to the executable (e.g. x01c),  
which results in the system library getting loaded/initialized  
*before* c_plparseopts is called.

Using "WITH_FREETYPE=OFF" does not link the freetype library to the  
executable.  In this case, the relevant system library does not get  
loaded/initialized until *after* c_plparseopts.  If c_plparseopts  
"deletes" command line arguments, then the program will crash  
(presumably when the library accesses the modified contents of NXArgv  
using the unmodified value of NXArgc).  This can be confirmed by  
noting that "x01c -dev xcairo" crashes while "PLPLOT_DEV=xcairo x01c"  
works using the exact same installation.  Adding PL_OPT_NODELETE to  
x01c's call to c_plparseopts also prevents the crash since not  
"deleting" arguments maintains consistency between NXArgc and the  
contents of NXArgv.

I can think of several ways of preventing this problem:

1. Always include CoreFoundation in linker flags on Macs.

2. Change c_plparseopts to not NULL terminate the modified argv  
array, but instead point the "extra" elements to an empty string.   
I've already tried this locally (a two line change) and it works, but  
it ends up with "argv[argc]" not being a null pointer which violates  
http://www.open-std.org/jtc1/sc22/WG14/www/docs/n1256.pdf (see  
section 5.1.2.2.1 item 2).

3a. Add code within "#if define ( __APPLE __)" blocks so that NXArgc  
can be modified to match the modified contents of NXArgv/argv.  This  
might also an issue on NeXTSTEP, since I think that's where Apple  
picked up these variables (hence the NX prefix)

3b. Create a cmake test for NXArgc/NXArgv and define a HAVE_NXARGC  
macro that can be used instead of __APPLE__.

I think 3b might be the cleanest option, but I'm open other  
possibilities (including any I've not listed).  Opinions?

Thanks again,
Dave


------------------------------------------------------------------------------
The Planet: dedicated and managed hosting, cloud storage, colocation
Stay online with enterprise data centers and the best network in the business
Choose flexible plans and management services without long-term contracts
Personal 24x7 support from experience hosting pros just a phone call away.
http://p.sf.net/sfu/theplanet-com
_______________________________________________
Plplot-devel mailing list
Plplot-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/plplot-devel

Reply via email to