NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: lib/39986: libmapper_zone.so is trying to call undefined weak symbol



The following reply was made to PR lib/39986; it has been noted by GNATS.

From: Takehiko NOZAKI <takehiko.nozaki%gmail.com@localhost>
To: gnats-bugs%netbsd.org@localhost
Cc: lib-bug-people%netbsd.org@localhost, gnats-admin%netbsd.org@localhost, 
netbsd-bugs%netbsd.org@localhost, 
        tech-userlevel%netbsd.org@localhost
Subject: Re: lib/39986: libmapper_zone.so is trying to call undefined weak 
        symbol
Date: Sat, 2 Jan 2010 03:45:23 +0900

 hi, all
 
 > While running mail/sylpheed it exits with the following line on my terminal 
 > at random occasions (when opening mail):
 >
 > /usr/lib/i18n/libmapper_zone.so.4.4: Trying to call undefined weak symbol 
 > `__deregister_frame_info'
 >
 
 this is not mapper_zone(which is part of Citrus iconv)'s problem.
 i suspect C/C++ runtime problem on NetBSD.
 
 [background]
 
   GTK+2 have so called gtkimmodule, own input method framework
   that doesn't depend on X Window System's XIM protocol.
   it isn't apply server/client style remote procedule call,
   simply and directly depends on dlopen(3).
   and some 3rd party gtkimmodule(AFAIK pkgsrc-wip/scim) is C++ ABI.
 
   but NetBSD's dlopen(3), dynamic loading C++ shared library from C application
  may causes crash.
 
 [reproduce the problem]
 
   1. build C++ shared library
 
     $ cat >foo.h
     #if defined(__cplusplus)
     extern "C" {
     #endif
     void foo(void);
     #if defined(__cplusplus)
     }
     #endif
     ^D
     $ cat >foo.cpp
     #include <string>
     #include <iostream>
     #include "foo.h"
 
     void
     foo(void)
     {
         std::basic_string<char> msg;
         msg = std::basic_string<char>("hello, C++ world.\n");
         std::cout << msg;
     }
     ^D
     $ g++ -shared -g -o libfoo.so foo.cpp
     $ cat >bar.h
     void bar(void);
     ^D
 
   2. build C shared library.
 
     $ cat >bar.c
     #include <stdio.h>
     #include "bar.h"
 
     void
     bar(void)
     {
         printf("hello, C world.\n");
     }
     ^D
     $ gcc -shared -g -o libbar.so bar.c
 
   3. build application that dlopen(3)  both C/C++ libraries.
 
     $ cat >buzz.c
     #include <dlfcn.h>
 
     typedef void (*func_t)(void);
     int
     main(void)
     {
         void *foo, *foo_func, *bar, *bar_func;
 
         foo = dlopen("libfoo.so", RTLD_GLOBAL);
         foo_func = dlsym(foo, "foo");
         ((func_t)foo_func)();
 
         bar = dlopen("libbar.so", RTLD_GLOBAL);
         bar_func = dlsym(bar, "bar");
         ((func_t)bar_func)();
 
         dlclose(foo);
         dlclose(bar);
 
         return 0;
     }
     ^D
     $ gcc -g -o buzz buzz.c
 
   4. run it.
 
     $ LD_LIBRARY_PATH=$LD_LIBRARY_PATH:. ./buzz
     hello, C++ world.
     hello, C world.
     ./libbar.so: Trying to call undefined weak symbol `__deregister_frame_info'
 
   this problem happen only following order:
     dlclose(foo)        /* C++ library */
     dlclose(bar)        /* C library */
 
   following order no harm:
     dlclose(bar)        /* C library */
     dlclose(foo)        /* C++ library */
 
 [why this problem occur?]
 
   C++ throws exception via stack frame by __(de)register_frame_info().
   this function exists in libgcc_s.so:
 
     $ nm /usr/lib/libgcc_s.so | egrep "__(de)?register_frame_info$"
     00007e00 T __deregister_frame_info
     00007c60 T __register_frame_info
 
   and crtbeginS.o has weak reference for it;
 
     $ nm /usr/lib/crtbeginS.o  | egrep "__(de)?register_frame_info$"
              w __deregister_frame_info
              w __register_frame_info
 
   so that both C++ and C library refer it too:
 
     $ nm libfoo.so | egrep "__(de)?register_frame_info"
              w __deregister_frame_info@@GCC_3.0
              w __register_frame_info@@GCC_3.0
 
     $ nm libbar.so | egrep "__(de)?register_frame_info"
              w __deregister_frame_info
              w __register_frame_info
 
   but, dependency for libgcc_s.so is recoreded only C++ library.
 
     $ ldd libfoo.so
     libfoo.so:
             -lc.12 => /usr/lib/libc.so.12
             -lstdc++.7 => /usr/lib/libstdc++.so.7
             -lm.0 => /usr/lib/libm.so.0
             -lgcc_s.1 => /usr/lib/libgcc_s.so.1
 
     libbar.so:
             -lc.12 => /usr/lib/libc.so.12
 
   so if dlclose(3) libfoo before libbar, can't resolve real
   __deregistered_frame_info() because libgcc_s has been unloaded.
   (if only load/unload C library, __deregister_frame_info is fake
 symbol, no problem)
 
     $ LD_DEBUG=1 LD_LIBRARY_PATH=$LD_LIBRARY_PATH:. ./buzz
     ...
     _rtld_call_fini_functions(0)
     _rtld_initlist_tsort
     calling fini function ./libfoo.so at 0xbbadd900
     calling fini function /usr/lib/libgcc_s.so.1 at 0xbb9de140
     calling fini function /usr/lib/libm.so.0 at 0xbb9f6880
     calling fini function /usr/lib/libstdc++.so.7 at 0xbbab2ce0
     _rtld_call_fini_functions(0)
     _rtld_initlist_tsort
     calling fini function ./libbar.so at 0xbb9d4430
     ./libbar.so: Trying to call undefined weak symbol `__deregister_frame_info'
     rtld_exit()
     _rtld_call_fini_functions(1)
     _rtld_initlist_tsort
     calling fini function /usr/lib/libc.so.12 at 0xbbbc51e0 (DF_1_INITFIRST)
 
 [how to fix]
 
   i'm not toolchain and elf guru, so i can't decided my mind:
 
   1. don't use __(de)?register_frame_info but .eh_frame section instead
     by adding --eh-frame-hdr option.  it seems that Linux/glibc2 now using it,
     also FreeBSD, OpenBSD too
 
     $ /usr/pkg/emul/linux/usr/bin/gcc -### -shared -o libbar.so bar.c
     ... "--eh-frame-hdr" ...
 
   2. clarify application using dlopen(3) must add -lgcc_s option.
 
     same approach of non ptheaded application loading ptheaded library.
     see following discussion:
     http://mail-index.netbsd.org/pkgsrc-users/2009/01/17/msg009088.html
 
   3. hack ld.elf_so
     re-add fake symbol to undefined weak symbol.
     ummmm, i think bad idea.
 
 
 any idea?
 
 very truly yours.
 -- 
 Takehiko NOZAKI <tnozaki%NetBSD.org@localhost>
 


Home | Main Index | Thread Index | Old Index