Demangling of method names and addr2line/c++filt

Ranjit Mathew rmathew4lists@hotmail.com
Thu Feb 13 12:51:00 GMT 2003


> So the questions seem to be:
> - Does addr2line (or addr2name) and dladdr always strip the leading
> underscore on platforms that need it stripped?
> If yes, then it seems save to always give a "-n" argument to c++filt.

I don't know about dladdr, but I did a bit of digging around in the 
GCC/binutils source code and found that:

1. The GCC target-specific macro USER_LABEL_PREFIX essentially decides 
   if an underscore should be prefixed or not for labels corresponding
   to functions. You can see the target headers in the "gcc/config/*"
   folders to see which ones define this (quite a few).

2. addr2line merely reports as the function name what it finds in the 
   symbolic debugging information in the executable. On Win32 for example,
   the debug info for a C function "t( )" is generated as:
        ...
        .stabs  "t:F(1,1)=(1,1)",36,0,4,_t
        ...
   So the symbolic name "t" gets associated with the assembler label "_t".

   AFAICT, it appears that USER_LABEL_PREFIX does not have a role to
   play in emitting symbolic debugging information (except of course the
   actual label with which the symbol is associated) and so the symbol
   would be free of underscores, except for those introduced by 
   C++/Java name mangling or those present in the "real" function name.

   Therefore, there's an implicit "stripping" of the leading underscore
   here, if you wish to see it that way.

3. the situation with c++filt is slightly complex:

   a. the one in GCC (gcc/cp/cxxfilt.c) strips the leading underscore
      by default if USER_LABEL_PREFIX[0]=='_'.

   b. the one in binutils (libiberty/cplus-dem.c in binutils-2.13.2.1 and
      binutils/cxxfilt.c in the current CVS) strips the leading underscore 
      by default if "targ_underscore==yes" - this is true for a large
      number of targets as defined in "bfd/config.bfd".

The following thread gives an insight into the c++filt mess:

    http://gcc.gnu.org/ml/gcc-patches/2002-09/msg00271.html

especially this message in the thread is directly relevant to our 
problem:

    http://gcc.gnu.org/ml/gcc-patches/2002-09/msg00779.html

IMHO, it is safe to say since we are giving c++filt only the mangled
name via addr2line and not the actual assembler label that is generated, 
we should ask it to abstain from stripping any leading and incidental
underscore that is a part of the mangled name.

And though the c++filt in both binutils and GCC are supposed to be
developed further in lock-step, I still think it is more reliable to
use and recommend the one from GCC.

Reading the man pages for dladdr( ), I'm a bit confused about whether
it uses the symbolic debugging information for a shared object or the
exported labels (are these two necessarily separate on all targets?)
themselves - if it's the former, we can safely proceed with "-n" to
c++filt, if it's the latter *and* underscores are used on that target, 
then we have a problem - particularly so if we get names from *both*
addr2line and dladdr on that target (likely).

My recommendation would be to use "-n" always and cross the other bridge
when (if ever) we get to it.

Ranjit.



More information about the Java mailing list