debuggercdi/com.nokia.carbide.cpp.debug.crashdebugger/html/DebuggingInformation/CrashDebuggerCallStack.guide05.html
author tzelaw
Tue, 14 Apr 2009 15:03:19 -0500
changeset 94 d74b720418db
parent 2 d760517a8095
child 990 5d016a880824
child 1024 48b401835d0a
permissions -rw-r--r--
Test framework support: Ask debugger to remember DebugTarget so test framework can use it to setup test framework related utility. With this we can use the DebugUI way of launching while keeping test framework functionality
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
cawthron
parents:
diff changeset
     1
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
cawthron
parents:
diff changeset
     2
	"http://www.w3.org/TR/html4/loose.dtd">
cawthron
parents:
diff changeset
     3
	<html><head>
cawthron
parents:
diff changeset
     4
	<title>Walking through the Call Stack</title>
cawthron
parents:
diff changeset
     5
	<link href="sysdoc-eclipse.css" type="text/css" rel="stylesheet" >
cawthron
parents:
diff changeset
     6
	<link href="sysdoc-eclipse.css" type="text/css" rel="stylesheet" >
cawthron
parents:
diff changeset
     7
	<link href="../../book.css" type="text/css" rel="stylesheet" >
cawthron
parents:
diff changeset
     8
<div class="Head1">
cawthron
parents:
diff changeset
     9
  <h2>Walking through the Call Stack</h2>
cawthron
parents:
diff changeset
    10
</div>
cawthron
parents:
diff changeset
    11
<div>
cawthron
parents:
diff changeset
    12
<p>The heuristic method is quick but produces lots of false positives.
cawthron
parents:
diff changeset
    13
Another option is to manually reconstitute the call stack from the memory dump.
cawthron
parents:
diff changeset
    14
This is relatively easy for debug builds because GCC uses R11 as a frame
cawthron
parents:
diff changeset
    15
pointer (FP) and generates the same prologue/epilogue for every
cawthron
parents:
diff changeset
    16
function.</p>
cawthron
parents:
diff changeset
    17
<p>For release builds, there is no generic solution. It is necessary
cawthron
parents:
diff changeset
    18
to check the generated assembler code as there is no standard prologue/epilogue
cawthron
parents:
diff changeset
    19
and R11 is not used as frame pointer.</p>
cawthron
parents:
diff changeset
    20
<p>A typical prologue for a debug ARM function looks like this:</p>
cawthron
parents:
diff changeset
    21
<p class="CodeBlock">mov&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ip, sp<br>stmfd&nbsp;&nbsp;&nbsp;sp!, {fp, ip, lr, pc}<br>sub&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fp, ip, #4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/* FP now points to base of stack frame */<br>sub&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sp, sp, #16&nbsp;&nbsp;&nbsp;&nbsp;/* space for local variables */</p>
cawthron
parents:
diff changeset
    22
<p>noting that: SP = R13, FP = R11, IP
cawthron
parents:
diff changeset
    23
= R12, LR = R14, and PC = R15.</p>
cawthron
parents:
diff changeset
    24
<p>This code creates the following stack frame:</p>
cawthron
parents:
diff changeset
    25
<div class="Figure">
cawthron
parents:
diff changeset
    26
<p class="Image"><a name=""><img src="CrashDebuggerStackFrame-01.gif" alt=""  border="0"></a></p>
cawthron
parents:
diff changeset
    27
</div>
cawthron
parents:
diff changeset
    28
<p>Looking at the example session listed in when
cawthron
parents:
diff changeset
    29
<a href="CrashDebuggerCallStack.guide.html" title="Examining the call stack / Tracing through the stack heuristically">tracing through the stack heuristically</a>. in which the crash is due to a panic, the FP value is the
cawthron
parents:
diff changeset
    30
R11 value; this is 0x6571de70. This gives us the innermost stack
cawthron
parents:
diff changeset
    31
frame:</p>
cawthron
parents:
diff changeset
    32
<p class="CodeBlock">6571de64:&nbsp;&nbsp;&nbsp;e8 de 71 65 &lt;------------- pointer to previous stack frame <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;74 de 71 65 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;74 fb 16 f8 &lt;------------- Saved return address <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;88 28 03 f8 &lt;------------- FP points to this word</p>
cawthron
parents:
diff changeset
    33
<p>Looking up the saved return address, 0xf816fb74, in
cawthron
parents:
diff changeset
    34
the symbol file shows that the current function was called from
cawthron
parents:
diff changeset
    35
DDmaChannel::DoCreate().</p>
cawthron
parents:
diff changeset
    36
