Chapter 4 - If the crash point is not located inside the program itself. |
It can happen that the crash offset is not located inside the program.
Typically, it is when performing a system call using wrong parameter or when
misusing a function pointer.
Hopefully, it is still possible to know the point where the program performed
this system call or function pointer jump. This is achieved using the LR
register.
The LR register contains the address where the program will return to when it
will exit from the current function. This address points to the function which
called the current one.
So, if the func1() function calls the func2() function and the program crashes
in func2(), then SRR0 points to func2() and LR points to func1().
int main(void)
{
WriteWord(NULL, 0);
ReadLong((ULONG *)0xFFFFFFFF);
return 0;
}
When the above "hitmania" program crashes in the WriteWord() function, then
the SRR0 register contains an address pointing to the WriteWord() function and
the LR register contains an address pointing to the main() function.
------------------------------------------------------------------------------
136> SRR0 -> hitmania Hunk 1 Offset 0x00000624
137> LR -> hitmania Hunk 1 Offset 0x0000064c
------------------------------------------------------------------------------
0x624 is in WriteWord() as seen in the chapter 3
0x64c is in main()
If the program is a bit more complex and calls a func1() function calling a
func2() function calling a func3() function where it crashes, then SRR0 will
point to func3() and LR will point to func2(). But no register will contain a
reference to func1().
But there is a way to trace all previous functions and get a reference to
func1(). This is achieved using the "stack frame".
Everytime a new function is executed, the program allocates a new stack frame
where it saves the current context. The content of the LR register is also
saved in the stack frame.
So, by analyzing previous stack frames, it is possible to know previous LR
contents and to trace the program.
When a crash happens, MorphOS fetchs all possible information from the stack
frames and displays it:
136> SRR0 -> hitmania Hunk 1 Offset 0x00000624
137> LR -> hitmania Hunk 1 Offset 0x0000064c
138> CTR -> Module Hunk 0 Offset 0x00015934
139>
140> PPCStackFrame History:
141> StackFrame[-0].LR-> Address 0x212408cc -> hitmania Hunk 1 Offset 0x000004bc
142> StackFrame[-1].LR-> Address 0x212406ac -> hitmania Hunk 1 Offset 0x0000029c
That means the current content of the LR register is 0x64c (the func3
function). Its previous content was 0x4bc (the func2 function). And just
before, it was 0x29c (the func1 function).
To debug a program crashed in some foreign code, simply look at the LR content
until there is an address inside the program code.
If there is no such address in the stack frame, then read the questions about
hardcore problems in the FAQ (chapter 8).