Hi all Please CC me any replies since I don't currently subscribe to this list.
I am trying to create a statically linked X application to simplify distribution. Up to and including Xfree86 4.1.0 everything worked fine by passing "-static" to gcc during the link stage. Starting with Xfree86 4.2.0, the application linked this way started to give strange and unpredictable segfaults during operation. It was a wxgtk app, and I started stripping out code to eliminate as many things as possible. Eventually I had a plain gtk application skeleton which triggered the fault. I found that if the system's libX11.a was replaced with the one from Xfree86 4.1.0 that the problem went away. Subsequently I found that if the dynamic locale loader was disabled in libX11 the program was stable. Similarly, if <X11 root>/lib/X11/locale/common/xlcDef.so.2 was removed the problem went away. The segfault was always in __libc_free(), called from XmbSetWMProperties(). This later function is called for each new window created by gtk (gdk_window_new()) and it was at this point (ie: window creation) that the segfault was occuring. In this instance mbWMProps.c:XmbSetWMProperties() is used to set the name and icon name for the window being created. This passes the name and icon name through lcWrap.c:XmbTextListToTextProperty(), presumedly to allow for locale modifications. XmbTextListToTextProperty() essentially handballs the request to the locale's mb_text_list_to_prop method. The problem with statically linked executables is that xlcDef.so.2 is actually a dynamic library with dependencies on libX11.so and libc.so. Thus when xlcDef.so.2 is loaded with dlopen(), the dynamic libX11 and libc libraries are dragged into core to satisfy these dependencies. For dynamic applications the second copies aren't dragged in - dlopen() uses the incore copies to resolve references; for statically linked applications, however, the static core copy can't be used. For static executables, from this point, we have two libc/X11 environments - one used by xlcDef.so.2 and one used by every other component of the program. Note that source filenames which follow are from xc/lib/libX11/. On our systems, the default `C' locale is handled by the dynamic /usr/X11R6/lib/X11/locale/common/xlcDef.so.2 module. In this module, the locale's mb_text_list_to_prop method remains pointed to the default class method, which is lcTxtPr.c:_XTextListToTextProperty(). This setting is made in the lcPublic.c:initialize_core() function, called from lcPubWrap.c:_XlcCreateLC() which is in turn called by the module's loader (lcDefConv.c:_XlcDefaultLoader()), which itself is called when the module is initially loaded in XlcDL.c:_XlcDynamicLoad(). Significantly, everything from _XlcDefaultLoader() down is running with the dynamic shared copies of libX11 and libc - so the mb_text_list_to_prop method pointer is set to point to the shared library's _XTextListToTextProperty() function. When memory allocation is done by either libc, the other has no way of knowing what is being done. Therefore it is only a matter of time before one of the libc/X11's corrupts the heap of the other. In my case, the locale module does do memory allocation with malloc()/free(). _XTextListToTextProperty() makes a buffer allocation before calling the appropriate conversion functions from the locale module, which in our case are (in order) lcDefConv.c:open_mbstostr() lcDefConv.c:create_conv() lcDefConv.c:mbstostr() lcDefConv.c:close_converter() If XmbTextListToTextProperty() is allowed to pass its request to the locale's mb_text_list_to_prop method, this results in a call to a copy of _XTextListToTextProperty() which lies within the shared library loaded along with the locale module - not the copy in the (static) program's core. Thus the application's heap memory is being used concurrently by two different libcs and eventually one will corrupt the other. Once this corruption occurs, the segfault happens. Therefore, we finally come to my question: * given this new dynamic locale functionality, how exactly is one to make a static executable which will run on all systems? Essentially, as I see it, static X libs compiled under Xfree86 4.2.0 will work on all systems which don't have the dynamic locale modules installed (eg: XFree86 systems <4.1.0), but will segfault and/or be unstable on systems which have the dynamic locale modules available. Regards jonathan -- * Jonathan Woithe [EMAIL PROTECTED] * * http://www.physics.adelaide.edu.au/~jwoithe * ***-----------------------------------------------------------------------*** ** "Time is an illusion; lunchtime doubly so" ** * "...you wouldn't recognize a subtle plan if it painted itself purple and * * danced naked on a harpsichord singing 'subtle plans are here again'" * _______________________________________________ Xpert mailing list [EMAIL PROTECTED] http://XFree86.Org/mailman/listinfo/xpert