<p class="CodeBlock">f816fb50    0198    DDmaTestChannel::DoCreate(int, TDesC8 const *, TVersion const &amp;)<br>f816fce8    007c    DDmaTestChannel::~DDmaTestChannel(void)<br>f816fd64    0294    DDmaTestChannel::Request(int, void *, void *)</p>
cawthron
parents:
diff changeset
    37
<p>Using the pointer to the previous stack frame saved into the
cawthron
parents:
diff changeset
    38
current frame, we can decode the next frame:</p>
cawthron
parents:
diff changeset
    39
<p class="CodeBlock">6571ded4:&nbsp;&nbsp;&nbsp;1c c4 03 64 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;f8 02 00 64 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;10 df 71 65 &lt;------------- pointer to previous stack frame <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ec de 71 65 <br><br>6571dee4:&nbsp;&nbsp;&nbsp;84 da 01 f8 &lt;------------- saved return address <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;5c fb 16 f8 &lt;------------- start of second stack frame <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;00 4e 40 00 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;00 00 00 00 </p>
cawthron
parents:
diff changeset
    40
<p>Looking up the saved return address, 0xf801da84, in
cawthron
parents:
diff changeset
    41
the symbol file shows that DDmaTestChannel::DoCreate() was called
cawthron
parents:
diff changeset
    42
from DLogicalDevice::ChannelCreate().</p>
cawthron
parents:
diff changeset
    43
<p class="CodeBlock">f801d9b4    00f8    DLogicalDevice::ChannelCreate(DLogicalChannelBase *&amp;, TChannelCreateInfo &amp;)<br>f801daac    01b8    ExecHandler::ChannelCreate(TDesC8 const &amp;, TChannelCreateInfo &amp;, int)<br>f801dc64    00e4    ExecHandler::ChannelRequest(DLogicalChannelBase *, int, void *, void *)</p>
cawthron
parents:
diff changeset
    44
<p>And here is the third stack frame:</p>
cawthron
parents:
diff changeset
    45
<p class="CodeBlock">6571df04:&nbsp;&nbsp;&nbsp;d4 df 71 65 &lt;------------- pointer to previous stack frame <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;14 df 71 65 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e0 db 01 f8 &lt;------------- saved return address <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;c0 d9 01 f8 &lt;------------- start of third stack frame </p>
cawthron
parents:
diff changeset
    46
<p>So DLogicalDevice::ChannelCreate() was called from
cawthron
parents:
diff changeset
    47
ExecHandler::ChannelCreate().</p>
cawthron
parents:
diff changeset
    48
<p>Note that this mechanical way of walking the stack is valid only
cawthron
parents:
diff changeset
    49
for debug functions. For release functions, it is necessary to study the code
cawthron
parents:
diff changeset
    50
generated by the compiler.</p>
cawthron
parents:
diff changeset
    51
<p>For completness, this is a typical prologue for a debug THUMB
cawthron
parents:
diff changeset
    52
function:</p>
cawthron
parents:
diff changeset
    53
<p class="CodeBlock">push&nbsp;&nbsp;&nbsp;&nbsp;{ r7, lr }<br>sub&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sp, #28<br>add&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;r7, sp, #12 /* R7 is THUMB frame pointer */</p>
cawthron
parents:
diff changeset
    54
<p>and this creates the following stack frame:</p>
cawthron
parents:
diff changeset
    55
<div class="Figure">
cawthron
parents:
diff changeset
    56
<p class="Image"><a name=""><img src="CrashDebuggerStackFrame-02.gif" alt=""  border="0"></a></p>
cawthron
parents:
diff changeset
    57
</div>
cawthron
parents:
diff changeset
    58
<p>A call stack can mix ARM and THUMB frames. Odd return addresses are
cawthron
parents:
diff changeset
    59
used for THUMB code and even ones for ARM code.</p> 
cawthron
parents:
diff changeset
    60
cawthron
parents:
diff changeset
    61
</div>
cawthron
parents:
diff changeset
    62
<h5>Related tasks</h5>
cawthron
parents:
diff changeset
    63
<ul>
cawthron
parents:
diff changeset
    64
  <li><a href="CrashDebuggerCallStack.guide02.html">General Points</a></li>
cawthron
parents:
diff changeset
    65
  <li><a href="CrashDebuggerCallStack.guide03.html">Finding the Stack</a></li>
cawthron
parents:
diff changeset
    66
  <li><a href="CrashDebuggerCallStack.guide04.html">Tracing through the Call Stack Heuristically</a></li>
cawthron
parents:
diff changeset
    67
</ul>
cawthron
parents:
diff changeset
    68
<div id="footer">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></div>
cawthron
parents:
diff changeset
    69
	   </body>
cawthron
parents:
diff changeset
    70
	   </html>
cawthron
parents:
diff changeset
    71