debuggercdi/com.nokia.carbide.cpp.debug.crashdebugger/html/DebuggingInformation/CrashDebuggerCallStack.guide04.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>Tracing through the Stack Heuristically</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="Head2">
cawthron
parents:
diff changeset
     9
<h2>Tracing through the Stack Heuristically</h2>
cawthron
parents:
diff changeset
    10
</div>
cawthron
parents:
diff changeset
    11
<div>
cawthron
parents:
diff changeset
    12
One way of tracing through the call stack is to assume that every word on the stack which looks like a ROM code address is a saved return
cawthron
parents:
diff changeset
    13
address. We say that this heuristic because:
cawthron
parents:
diff changeset
    14
<ul>
cawthron
parents:
diff changeset
    15
<li>
cawthron
parents:
diff changeset
    16
<p>some data words may look like code addresses in ROM.</p>
cawthron
parents:
diff changeset
    17
</li>
cawthron
parents:
diff changeset
    18
<li>
cawthron
parents:
diff changeset
    19
<p>there may be saved return addresses left over from previous
cawthron
parents:
diff changeset
    20
function calls. For example, suppose that F() calls
cawthron
parents:
diff changeset
    21
A() and then B() in sequence. A() itself
cawthron
parents:
diff changeset
    22
calls X(), which calls Y(). If a crash occurs in
cawthron
parents:
diff changeset
    23
B(), the saved return addresses from the calls to X()
cawthron
parents:
diff changeset
    24
and Y() are still present on the stack and may be mistaken for
cawthron
parents:
diff changeset
    25
function calls occuring while B() is active.</p>
cawthron
parents:
diff changeset
    26
<p>This scenario happens frequently when B()
cawthron
parents:
diff changeset
    27
allocates a buffer (e.g. TBuf) on the stack which overlaps
cawthron
parents:
diff changeset
    28
old stack frames.</p>
cawthron
parents:
diff changeset
    29
<div class="Figure">
cawthron
parents:
diff changeset
    30
<p class="Image"><a name=""><img src="CrashDebuggerCallStackHeuristic-01.gif" alt=""  border="0"></a></p>
cawthron
parents:
diff changeset
    31
</div>
cawthron
parents:
diff changeset
    32
</li>
cawthron
parents:
diff changeset
    33
</ul>
cawthron
parents:
diff changeset
    34
<p>If you want to trace applications loaded into RAM, then stack
cawthron
parents:
diff changeset
    35
tracing is more difficult because RAM-loaded DLLs are given addresses assigned
cawthron
parents:
diff changeset
    36
at load time.</p>
cawthron
parents:
diff changeset
    37
<p>On ARM, the stack pointer starts at the higher address end and
cawthron
parents:
diff changeset
    38
moves 'down' towards the lower address end. This means that values at the top
cawthron
parents:
diff changeset
    39
of the memory dump are more recent. You need to look back through this for code
cawthron
parents:
diff changeset
    40
addresses. For ROM code this will be words with most significant byte in the
cawthron
parents:
diff changeset
    41
range 0xF8 to 0xFF, remembering that they are
cawthron
parents:
diff changeset
    42
little-endian. This can either be done manually, or automatically using the
cawthron
parents:
diff changeset
    43
printsym.pl perl script, which can be found in
cawthron
parents:
diff changeset
    44
...\epoc32\tools.</p>
cawthron
parents:
diff changeset
    45
<p>Let's follow this in an example session:</p>
cawthron
parents:
diff changeset
    46
<ul>
cawthron
parents:
diff changeset
    47
<li>
cawthron
parents:
diff changeset
    48
<p>Decide whether the crash has been caused by a panic or an
cawthron
parents:
diff changeset
    49
exception using the <a href="CrashDebugger_cmd_f.guide.html" title="The debug monitor and command syntax / f - display kernel fault information">f</a> command:</p>
cawthron
parents:
diff changeset
    50
<p class="CodeBlock">.f<br>Fault Category: EXAMPLE  Fault Reason: 0000002a<br>ExcId 00000000 CodeAddr 00000000 DataAddr 00000000 Extra 00000000</p>
cawthron
parents:
diff changeset
    51
</li>
cawthron
parents:
diff changeset
    52
<li>
cawthron
parents:
diff changeset
    53
<p>This shows that the crash was caused by a panic, so now use the
cawthron
parents:
diff changeset
    54
