debuggercdi/com.nokia.carbide.cpp.debug.crashdebugger/html/DebuggingInformation/CrashDebuggerCallStack.guide04.html
changeset 0 fb279309251b
child 990 5d016a880824
child 1024 48b401835d0a
equal deleted inserted replaced
-1:000000000000 0:fb279309251b
       
     1 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
       
     2 	"http://www.w3.org/TR/html4/loose.dtd">
       
     3 	<html><head>
       
     4 	<title>Tracing through the Stack Heuristically</title>
       
     5 	<link href="sysdoc-eclipse.css" type="text/css" rel="stylesheet" >
       
     6 	<link href="sysdoc-eclipse.css" type="text/css" rel="stylesheet" >
       
     7 	<link href="../../book.css" type="text/css" rel="stylesheet" >
       
     8 <div class="Head2">
       
     9 <h2>Tracing through the Stack Heuristically</h2>
       
    10 </div>
       
    11 <div>
       
    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
       
    13 address. We say that this heuristic because:
       
    14 <ul>
       
    15 <li>
       
    16 <p>some data words may look like code addresses in ROM.</p>
       
    17 </li>
       
    18 <li>
       
    19 <p>there may be saved return addresses left over from previous
       
    20 function calls. For example, suppose that F() calls
       
    21 A() and then B() in sequence. A() itself
       
    22 calls X(), which calls Y(). If a crash occurs in
       
    23 B(), the saved return addresses from the calls to X()
       
    24 and Y() are still present on the stack and may be mistaken for
       
    25 function calls occuring while B() is active.</p>
       
    26 <p>This scenario happens frequently when B()
       
    27 allocates a buffer (e.g. TBuf) on the stack which overlaps
       
    28 old stack frames.</p>
       
    29 <div class="Figure">
       
    30 <p class="Image"><a name=""><img src="CrashDebuggerCallStackHeuristic-01.gif" alt=""  border="0"></a></p>
       
    31 </div>
       
    32 </li>
       
    33 </ul>
       
    34 <p>If you want to trace applications loaded into RAM, then stack
       
    35 tracing is more difficult because RAM-loaded DLLs are given addresses assigned
       
    36 at load time.</p>
       
    37 <p>On ARM, the stack pointer starts at the higher address end and
       
    38 moves 'down' towards the lower address end. This means that values at the top
       
    39 of the memory dump are more recent. You need to look back through this for code
       
    40 addresses. For ROM code this will be words with most significant byte in the
       
    41 range 0xF8 to 0xFF, remembering that they are
       
    42 little-endian. This can either be done manually, or automatically using the
       
    43 printsym.pl perl script, which can be found in
       
    44 ...\epoc32\tools.</p>
       
    45 <p>Let's follow this in an example session:</p>
       
    46 <ul>
       
    47 <li>
       
    48 <p>Decide whether the crash has been caused by a panic or an
       
    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>
       
    50 <p class="CodeBlock">.f<br>Fault Category: EXAMPLE  Fault Reason: 0000002a<br>ExcId 00000000 CodeAddr 00000000 DataAddr 00000000 Extra 00000000</p>
       
    51 </li>
       
    52 <li>
       
    53 <p>This shows that the crash was caused by a panic, so now use the
       
    54 <a href="CrashDebugger_cmd_r.guide.html" title="The debug monitor and command syntax / r - dump register contents">r</a> command to find
       
    55 the CPU mode and the stack pointer:</p>
       
    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>
       
    57 <p>The panic happened in supervisor mode, because CPSR &amp;
       
    58 0x1F == 0x13, so R13Svc, i.e. the value of R13
       
    59 shown under MODE_SVC: in the above display, is the stack pointer
       
    60 to look at; this has the value 0x6571DE54.</p>
       
    61 </li>
       
    62 <li>
       
    63 <p>Using the
       
    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
       
    65 at memory starting at location 0x6571DE54 gives:</p>
       
    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>
       
    67 <p>We can look for potential ROM addresses by scanning the log and
       
    68 look up the corresponding function name in the symbol file generated
       
    69 <a href="CrashDebuggerUsingMAKSYM-Ref.guide.html">using the MAKSYM tool</a> . The first
       
    70 one is 0xF8170414 at offset 4 in the memory dump.
       
    71 </p>
       
    72 </li>
       
    73 <li>
       
    74 <p>Alternatively, we can use the printsym.pl perl
       
    75 script, passing it the dump output. The following is part of the output:</p>
       
    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>
       
    77 <p>There are several false positives in this output (and even more
       
    78 in the truncated parts). So some study of the source code is needed to discard
       
    79 the noise and find the actual call stack. Here it is (innermost frame
       
    80 first):</p>
       
    81 <ul>
       
    82 <li>
       
    83 <p>Kern::Fault</p>
       
    84 </li>
       
    85 <li>
       
    86 <p>DDmaTestChannel::DoCreate</p>
       
    87 </li>
       
    88 <li>
       
    89 <p>ExecHandler::ChannelCreate</p>
       
    90 </li>
       
    91 <li>
       
    92 <p> __ArmVectorSwi</p>
       
    93 </li>
       
    94 </ul>
       
    95 <p>Note that for the sake of the example, a call to Kern::Fault() was deliberately inserted into
       
    96 DDmaTestChannel::DoCreate().</p>
       
    97 <p>All other function names are false positives and should be
       
    98 ignored</p>
       
    99 </li>
       
   100 </ul>
       
   101 <h5>Related tasks</h5>
       
   102 <ul>
       
   103   <li><a href="CrashDebuggerCallStack.guide02.html">General Points</a></li>
       
   104   <li><a href="CrashDebuggerCallStack.guide03.html">Finding the Stack</a></li>
       
   105   <li><a href="CrashDebuggerCallStack.guide05.html">Walking through the Call Stack</a></li>
       
   106 </ul>
       
   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>
       
   108 	   </div>