Bug 169017

Summary: backtrace() does not resolve symbols when compiled with hidden visibility
Product: [Fedora] Fedora Reporter: Helge Deller <helge.deller>
Component: glibcAssignee: Jakub Jelinek <jakub>
Status: CLOSED NOTABUG QA Contact: Brian Brock <bbrock>
Severity: medium Docs Contact:
Priority: medium    
Version: 4   
Target Milestone: ---   
Target Release: ---   
Hardware: x86_64   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2005-09-24 11:11:06 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:

Description Helge Deller 2005-09-22 08:14:37 UTC
From Bugzilla Helper: User-Agent: Mozilla/5.0 (compatible; Konqueror/3.4; Linux) KHTML/3.4.91 (like Gecko)  Description of problem: The glibc function backtrace() does not resolve symbols in programs which were     compiled with the gcc option -fvisibility=hidden.         Here is an example program (backtrace.c) to reproduce the problem:    -------------------------------------------------------------------    /* Works:   cc -o backtrace backtrace.c -Wl,--export-dynamic */    /* Fails:   cc -o backtrace backtrace.c -fvisibility=hidden    -Wl,--export-dynamic */        #include <stdio.h>    #include <unistd.h>    #include <string.h>    #include <execinfo.h>    #include <stdlib.h>    #include <signal.h>        void showFuncStack()    {      int addrs;      void * addr[10];      addrs = backtrace(addr, sizeof(addr)/sizeof(addr[0]));      backtrace_symbols_fd(addr, addrs, 2);    }    void cc()    {      showFuncStack();    }    int main(int argc, char *argv[])    {      cc();      return 0;    }         Version-Release number of selected component (if applicable): glibc-2.3.5-10.3  How reproducible: Always  Steps to Reproduce: 1. compile above program: "cc -o backtrace backtrace.c -fvisibility=hidden     -Wl,--export-dynamic"     2. run the program: ./backtrace    3. you will not see the symbols "showFuncStack" or "cc" in the output.     Now how it works:  4. compile above program without the "-fvisibility=hidden" option: "cc -o   backtrace backtrace.c -fvisibility=default -Wl,--export-dynamic"   5. run the program again: ./backtrace   6: you will see all symbols.           Actual Results:  The output is:  ./backtrace[0x4006fe]  ./backtrace[0x400722]  ./backtrace[0x40073d]  /lib64/libc.so.6(__libc_start_main+0xef)[0x337c41c3cf]  ./backtrace[0x400659]     Expected Results:  The output should be (which   ./backtrace(showFuncStack+0x16)[0x40075e]  ./backtrace(cc+0xe)[0x400782]  ./backtrace(main+0x19)[0x40079d]  /lib64/libc.so.6(__libc_start_main+0xef)[0x337c41c3cf]  ./backtrace[0x4006b9]     Additional info:  It's true, that hidden symbols should not be visible when linking with other  programs. Nevertheless, backtrace() should show the symbols at least, since  they are necessary if you want to debug a program after it has crashed....

Comment 1 Jakub Jelinek 2005-09-22 23:09:58 UTC
That's a feature.  backtrace_symbols{,_fd} () uses only the dynamic symbol table,
something that is already loaded and can be looked up easily.
Hidden symbols aren't in the dynamic symbol table, so they don't show up in
backtrace_symbols{,_fd} ().
If that's not enough and either non-allocated symbol table or debugging info
needs to be analyzed, that's a job of other utilities (like addrline).


Comment 2 Helge Deller 2005-09-23 12:53:31 UTC
Hello Jakub,

that's really bad.
We use the backtrace() function in our application to produce a backtrace in a
log file, which then later can be used by development to find the real problem.
It's really unhandy to ask customers to run addrline or such.

So, what do you propose ? _Would_ it be possible to make backtrace look/load the
non-dynamic symbol table as well ? Would it be hard to implement ?
What about a chance of making it possible, if it would be a feature request ?

I'm just asking again, since without having the backtrace() functionality it
does not make sense to compile and ship our application with the
-fvisibility=hidden flag (which should bring some more performance on Linux).

TIA,
Helge

PS: Please close it afterwards as "NOTABUG" again...

Comment 3 Jakub Jelinek 2005-09-24 11:11:06 UTC
FYI, backtrace () just gives you addresses, you are really talking about
backtrace_symbols{,_fd} ().  But glibc is certainly not meant to be a kitchen
sink and even just finding the library, opening it, finding the symbol and string
tables and looking information there would mean glibc would need to contain
quite a lot of ELF handling code, probably a copy of libelf.  Plus most of the
symbol and string tables as well as debug info in our distro are stripped into
separate files, so it would need to handle that too.  Not to mention
that using debug info as opposed to just symbol table you can get far better
info, see e.g. addr2line -i option in rawhide that gives you info about inlined
functions in the backtrace.

Nothing prevents you from spawning addr2line utility (or eu-addr2line) and
passing it the addresses from backtrace () and reporting back what it printed.
And that's the best solution here IMHO.

Comment 4 Helge Deller 2005-09-26 11:08:32 UTC
Hello Jakub,

spawning addr2line will not work in our case, since our application dlopen()
other shared libraries, which addr2line will not know about and thus will not be
able to decode.
I agree, that glibc should not be a kitchen sync, but without being able to see
at least the (newly) local text symbols (which have been global text symbols
before the -fvisibility=hidden flag) the backtrace_symbols()-functions in glibc
is IMHO more or less useless. All you normally will see is "main()".
What about dropping backtrace_symbols() [and maybe backtrace()] from glibc and
provide full functionality in an external optional library ?

Helge