<a href="CrashDebugger_cmd_r.guide.html" title="The debug monitor and command syntax / r - dump register contents">r</a> command to find
cawthron
parents:
diff changeset
    55
the CPU mode and the stack pointer:</p>
cawthron
parents:
diff changeset
    56
<p class="CodeBlock">.r<br>MODE_USR:<br>&nbsp;R0=6571de54  R1=0000002a  R2=00000002  R3=ffffffff<br>&nbsp;R4=0000002a  R5=f8170414  R6=6571df14  R7=6403cba8<br>&nbsp;R8=00000001  R9=6403c41c R10=640002f8 R11=6571de70<br>R12=00000020 R13=00404e00 R14=f80818c0 R15=f800bfa8<br>CPSR=60000013<br>MODE_FIQ:<br>&nbsp;R8=00000000  R9=ffffffff R10=ffffffff R11=00000000<br>R12=00000000 R13=64000d0c R14=c080079c SPSR=e00000dc<br>MODE_IRQ:<br>R13=6400110c R14=00000013 SPSR=20000013<br>MODE_SVC:<br>R13=6571de54 R14=f80328bc SPSR=60000010<br>MODE_ABT:<br>R13=6400090c R14=ffff0010 SPSR=400000d7<br>MODE_UND:<br>R13=6400090c R14=95221110 SPSR=f000009d</p>
cawthron
parents:
diff changeset
    57
<p>The panic happened in supervisor mode, because CPSR &amp;
cawthron
parents:
diff changeset
    58
0x1F == 0x13, so R13Svc, i.e. the value of R13
cawthron
parents:
diff changeset
    59
shown under MODE_SVC: in the above display, is the stack pointer
cawthron
parents:
diff changeset
    60
to look at; this has the value 0x6571DE54.</p>
cawthron
parents:
diff changeset
    61
</li>
cawthron
parents:
diff changeset
    62
<li>
cawthron
parents:
diff changeset
    63
<p>Using the
cawthron
parents:
diff changeset
    64
<a href="CrashDebugger_cmd_m.guide.html" title="The debug monitor and command syntax / m - do a memory dump">m</a> command to look
cawthron
parents:
diff changeset
    65
at memory starting at location 0x6571DE54 gives:</p>
cawthron
parents:
diff changeset
    66
