Date: Fri, 15 Jul 2005 11:59:43 -0700 From: Pascal Hofstee <caelian@gmail.com> To: freebsd-threads@freebsd.org Cc: David Ayers <d.ayers@inode.at> Subject: GNUstep, libobjc and threading Message-ID: <1121453983.672.15.camel@synergy.charterpipeline.net.lan>
next in thread | raw e-mail | index | archive | help
Hi, Ever since the GNUstep project decided to make certain changes regarding how GNUstep applications should be linked to external libraries ... GNUstep builds on the FreeBSD platform appeared to be broken where they used to function properly before. (Problem being applications segfaulting in libobjc's thread initialization) During the last couple of days, David Ayers, one of the people with an active GNUstep interest and willingness to see this issue resolved was kind enough to allow me to provide him access to my FreeBSD/amd64 7.0-CURRENT machine in an attempt to get to the bottom of this issue. His final analysis boils down to the following: ----[ Analysis of GNUstep on FreeBSD pthread problem ]---- The real bug does indeed lie in the internal initialization process of the FreeBSD libpthread library. In this case when libobjc is not excplitly linked into the executable, (and is further at the bottom of the ldd depenency list) it get's initialized before libpthread does. i.e. it starts calling libpthread functions before the following constructor: void _thread_init_hack(void) __attribute__ ((constructor)); void _thread_init_hack(void) { _libpthread_init(NULL); } of the libpthread library is called. This constructor sets up the data structures for _get_curthread(). The function that libobjc calls early: pthread_key_create() calls _get_currthread which still returns NULL. This pointer is then dereferenced in the THR_LOCK_ACQUIRE macro resulting in the segfault. Many of the mutex functions have already been guarded for this case with the following code fragements: if (_thr_initial == NULL) _libpthread_init(NULL); See also the following comment in thr_create.c: ... * Some notes on new thread creation and first time initializion * to enable multi-threading. * * There are basically two things that need to be done. * * 1) The internal library variables must be initialized. * 2) Upcalls need to be enabled to allow multiple threads * to be run. * * The first may be done as a result of other pthread functions * being called. When _thr_initial is null, _libpthread_init is * called to initialize the internal variables; this also creates * or sets the initial thread. It'd be nice to automatically * have _libpthread_init called on program execution so we don't * have to have checks throughout the library. ... So they seem to be aware of the issue but haven't guarded all functions like pthread_key_create() which libobjc calls. I don't believe that we can find a reliable workaround within GNUstep. I also don't know if this bug is in a stable release version of FreeBSD. But I want to mention that a call to pthread_self() would workaround this. Yet this call would have to be done in libobjc's __objc_init_thread_system and not in GNUstep. The other hack is to fiddle with the link order so that the constructor above can cover up the issue. I'll leave it up to the -make maintainers to decide what to do. My current tendency is to close this bug as invalid at least until someone verifies that the issue exists with released versions of FreeBSD. And even then a workaround should probably be done in libobjc (which seems to be installed by FreeBSD but if libobjc needs updating you might as well update libpthread instead and fix the bug properly). ----[ End of Analysis]---- On a sidenote .. this same problem is duplicated (likely similarly) when using libthr ... and does not occur when using libc_r. Is the above analysis enough information to hopefully fix this problem with FreeBSD's threading libraries ... and would properly gaurding the mentioned pthread_key_create function with a similar _thread_initial check be sufficient ? With kind regards, and hoping to get some feedback on this ... -- Pascal Hofstee
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?1121453983.672.15.camel>