[Solved]back trace in gdb after ring 0 exception?

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
xeyes
Member
Member
Posts: 212
Joined: Mon Dec 07, 2020 8:09 am

[Solved]back trace in gdb after ring 0 exception?

Post by xeyes »

Happy holidays:)

As we know, when an exception is taken in ring0 (x86 not 64) the ring 0 stack is still largely 'visible'.

While gdb can still back trace the stack, it doesn't seem to do so reliably past the exception handler entry. Maybe it was confused by the extra CS and EFL pushed by CPU and registers saved by my handler's assembly part during the exception entry, and since I don't have frame base pointers for all frames it is easier to get lost (but it is loaded with symbols and the elf though).

Symptoms include locals for frames past the exception handler entry are all messed up, sometimes even the calling sequence is questionable (i.e. non recursive functions appearing next to each other in the gdb back trace)

I'm wondering is there an option or some way to help gdb get on the right track (to get as much useful info out) without having to manually alter memory to 'fix the stack' (as at that point I might as well just trace it manually)?
Last edited by xeyes on Thu Jan 07, 2021 8:58 pm, edited 1 time in total.
nullplan
Member
Member
Posts: 1790
Joined: Wed Aug 30, 2017 8:24 am

Re: back trace in gdb after ring 0 exception?

Post by nullplan »

Backtracing without call frame information is complicated. Every backtracer I know is going to have to rely on heuristics to get by. On x86, a common assumption is that stack frames are maintained, and that allows the tracer to assume a common frame format. Unfortunately, the stack frame of an exception handler is completely non-standard. You can try to use DWARF call frame information to tell the debugger how to proceed. And good luck with that. I never managed to understand the format. And if you are in 32-bit mode, you have the added bonus of having to support two different stack frame formats in the same place. I'm sure that doesn't make it easier.
Carpe diem!
xeyes
Member
Member
Posts: 212
Joined: Mon Dec 07, 2020 8:09 am

Re: back trace in gdb after ring 0 exception?

Post by xeyes »

nullplan wrote:Backtracing without call frame information is complicated. Every backtracer I know is going to have to rely on heuristics to get by. On x86, a common assumption is that stack frames are maintained, and that allows the tracer to assume a common frame format. Unfortunately, the stack frame of an exception handler is completely non-standard. You can try to use DWARF call frame information to tell the debugger how to proceed. And good luck with that. I never managed to understand the format. And if you are in 32-bit mode, you have the added bonus of having to support two different stack frame formats in the same place. I'm sure that doesn't make it easier.
Thanks, I've feared that's the case.

Maybe time for a script to call addr2line on any address inside the text section and then manually dig into the suspicious call frames.
xeyes
Member
Member
Posts: 212
Joined: Mon Dec 07, 2020 8:09 am

Re: back trace in gdb after ring 0 exception?

Post by xeyes »

Found a simple way to help GDB out :)

Simply do these in GDB:
1. set EIP to the instruction that triggered the exception
2. set ESP to the location right below the [EIP:CS:EFL] triplet

At this point the machine state is very close to when the exception was about to be hit, and the normal bt cmd can show the correct stack trace with all stack variables and arguments showing correct values

If the frame that hit exception has register vars, they are obviously saved by (your own) exception handler so would be easy to make sense of.
Post Reply