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).

<< How to find where the program crashed (using objdump) | A few tips >>