NetBSD-Bugs archive

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

Re: lib/39986: 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 <>
Subject: Re: lib/39986: is trying to call undefined weak 
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/ 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.
   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" {
     void foo(void);
     #if defined(__cplusplus)
     $ cat >foo.cpp
     #include <string>
     #include <iostream>
     #include "foo.h"
         std::basic_string<char> msg;
         msg = std::basic_string<char>("hello, C++ world.\n");
         std::cout << msg;
     $ g++ -shared -g -o foo.cpp
     $ cat >bar.h
     void bar(void);
   2. build C shared library.
     $ cat >bar.c
     #include <stdio.h>
     #include "bar.h"
         printf("hello, C world.\n");
     $ gcc -shared -g -o bar.c
   3. build application that dlopen(3)  both C/C++ libraries.
     $ cat >buzz.c
     #include <dlfcn.h>
     typedef void (*func_t)(void);
         void *foo, *foo_func, *bar, *bar_func;
         foo = dlopen("", RTLD_GLOBAL);
         foo_func = dlsym(foo, "foo");
         bar = dlopen("", RTLD_GLOBAL);
         bar_func = dlsym(bar, "bar");
         return 0;
     $ gcc -g -o buzz buzz.c
   4. run it.
     hello, C++ world.
     hello, C world.
     ./ 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
     $ nm /usr/lib/ | 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 | egrep "__(de)?register_frame_info"
              w __deregister_frame_info@@GCC_3.0
              w __register_frame_info@@GCC_3.0
     $ nm | egrep "__(de)?register_frame_info"
              w __deregister_frame_info
              w __register_frame_info
   but, dependency for is recoreded only C++ library.
     $ ldd
             -lc.12 => /usr/lib/
             -lstdc++.7 => /usr/lib/
             -lm.0 => /usr/lib/
             -lgcc_s.1 => /usr/lib/
             -lc.12 => /usr/lib/
   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)
     calling fini function ./ at 0xbbadd900
     calling fini function /usr/lib/ at 0xbb9de140
     calling fini function /usr/lib/ at 0xbb9f6880
     calling fini function /usr/lib/ at 0xbbab2ce0
     calling fini function ./ at 0xbb9d4430
     ./ Trying to call undefined weak symbol `__deregister_frame_info'
     calling fini function /usr/lib/ 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 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:
   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 <>

Home | Main Index | Thread Index | Old Index