Stack tracing for calling stack

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
jal
Member
Member
Posts: 1385
Joined: Wed Oct 31, 2007 9:09 am

Stack tracing for calling stack

Post by jal »

If something goes horribly wrong and your OS gets an exception you cannot handle, it's nice to display the good old register dump and the like. What may also be very useful is printing somewhere the function that caused the exception. I've created a simple look-up from the ELF symbol table that does that (it works; and yes, it would also be great to be able to print e.g. the line number, but I'm not fancying to make a DWARF interpreter anytime soon).

However, what could also be rather useful is displaying a calling stack, showing which function called my function, which function called that one, etc. My question is how to do that. Just scan down the stack and try to interpret every dword as an address, and see whether that's somewhere in the symbol table? Seems rather crude and error prone, but it's the only thing I can think of right now.


JAL
User avatar
JamesM
Member
Member
Posts: 2935
Joined: Tue Jul 10, 2007 5:27 am
Location: York, United Kingdom
Contact:

Post by JamesM »

Hi.

You can do it by unwinding stack frames. In most cases (and with GCC, pretty much all cases) a function starts by pushing the base pointer (ebp). So you end up with something like this as a stack:

Code: Select all

20 <-- ESP
24
28 <-- Pushed EBP
32 <-- Pushed Return address
34
And, in fact, the *current* value of EBP will point to where the old one was pushed. So if you take EBP and keep dereferencing it, you will end up unwinding the stack, one frame at a time.

then note, that if you take any of those EBPs you just found, and add 4 to it and dereference it (go one place up the stack from it), you get the return address from that stack frame.

So all you have to do is follow the trail of EBPs, find the return addresses for each stack frame, and lookup the symbol for each. Sorted.
jal
Member
Member
Posts: 1385
Joined: Wed Oct 31, 2007 9:09 am

Post by jal »

JamesM wrote:So all you have to do is follow the trail of EBPs, find the return addresses for each stack frame, and lookup the symbol for each. Sorted.
I figured that much, however that only works with the same calling convention. If one has certain functions that take register parameters, or one uses assembly functions, then one is stuck (well, I am stuck, since I use these :))?


JAL
User avatar
JamesM
Member
Member
Posts: 2935
Joined: Tue Jul 10, 2007 5:27 am
Location: York, United Kingdom
Contact:

Post by JamesM »

This depends. Functions using register-passing will still work as long as the base pointer is pushed at the start of the function, which is the case for pretty much any function requiring stack-local storage. Assembler functions work for me as well (because I push EBP).
jal
Member
Member
Posts: 1385
Joined: Wed Oct 31, 2007 9:09 am

Post by jal »

JamesM wrote:This depends. Functions using register-passing will still work as long as the base pointer is pushed at the start of the function, which is the case for pretty much any function requiring stack-local storage. Assembler functions work for me as well (because I push EBP).
Ok, then I should use the PUSH EBP trick in my asm routines as well. Thanks for this very helpful information!


JAL
User avatar
zaleschiemilgabriel
Member
Member
Posts: 232
Joined: Mon Feb 04, 2008 3:58 am

Post by zaleschiemilgabriel »

for this to work it means you have to preserve ebp, right?
User avatar
JamesM
Member
Member
Posts: 2935
Joined: Tue Jul 10, 2007 5:27 am
Location: York, United Kingdom
Contact:

Post by JamesM »

Yes. This is done automatically for any C functions by the compiler (and should be done by you too, if you're following cdecl (but of course you may not be)), unless you have -fomit-frame-pointer enabled.
sawdust
Member
Member
Posts: 51
Joined: Thu Dec 20, 2007 4:04 pm

Re:

Post by sawdust »

jal wrote: Ok, then I should use the PUSH EBP trick in my asm routines as well. Thanks for this very helpful information!
JAL
Hi JAL,
Did you have luck implementing this one? I too have a similar requirement and your input will be very helpful to me.
Thx :)
jal
Member
Member
Posts: 1385
Joined: Wed Oct 31, 2007 9:09 am

Re: Re:

Post by jal »

sawdust wrote:Did you have luck implementing this one? I too have a similar requirement and your input will be very helpful to me.
I'm not sure I can give any input. I followed up on James' suggestion, that's basically it.


JAL
sawdust
Member
Member
Posts: 51
Joined: Thu Dec 20, 2007 4:04 pm

Re: Re:

Post by sawdust »

jal wrote: I'm not sure I can give any input. I followed up on James' suggestion, that's basically it.
JAL
I mean, if you have a working code stub, can you post it here?
jal
Member
Member
Posts: 1385
Joined: Wed Oct 31, 2007 9:09 am

Re: Re:

Post by jal »

sawdust wrote:I mean, if you have a working code stub, can you post it here?
No, I'm sorry, I'm not into code sharing at this point.


JAL
Post Reply