This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Function, file and line information out of '_Unwind_Context'ptr


Hi Jim,

it seems like 'libbfd' and 'Unwind_Context' pointer are to be interpreted differently.
Given the example program (just the relevant parts):
--- main.cc ---
...
static _Unwind_Reason_Code
Trace_cb(struct _Unwind_Context *ptr, void *)
{
void *pc = (void *) _Unwind_GetIP(ptr);
std::cout << "Function: " << (void *) pc<< std::endl;
return _URC_NO_REASON;
}


void foo1()
{
       _Unwind_Backtrace(Trace_cb, NULL);
}

void foo()
{
       foo1();
}

int main()
{
       foo();
       read_symbols();
       return 0;
}
---

Produces a correct backtrace:
---
Function: 0x12002d508
Function: 0x12002d544
Function: 0x12002d580
Function: 0x12002d22c
---

This is the output of 'addr2line' on the complete source:
---
addr2line -e main 0x12002d508 0x12002d544 0x12002d580
/buildspace/GBruchhaeuser/SCMws/bt/main.cc:18
/buildspace/GBruchhaeuser/SCMws/bt/main.cc:25
/buildspace/GBruchhaeuser/SCMws/bt/main.cc:31
---

Well, these pointers refer to the function calls.
The symbols which from libbfd are pointing to the function definition:
---
...
void
process_symbol(asymbol *symbol)
{
       std::cout << (void *) bfd_asymbol_value(symbol) << " = "
                 << bfd_asymbol_name(symbol) << std::endl;
}

...
void read_symbols()
{
...
asymbol **symbol_table = (asymbol **) calloc(1, storage_needed);
long number_of_symbols = bfd_canonicalize_symtab(abfd, symbol_table);
if (number_of_symbols < 0) {
std::cout << "Function 'bfd_canonicalize_symtab' failed!" << std::endl;
return;
}


       for (int i = 0; i < number_of_symbols; i++) {
               process_symbol(symbol_table[i]);
       }
}
...
---

If I compare these pointers then it looks like:
=== Unwind ==> BFD ==> Symbol
Function: 0x12002d508 ==> 0x12002d560 ==> main
Function: 0x12002d544 ==> 0x12002d4dc ==> foo1
Function: 0x12002d580 ==> 0x12002d524 ==> foo
Function: 0x12002d22c ==> ??:0
===

How can I combine both the pointer information so that I can printout function names instead of addresses in my backtrace? A simple range check doesn't seem to do it :-(

Any idea??

Many thanks,
Gerrit




Gerrit BruchhÃuser wrote:


Hi Jim,

wow. This mail must have taken a lot of your time.
Many thanks for all this information. I am really impressed!

Try calling _Unwind_GetIP for the function address.  IP is Instruction
Pointer, which is just another name for PC Program Counter.


well, it worked: :-)
---
ggbruchha@tru64-unix-4:~> g++ -g3 -O0 -o main main.cc
gbruchha@tru64-unix-4:~> ./main
Function: 0x1200226a8
Function: 0x1200226e4
Function: 0x120022720
Function: 0x1200223cc
gbruchha@tru64-unix-4:~> addr2line --exe main 0x1200223cc 0x120022720 0x1200226e4 0x1200226a8
??:0
/users/gbruchha/main.cc:31
/users/gbruchha/main.cc:26
/users/gbruchha/main.cc:19
---




The LSB is a good source of documentation and references to other docs. We also have links to documentation on our home page under Further
Readings. This has pointers to the C++ ABI (which includes Unwinder
info), and the Alpha ABI (function descriptors).


What did you mean with LSB?? I never heard of it before. Did you mean one of:
http://www.linuxbase.org/
http://freestandards.org/
?



Now I am able to create backtraces in case '-O0 -g3' is given to g++. Well, this is almost all I wanted to do. Just the function names are missing but I think I am able to figure this out someway. I want to integrate 'addr2line' into my program anyways.


Is there any buildin to retreive an indication on whether the unwinding may work (-O0 and -g are given)?

Many thanks,
Gerrit


Jim Wilson wrote:


On Sun, 2004-06-27 at 06:47, Gerrit BruchhÃuser wrote:


It would be extremly useful to have a 'Backtrace' like building function in g++ (as there is in GLIBC) which does work with any platform g++ runs on. I thought I could use the '_Unwind_Stack' function for this. Is there maybe an other way to retreive file and line information out of the mentioned structure pointer??


The glibc backtrace function is x86 specific.  It is trivial to generate
a backtrace on a CISC like the x86, but it is hard on a RISC, and it is
getting harder with newer ABIs and more agressively optimizing
compilers.

By the way, if you are using -foptimize-sibling-calls, which is the
default at -O2, then your backtraces are already broken.  This option
optimizes away stack frames when we have a sibling call, and you can't
backtrace through a stack frame that isn't there.

Similarly, if you are using function inlining, then the backtraces won't
exactly represent what the programs is doing.  This is fixable by
reading the debug info, but even gdb/addr2line doesn't have code to do
this yet.

As for Alpha, the Alpha ABI has function descriptors which can be used
to generate backtraces.  The Alpha ABI deliberately sacrifices some
performance so that backtraces can still work.  If you find an Alpha ABI
reference and read up on it, you should be able to write your own code
to do stack backtraces on the alpha.  This will be faster than using the
unwinder.

But for most common RISC targets nowadays, the only safe way to do a
backtrace is to use the unwinder, and this will be a slow process
compared to the glibc backtrace function.

If you just want function names in the backtrace, you can do this pretty
easily by reading the symbol table (e.g. the ECOFF symbol table).  If
you want line numbers also, then you have to read the debug info, and
there is no getting around the fact that this will be an even slower
process.  This is best done offline as Arnaud Charlet suggested if you
really need this.  I believe the glibc backtrace function only gives you
function names.

The LSB is a good source of documentation and references to other docs. We also have links to documentation on our home page under Further
Readings. This has pointers to the C++ ABI (which includes Unwinder
info), and the Alpha ABI (function descriptors).


Try calling _Unwind_GetIP for the function address. IP is Instruction
Pointer, which is just another name for PC Program Counter.






Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]