I would really like a debugging tool that is able to visualise the current stack frame (bytes between RSP and RBP) as a block diagram.
Something like this, but with real execution values in the cells:
http://abrickshort.files.wordpress.com/2006/11/stackframe.jpg
Does such software exist? I'm using a UNIX system.
PS.
Aware of gdb's "examine bytes" function. That's what I use now, but I would like pretty diagrams to show my supervisor.
Cheers
GDB won't be able to give you the diagram off-the-shelf, but info frame n gives almost everything you need:
(gdb) info frame 2
Stack frame at 0x7ffff7fe3fe0:
rip = 0x3cbd806ccb in start_thread (pthread_create.c:301); saved rip 0x3cbd0e0c2d
called by frame at 0x0, caller of frame at 0x7ffff7fe3ed0
source language c.
Arglist at 0x7ffff7fe3ec8, args: arg=0x7ffff7fe4700
Locals at 0x7ffff7fe3ec8, Previous frame's sp is 0x7ffff7fe3fe0
Saved registers:
rbx at 0x7ffff7fe3fd0, rip at 0x7ffff7fe3fd8
Related
I was trying to implement a stack tracer, using stack pointers; RSP and RBP, but I think debuggers use an entirely different way to grab the return addresses, or maybe I am missing something. I can grab the return address of the last stack frame, but I can't get the others because I don't know the size of other stack frames, so I can't figure out how much bytes should I go back from stack frame, to get the return address. Are there anybody know which way do debuggers use to trace stack?
It is possible to trace the stack when the code uses frame pointers. In this case ebp/rbp is used as the frame pointer and functions begin with prologs and end with epilogs.
A typical prolog looks like this:
push rbp ; save previous frame pointer
mov rbp, rsp ; initialize this functions frame pointer
A typical epilog looks like this:
mov rsp, rbp ; restore the value of rsp
pop rbp ; restore previous frame pointer value from stack
retn
Thus in every place in a function rbp points to the stack position where the previous frame pointer is saved and rbp+8 contains the saved return address.
To get the called function a debugger should read [rbp+8] value and find a function to which this address belongs. This can be done by searching in debugging symbols.
Next it should read [rbp] value to get the frame pointer of the caller function. Continue this process until you find a toplevel function. This is typically a system library function that starts threads.
Writing x64 Assembly code using MASM, we can use these directives to provide frame unwinding information. For example, from .SETFRAME definition:
These directives do not generate code; they only generate .xdata and .pdata.
Since these directives don't produce any code, I cannot see their effects in Disassembly window. So, I don't see any difference, when I write assembly function with or without these directives. How can I see the result of these directives - using dumpbin or something else?
How to write code that can test this unwinding capability? For example, I intentionally write assembly code that causes an exception. I want to see the difference in exception handling behavior, when function is written with or without these directives.
In my case caller is written in C++, and can use try-catch, SSE etc. - whatever is relevant for this situation.
Answering your question:
How can I see the result of these directives - using dumpbin or something else?
You can use dumpbin /UNWINDINFO out.exe to see the additions to the .pdata resulting from your use of .SETFRAME.
The output will look something like the following:
00000054 00001530 00001541 000C2070
Unwind version: 1
Unwind flags: None
Size of prologue: 0x04
Count of codes: 2
Frame register: rbp
Frame offset: 0x0
Unwind codes:
04: SET_FPREG, register=rbp, offset=0x00
01: PUSH_NONVOL, register=rbp
A bit of explanation to the output:
The second hex number found in the output is the function address 00001530
Unwind codes express what happens in the function prolog. In the example what happens is:
RBP is pushed to the stack
RBP is used as the frame pointer
Other functions may look like the following:
000000D8 000016D0 0000178A 000C20E4
Unwind version: 1
Unwind flags: EHANDLER UHANDLER
Size of prologue: 0x05
Count of codes: 2
Unwind codes:
05: ALLOC_SMALL, size=0x20
01: PUSH_NONVOL, register=rbx
Handler: 000A2A50
One of the main differences here is that this function has an exception handler. This is indicated by the Unwind flags: EHANDLER UHANDLER as well as the Handler: 000A2A50.
Probably your best bet is to have your asm function call another C++ function, and have your C++ function throw a C++ exception. Ideally have the code there depend on multiple values in call-preserved registers, so you can make sure they get restored. But just having unwinding find the right return addresses to get back into your caller requires correct metadata to indicate where that is relative to RSP, for any given RIP.
So create a situation where a C++ exception needs to unwind the stack through your asm function; if it works then you got the stack-unwind metadata directives correct. Specifically, try{}catch in the C++ caller, and throw in a C++ function you call from asm.
That thrower can I think be extern "C" so you can call it from asm without name mangling. Or call it via a function pointer, or just look at MSVC compiler output and copy the mangled name into asm.
Apparently Windows SEH uses the same mechanism as plain C++ exceptions, so you could potentially set up a catch for the exception delivered by the kernel in response to a memory fault from something like mov ds:[0], eax (null deref). You could put this at any point in your function to make sure the exception unwind info was correct about the stack state at every point, not just getting back into sync before a function-call.
https://learn.microsoft.com/en-us/cpp/build/exception-handling-x64?view=msvc-170&viewFallbackFrom=vs-2019 has details about the metadata.
BTW, the non-Windows (e.g. GNU/Linux) equivalent of this metadata is DWARF .cfi directives which create a .eh_frame section.
I don't know equivalent details for Windows, but I do know they use similar metadata that makes it possible to unwind the stack without relying on RBP frame pointers. This lets compilers make optimized code that doesn't waste instructions on push rbp / mov rbp,rsp and leave in function prologues/epilogues, and frees up RBP for use as a general-purpose register. (Even more useful in 32-bit code where 7 instead of 6 registers besides the stack pointer is a much bigger deal than 15 vs. 14.)
The idea is that given a RIP, you can look up the offset from RSP to the return address on the stack, and the locations of any call-preserved registers. So you can restore them and continue unwinding into the parent using that return address.
The metadata indicates where each register was saved, relative to RSP or RBP, given the current RIP as a search key. In functions that use an RBP frame pointer, one piece of metadata can indicate that. (Other metadata for each push rbx / push r12 says which call-preserved regs were saved in which order).
In functions that don't use RBP as a frame pointer, every push / pop or sub/add RSP needs metadata for which RIP it happened at, so given a RIP, stack unwinding can see where the return address is, and where those saved call-preserved registers are. (Functions that use alloca or VLAs thus must use RBP as a frame pointer.)
This is the big-picture problem that the metadata has to solve. There are a lot of details, and it's much easier to leave things up to a compiler!
Seems lldb can only use frame variable to introspect variable whether with debug info or on the start of the method call.
But sometimes our code will break on some system or third lib, we may want to introspect the variable or stack. I find a solution for this, Disassemble the frame, read the assemble code and introspect the stack manually.
But I can't find a quick way to get the frame's stack when it's not on the topmost. Any simple way to do this in lldb or in Xcode.
I found a project in github claimed that can dump all stack memory. So can I use some native lldb command to dump the stack memory of a method call?
It sounds to me like the Python API's to lldb will be best suited to the kind of investigation you want to do:
http://lldb.llvm.org/python_reference/index.html
You want the CFA, then, which you can get from the Python API with SBStackFrame.GetCFA(). The CFA (Call Frame Address) will be the stack frame address when the function was entered. From there to the next younger frame's CFA is the stack memory used by this frame.
You can use SBProcess.ReadMemory to get at the memory.
I'm trying to find a stack overflow in a project on MSP430, and found that it occurs mainly when an IRQ occurs after the stack is pretty full.
I've set a breakpoint on a stack pointer write with a value that is smaller than the start address of the stack, and the CPU halts in the IRQ handler.
The call stack display in IAR C-SPY then terminates at the handler function, however I'd be interested in what is below this, as this is what filled the stack.
Is there a way to display the call stack below the current interrupt handler?
If the interrupt handler is written in C, this should work correctly, as the generated CFI (call frame information) should be correct even for interrupt functions.
However, if this (for some reason) should not work, or if the interrupt routine is written in assembler (without proper CFI directives), you can use a little trick. You can manually modify the PC and SP registers in the register window by retrieving the PC from the stack and by "backing up" the SP the amount that it was adjusted inside the function. After this, the debugger will display the function that was executing when the interrupt occurred.
Note, in the traditional MSP430 core, the PC is stored as a plain 16 bit value. However, in the MSP430X core the 20 bits are a bit intertwined with the status register, see the architecture manual for details.
Is there a way to view the register contents in each stack frame in a crash dump?
The registers window seems to contain the registers when the exception occurred but it would be useful to be able to see their contents in each stack frame.
Depending on the calling convention, you can get some of the registers which are saved on the stack. For example, in the cdecl calling convention, all of the registers except for EAX, ECX, and EDX are required to be saved, either by the caller or the callee. Those three registers are clobberable, so you generally won't be able to get their values from higher up in the call stack. If a function doesn't use a register that must be saved, then it won't save it, but since it doesn't use it, that register has the same value in the next higher stack frame.
After doing some research and thinking about this a bit, I realized that it is probably not possible. A crash minidump saves certain areas of process memory (depending on the flags passed to the MiniDumpWriteDump() function) and enough state information to re-create the environment where the crash happened in a debugger. It does not have the processor state at each instruction or even at each stack frame, it only knows about the processor state when the exception occurred.
In optimized builds, it's true that some information down the stack may get tossed, however, you can ask the debugger to try and show you the information for a given stack frame. First do "kn" to see the stack with frame numbers, then try ".frame /c [frame]" or ".frame /r [frame]".
Check out the help (".hh") for more information.
I don't think you can get it either when debugging. The only value you can get from registers is their value at the current instruction.