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

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