<p class="CodeBlock">.m6571de54+200<br>6571de54: 07 00 00 10 14 04 17 f8 00 00 00 00 d4 4e 40 00 .............N@.<br>6571de64: e8 de 71 65 74 de 71 65 74 fb 16 f8 88 28 03 f8 ..qet.qet....(..<br>6571de74: 0c d4 03 f8 64 35 03 f8 00 00 00 00 00 00 00 00 ....d5..........<br>6571de84: d0 00 00 00 14 df 71 65 a8 cb 03 64 a8 cb 03 64 ......qe...d...d<br>6571de94: d0 00 00 00 14 df 71 65 1c df 71 65 ec 4e 40 00 ......qe..qe.N@.<br>6571dea4: 1c c4 03 64 b4 2a 03 f8 00 00 00 00 14 df 71 65 ...d.*........qe<br>6571deb4: d0 de 71 65 c4 de 71 65 b0 ab 03 f8 00 00 00 00 ..qe..qe........<br>6571dec4: e0 ba 03 64 14 df 71 65 1c df 71 65 01 00 00 00 ...d..qe..qe....<br>6571ded4: 1c c4 03 64 f8 02 00 64 10 df 71 65 ec de 71 65 ...d...d..qe..qe<br>6571dee4: 84 da 01 f8 5c fb 16 f8 00 4e 40 00 00 00 00 00 ....\....N@.....<br>6571def4: 00 4e 40 00 00 00 00 00 d3 00 00 00 ec 4e 40 00 .N@..........N@.<br>6571df04: d4 df 71 65 14 df 71 65 e0 db 01 f8 c0 d9 01 f8 ..qe..qe........<br>6571df14: a8 cb 03 64 e0 ba 03 64 01 00 01 00 00 00 00 00 ...d...d........<br>6571df24: 00 00 00 00 d4 4e 40 00 00 00 00 30 40 00 00 00 .....N@....0@...<br>6571df34: 13 00 00 60 98 df 71 65 48 df 71 65 f4 81 00 f8 ...`..qeH.qe....<br>6571df44: 8c 7a 00 f8 68 df 71 65 58 df 71 65 6c df 71 65 .z..h.qeX.qel.qe<br>6571df54: 60 df 71 65 0c 2b 00 f8 bc 2a 00 f8 84 df 71 65 `.qe.+...*....qe<br>6571df64: 70 df 71 65 e4 7d 04 f8 08 2b 00 f8 0d 00 00 00 p.qe.}...+......<br>6571df74: 0a 00 00 30 40 00 00 00 54 65 73 74 44 6d 61 53 ...0@...TestDmaS<br>6571df84: 69 6d 04 f8 a9 4b 40 00 b8 df 71 65 9c df 71 65 im...K@...qe..qe<br>6571df94: 2c be 00 f8 2c bd 00 f8 38 4c 40 0d 01 00 00 00 ,...,...8L@.....<br>6571dfa4: 00 00 00 00 84 2d 02 f8 d4 df 71 65 bc df 71 65 .....-....qe..qe<br>6571dfb4: b8 2d 02 f8 dc bd 00 f8 54 a4 00 f8 00 00 00 00 .-......T.......<br>6571dfc4: ac da 01 f8 10 00 00 60 d8 df 71 65 70 74 00 f8 .......`..qept..<br>6571dfd4: b8 da 01 f8 d4 4e 40 00 20 f7 16 f8 d0 4e 40 00 .....N@. ....N@.<br>6571dfe4: 00 00 00 00 00 00 00 00 ec 4e 40 00 40 00 00 00 .........N@.@...</p>
cawthron
parents:
diff changeset
    67
<p>We can look for potential ROM addresses by scanning the log and
cawthron
parents:
diff changeset
    68
look up the corresponding function name in the symbol file generated
cawthron
parents:
diff changeset
    69
<a href="CrashDebuggerUsingMAKSYM-Ref.guide.html">using the MAKSYM tool</a> . The first
cawthron
parents:
diff changeset
    70
one is 0xF8170414 at offset 4 in the memory dump.
cawthron
parents:
diff changeset
    71
</p>
cawthron
parents:
diff changeset
    72
</li>
cawthron
parents:
diff changeset
    73
<li>
cawthron
parents:
diff changeset
    74
<p>Alternatively, we can use the printsym.pl perl
cawthron
parents:
diff changeset
    75
script, passing it the dump output. The following is part of the output:</p>
cawthron
parents:
diff changeset
    76
<p class="CodeBlock">R:\base\e32\rombuild&gt;perl -S printsym.pl ASSABETARM4D.symbol<br>ROM Symbols from ASSABETARM4D.symbol<br>Please enter data to be decoded<br>6571de54: 07 00 00 10 14 04 17 f8 00 00 00 00 d4 4e 40 00 .............N@.<br>= 10000007 ....&nbsp;<br>= f8170414 ....  etext=. + 0x0<br>= 00000000 ....<br>= 00404ed4 .N@.<br>6571de64: e8 de 71 65 74 de 71 65 74 fb 16 f8 88 28 03 f8 ..qet.qet....(..<br>= 6571dee8 ..qe<br>= 6571de74 t.qe<br>= f816fb74 t...  DDmaTestChannel::DoCreate(int, TDesC8 const *, TVersion const &amp;<br>) + 0x24<br>= f8032888 .(..  Kern::Fault(char const *, int) + 0xc<br>6571de74: 0c d4 03 f8 64 35 03 f8 00 00 00 00 00 00 00 00 ....d5..........<br>= f803d40c ....  RHeap::Alloc(int) + 0xf4<br>= f8033564 d5..  Kern::MutexSignal(DMutex &amp;) + 0xc<br>= 00000000 ....<br>= 00000000 ....<br><br>[............ truncated ...............]<br><br>= f801da84 ....  DLogicalDevice::ChannelCreate(DLogicalChannelBase *&amp;, TChannelC<br>reateInfo &amp;) + 0xd0<br>= f816fb5c \...  DDmaTestChannel::DoCreate(int, TDesC8 const *, TVersion const &amp;<br>) + 0xc<br>= 00404e00 .N@.<br>= 00000000 ....<br>6571def4: 00 4e 40 00 00 00 00 00 d3 00 00 00 ec 4e 40 00 .N@..........N@.<br>= 00404e00 .N@.<br>= 00000000 ....<br>= 000000d3 ....<br>= 00404eec .N@.<br>6571df04: d4 df 71 65 14 df 71 65 e0 db 01 f8 c0 d9 01 f8 ..qe..qe........<br>= 6571dfd4 ..qe<br>= 6571df14 ..qe<br>= f801dbe0 ....  ExecHandler::ChannelCreate(TDesC8 const &amp;, TChannelCreateInfo &amp;<br>, int) + 0x134<br>= f801d9c0 ....  DLogicalDevice::ChannelCreate(DLogicalChannelBase *&amp;, TChannelC<br>reateInfo &amp;) + 0xc<br><br>[.......................... truncated .........................]<br><br>= f8022db8 .-..  ExecHandler::DebugPrint(void *, int) + 0x34<br>= f800bddc ....  A::UserDebugPrint(unsigned char const *, int, int) + 0xc<br>= f800a454 T...  EpocSlowExecTable + 0xc<br>= 00000000 ....<br>6571dfc4: ac da 01 f8 10 00 00 60 d8 df 71 65 70 74 00 f8 .......`..qept..<br>= f801daac ....  ExecHandler::ChannelCreate(TDesC8 const &amp;, TChannelCreateInfo &amp;<br>, int) + 0x0<br>= 60000010 ...`<br>= 6571dfd8 ..qe<br>= f8007470 pt..  __ArmVectorSwi + 0xd8<br>6571dfd4: b8 da 01 f8 d4 4e 40 00 20 f7 16 f8 d0 4e 40 00 .....N@. ....N@.<br>= f801dab8 ....  ExecHandler::ChannelCreate(TDesC8 const &amp;, TChannelCreateInfo &amp;<br>, int) + 0xc<br>= 00404ed4 .N@.<br>= f816f720  ...  etext=. + 0x560<br>= 00404ed0 .N@.<br>6571dfe4: 00 00 00 00 00 00 00 00 ec 4e 40 00 40 00 00 00 .........N@.@...<br>= 00000000 ....<br>= 00000000 ....<br>= 00404eec .N@.<br>= 00000040 @...<br>^C<br>R:\base\e32\rombuild&gt;</p>
cawthron
parents:
diff changeset
    77
<p>There are several false positives in this output (and even more
cawthron
parents:
diff changeset
    78
in the truncated parts). So some study of the source code is needed to discard
cawthron
parents:
diff changeset
    79
the noise and find the actual call stack. Here it is (innermost frame
cawthron
parents:
diff changeset
    80
first):</p>
cawthron
parents:
diff changeset
    81
<ul>
cawthron
parents:
diff changeset
    82
<li>
cawthron
parents:
diff changeset
    83
<p>Kern::Fault</p>
cawthron
parents:
diff changeset
    84
</li>
cawthron
parents:
diff changeset
    85
<li>
cawthron
parents:
diff changeset
    86
<p>DDmaTestChannel::DoCreate</p>
cawthron
parents:
diff changeset
    87
</li>
cawthron
parents:
diff changeset
    88
<li>
cawthron
parents:
diff changeset
    89
<p>ExecHandler::ChannelCreate</p>
cawthron
parents:
diff changeset
    90
</li>
cawthron
parents:
diff changeset
    91
<li>
cawthron
parents:
diff changeset
    92
<p> __ArmVectorSwi</p>
cawthron
parents:
diff changeset
    93
</li>
cawthron
parents:
diff changeset
    94
</ul>
cawthron
parents:
diff changeset
    95
<p>Note that for the sake of the example, a call to Kern::Fault() was deliberately inserted into
cawthron
parents:
diff changeset
    96
DDmaTestChannel::DoCreate().</p>
cawthron
parents:
diff changeset
    97
<p>All other function names are false positives and should be
cawthron
parents:
diff changeset
    98
ignored</p>
cawthron
parents:
diff changeset
    99
</li>
cawthron
parents:
diff changeset
   100
</ul>
cawthron
parents:
diff changeset
   101
<h5>Related tasks</h5>
cawthron
parents:
diff changeset
   102
<ul>
cawthron
parents:
diff changeset
   103
  <li><a href="CrashDebuggerCallStack.guide02.html">General Points</a></li>
cawthron
parents:
diff changeset
   104
  <li><a href="CrashDebuggerCallStack.guide03.html">Finding the Stack</a></li>
cawthron
parents:
diff changeset
   105
  <li><a href="CrashDebuggerCallStack.guide05.html">Walking through the Call Stack</a></li>
cawthron
parents:
diff changeset
   106
</ul>
cawthron
parents:
diff changeset
   107
<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
   108
	   </div>