an**************@gmail.com wrote:
Hi List,
This question can be categorised under "C programming in Linux", but
as I didnt find any group of that sort, I post it here.
I have a small program to print the stack trace of a particular
function. Here is the code:
================================================== ==
#include <stdio.h>
#include <execinfo.h>
#include <stdlib.h>
void print_trace (void){
void *arr[20];
size_t asize, icnt;
char **str;
asize = backtrace (arr, 20);
str = backtrace_symbols (arr, asize);
for (icnt=0; icnt<asize; ++icnt)
printf ("%s\n",str[icnt]);
free (str);
}
int main(int argc, char **argv)
{
print_trace ();
return 0;
}
================================================== ==
By calling backtrace ( ) and backtrace_symbols ( ) I can get a trace
of the calling functions path.
What I would like to know is if I can find the contents of the calling
functions () s argument values too?
More precisely:
A(void) {
...
backtrace ( )
backtrace_symbols ( )
...
}
B (int foo, int bar){
A () ;
...
}
C (int foo, int bar, int baz){
B ();
...
}
int main (){
C ()
...
...
}
>>From the backtrace_symbols we can generate a path of the function call
main() calling C ()-C() calling B() -B() calling A(). Can we also
get the values for the arguments used in C (foo, bar, baz) and B (foo,
bar)? If we could then how?
Thanks
Anirbid
Of course you can. You have just to write a debugger.
To know what the values in the stack *are* you have to know the
type of the arguments. THEN and only then, you can interpret
the bits in the stack in a meaningful fashion. If not, you can just
see some bits but you have no idea of what they represent.
Besides, you have to know that the values start at a certain offset from
the stack, the organization of stack/frame pointer, and several other
interesting things.
Writing a debugger is a lot of fun. Lcc-win32's debugger costed me some
pain, but it was worth.
It is not a completely general debugger of course. I have
never tested it outside lcc-win32, and I suppose that you have enough
time to write a differeent debugger for each compiler you will use.
Debug information formats vary a lot. Microsoft used NB09 in Windows 98
and changed to NB10 in windows 2000. I use NB09 since I did not see why
I should change.
Gcc uses a different format called "stabs", under windows, and in the
old versions of linux. Now the changed to DWARF, leaving the stabs format.
Under linux, I use the stabs format, and DWARF when there is no other
choice.
But there is also not only the debug information format that changes.
You have to know that the frame pointer organization
changes considerably if you are in optimized code or not.
This could throw off many of your offsets if you do not take care.
But it is a fun project.