Adaptation/GUID-1E43E258-A926-5D24-B0A5-8756491C687F.dita
changeset 15 307f4279f433
equal deleted inserted replaced
14:578be2adaf3e 15:307f4279f433
       
     1 <?xml version="1.0" encoding="utf-8"?>
       
     2 <!-- Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies) All rights reserved. -->
       
     3 <!-- This component and the accompanying materials are made available under the terms of the License 
       
     4 "Eclipse Public License v1.0" which accompanies this distribution, 
       
     5 and is available at the URL "http://www.eclipse.org/legal/epl-v10.html". -->
       
     6 <!-- Initial Contributors:
       
     7     Nokia Corporation - initial contribution.
       
     8 Contributors: 
       
     9 -->
       
    10 <!DOCTYPE concept
       
    11   PUBLIC "-//OASIS//DTD DITA Concept//EN" "concept.dtd">
       
    12 <concept id="GUID-1E43E258-A926-5D24-B0A5-8756491C687F" xml:lang="en"><title>Call
       
    13 Stack Information Commands</title><prolog><metadata><keywords/></metadata></prolog><conbody>
       
    14 <p>Describes how to use the debug monitor commands to get information about
       
    15 the call stack. </p>
       
    16 <ul>
       
    17 <li id="GUID-9D1E42B6-658E-59DF-AC7D-0551B8EF6B61"><p> <xref href="GUID-1E43E258-A926-5D24-B0A5-8756491C687F.dita#GUID-1E43E258-A926-5D24-B0A5-8756491C687F/GUID-D8F141D7-3BE2-5ADB-8A55-CFFE85E89804">General points</xref>  </p> </li>
       
    18 <li id="GUID-92B8F3E9-11C1-5260-A862-6CE017984DB0"><p> <xref href="GUID-1E43E258-A926-5D24-B0A5-8756491C687F.dita#GUID-1E43E258-A926-5D24-B0A5-8756491C687F/GUID-1EC3F2E7-6BFF-56BE-B042-DA6940CC909E">Finding the stack</xref>  </p> </li>
       
    19 <li id="GUID-CEFC5F08-C19E-53DD-A0E2-C9C4FFFF3490"><p> <xref href="GUID-1E43E258-A926-5D24-B0A5-8756491C687F.dita#GUID-1E43E258-A926-5D24-B0A5-8756491C687F/GUID-877742A5-F07F-54B6-B871-255FAAE790EB">Tracing through the call stack heuristically</xref>  </p> </li>
       
    20 <li id="GUID-8D00F8C3-B367-5C75-89E4-B712002E942D"><p> <xref href="GUID-1E43E258-A926-5D24-B0A5-8756491C687F.dita#GUID-1E43E258-A926-5D24-B0A5-8756491C687F/GUID-7F160B0F-9921-578B-B9B0-7CC4CA3B24C3">Walking through the call stack</xref>  </p> </li>
       
    21 </ul>
       
    22 <section id="GUID-D8F141D7-3BE2-5ADB-8A55-CFFE85E89804"><title>General points</title> <p>Tracing
       
    23 the call stack is an advanced use of the <xref href="GUID-08E14B34-5144-5AA8-AA55-7AF03671676C.dita#GUID-08E14B34-5144-5AA8-AA55-7AF03671676C/GUID-2A0D5950-F1A5-5EE1-87A3-840B1EAD6AAD">m</xref> command that allows you to <xref href="GUID-DC2CF276-95E2-5810-9B8D-EB8B72E04FEC.dita">examine
       
    24 memory</xref>. </p> <p>Every time a function is called, the return address
       
    25 is automatically saved into register <codeph>R14</codeph> (Link Register).
       
    26 In addition to this the return address is generally pushed onto the call stack;
       
    27 it is always pushed in debug builds but the push operation is sometimes optimized
       
    28 out in release builds. This allows you to trace back through the value of <codeph>R14</codeph> and
       
    29 these saved addresses to see the sequence of function calls. Unfortunately
       
    30 this is quite tedious to do because the stack is also used for automatic variables
       
    31 and other data. You need to work out which values on the stack refer to return
       
    32 addresses. </p> <p>When you are debugging only ROM-based code, it is relatively
       
    33 easy to identify the pushed return addresses because all code addresses will
       
    34 be in the ROM range: <codeph>0xF800000</codeph> to <codeph>0xFFEFFFFF</codeph> for
       
    35 the <xref href="GUID-D520CBC3-FCAC-5A53-AE1A-E5254ABBC6A2.dita#GUID-D520CBC3-FCAC-5A53-AE1A-E5254ABBC6A2/GUID-A5845A0C-2C88-52BB-B7DE-210C2DE481B9">moving
       
    36 model</xref>. However, there is also data in the ROM, which means that an
       
    37 address on the stack which is in the ROM range could point to data instead
       
    38 of code. If you want to trace applications loaded into RAM, i.e. anything
       
    39 not run from drive Z:, then stack tracing is more difficult because the code
       
    40 can move about and RAM-loaded code is given an address assigned at load time. </p> <p>Note
       
    41 that <xref href="GUID-DA62FD4F-2E74-5B2F-B703-4A40DF5F01CA.dita">using the MAKSYM
       
    42 tool</xref> is essential for tracing back through the stack. </p> </section>
       
    43 <section id="GUID-1EC3F2E7-6BFF-56BE-B042-DA6940CC909E"><title>Finding the
       
    44 stack</title> <p>To trace back through a thread’s kernel or user stack, you
       
    45 first need to find the stack pointer value. On the ARM, <codeph>R13</codeph> always
       
    46 points to the stack, but there are different <codeph>R13</codeph> registers
       
    47 for each processor mode: </p> <ul>
       
    48 <li id="GUID-756C8CDD-AF47-561B-BAA7-EA8FBDEE5245"><p>In thread context: </p> <ul>
       
    49 <li id="GUID-81BC92C2-6022-5EBF-BF60-C4D69131C720"><p> <codeph>R13usr</codeph> points
       
    50 to the thread’s user stack, </p> </li>
       
    51 <li id="GUID-CA6CF8C9-0BA3-5BD4-AECE-80AB3DFCFAD1"><p> <codeph>R13svc</codeph> points
       
    52 to the thread’s kernel stack. </p> </li>
       
    53 </ul> </li>
       
    54 <li id="GUID-C4A1AD73-64E8-56F7-A7DF-129B2A35FC9D"><p>When handling interrupts,
       
    55 dedicated stacks are used: </p> <ul>
       
    56 <li id="GUID-7D27A691-1479-578B-9B05-7946C8D84010"><p> <codeph>R13Fiq</codeph> points
       
    57 to the stack used when processing fast interrupts (FIQ). </p> </li>
       
    58 <li id="GUID-CE76BE0F-A6BA-55A6-8CDD-B1E40D97A42D"><p> <codeph>R13Irq</codeph> points
       
    59 to the stack used when processing general purpose interrupts (IRQ). </p> </li>
       
    60 </ul> </li>
       
    61 </ul> <p>To find out which stack to inspect, you need to know what mode the
       
    62 CPU was in when the fault occurred. The <xref href="GUID-7ECDCF7B-3B2A-561F-9136-04BC4DAE46E4.dita#GUID-7ECDCF7B-3B2A-561F-9136-04BC4DAE46E4/GUID-BFA2235C-1598-59E6-9F1F-A8281F13A957">processor
       
    63 mode</xref> is identified by the five least-significant bits of the CPSR register.
       
    64 To get the value of the CPSR register: </p> <ul>
       
    65 <li id="GUID-2FAF9E34-CCF0-5C6E-AA6A-9D274433FC49"><p>use the <xref href="GUID-08E14B34-5144-5AA8-AA55-7AF03671676C.dita#GUID-08E14B34-5144-5AA8-AA55-7AF03671676C/GUID-D5F2E0AF-EF03-5150-813B-DF989F12C47B">f</xref> command when the debug monitor is triggered by a hardware exception. </p> </li>
       
    66 <li id="GUID-EECA647F-38C8-5B57-80EA-B4D9EBA1928B"><p>use the <xref href="GUID-08E14B34-5144-5AA8-AA55-7AF03671676C.dita#GUID-08E14B34-5144-5AA8-AA55-7AF03671676C/GUID-0CDF0190-A445-526B-AC1F-D9D58095B18B">r</xref> command when the debug monitor is triggered by a panic. </p> </li>
       
    67 </ul> <p>The following examples show how to find the stack(s): </p> <ul>
       
    68 <li id="GUID-A5533A14-EEF7-5A9F-B93B-E6E41ECF3928"><p> <xref href="GUID-1E43E258-A926-5D24-B0A5-8756491C687F.dita#GUID-1E43E258-A926-5D24-B0A5-8756491C687F/GUID-4E735CB7-3171-58FB-9D93-EE86702952F6">Kernel &amp; user stacks of the current thread after a hardware exception</xref>  </p> </li>
       
    69 <li id="GUID-750F8489-5918-5062-9ABC-C8951E50716A"><p> <xref href="GUID-1E43E258-A926-5D24-B0A5-8756491C687F.dita#GUID-1E43E258-A926-5D24-B0A5-8756491C687F/GUID-FB9D2307-01D9-562A-A46F-AAD91D61C32E">Kernel &amp; user stacks of the current thread after a panic</xref>  </p> </li>
       
    70 <li id="GUID-0ADBB680-827C-5AEF-96F9-B5684B146097"><p> <xref href="GUID-1E43E258-A926-5D24-B0A5-8756491C687F.dita#GUID-1E43E258-A926-5D24-B0A5-8756491C687F/GUID-C265F9C5-3280-5A4F-B023-56E33D52DDE0">Interrupt stacks</xref>  </p> </li>
       
    71 <li id="GUID-B7CA8584-317C-5ECB-9D4D-2EEFED3F51EA"><p> <xref href="GUID-1E43E258-A926-5D24-B0A5-8756491C687F.dita#GUID-1E43E258-A926-5D24-B0A5-8756491C687F/GUID-9637574E-A9A0-509D-B9B1-C672E2B13431">Kernel &amp; user stacks of a non-current thread</xref>  </p> </li>
       
    72 </ul> <p id="GUID-4E735CB7-3171-58FB-9D93-EE86702952F6"><b>Kernel &amp; user stacks
       
    73 of the current thread after a hardware exception</b> </p> <p>Use the <xref href="GUID-08E14B34-5144-5AA8-AA55-7AF03671676C.dita#GUID-08E14B34-5144-5AA8-AA55-7AF03671676C/GUID-D5F2E0AF-EF03-5150-813B-DF989F12C47B">f</xref> command. </p> <codeblock id="GUID-A92D63C6-1594-5C95-AAC2-42D2FDE5160F" xml:space="preserve">Fault Category: Exception  Fault Reason: 10000000
       
    74 ExcId 00000001 CodeAddr f816c908 DataAddr 80000001 Extra c0007003
       
    75 Exc 1 Cpsr=60000010 FAR=80000001 FSR=c0007003
       
    76  R0=00000000  R1=00000000  R2=30000000  R3=80000001
       
    77  R4=00000001  R5=00403d88  R6=00002000  R7=f816c768
       
    78  R8=00000012  R9=00000040 R10=00000000 R11=00403fa4
       
    79 R12=00403d5c R13=00403d70 R14=f80906f8 R15=f816c908
       
    80 R13Svc=6571e000 R14Svc=f80074bc SpsrSvc=80000010
       
    81 </codeblock> <p>In this example: </p> <ul>
       
    82 <li id="GUID-7C35AE63-13E9-5D8D-A77F-CD1A0B9A5EF4"><p>the kernel stack is
       
    83 the value of <codeph>R13Svc</codeph>, i.e. <codeph>0x6571e00</codeph>. </p> </li>
       
    84 <li id="GUID-D70628B9-A750-5557-BACF-471D2D75A2E4"><p>the user stack is the
       
    85 value of <codeph>R13</codeph>, i.e. <codeph>0x00403d70</codeph>. </p> </li>
       
    86 </ul> <p id="GUID-FB9D2307-01D9-562A-A46F-AAD91D61C32E"><b>Kernel &amp; user stacks
       
    87 of the current thread after a panic</b> </p> <p>Use the <xref href="GUID-08E14B34-5144-5AA8-AA55-7AF03671676C.dita#GUID-08E14B34-5144-5AA8-AA55-7AF03671676C/GUID-0CDF0190-A445-526B-AC1F-D9D58095B18B">r</xref> command. </p> <codeblock id="GUID-705AF9EC-4513-5C3C-BD28-A91992D73296" xml:space="preserve">MODE_USR:
       
    88  R0=6571de54  R1=0000002a  R2=00000002  R3=ffffffff
       
    89  R4=0000002a  R5=f8170414  R6=6571df14  R7=6403cc50
       
    90  R8=00000001  R9=6403c44c R10=640002f8 R11=6571de70
       
    91 R12=00000020 R13=00404e00 R14=f80818c0 R15=f800bfa8
       
    92 CPSR=60000013
       
    93 MODE_FIQ:
       
    94  R8=00000000  R9=ffffffff R10=ffffffff R11=00000000
       
    95 R12=00000000 R13=64000d0c R14=c080079c SPSR=e00000dc
       
    96 MODE_IRQ:
       
    97 R13=6400110c R14=00000013 SPSR=20000013
       
    98 MODE_SVC:
       
    99 R13=6571de54 R14=f80328bc SPSR=60000010
       
   100 MODE_ABT:
       
   101 R13=6400090c R14=ccbfd0e0 SPSR=b00000d9
       
   102 MODE_UND:
       
   103 R13=6400090c R14=b5a39950 SPSR=f000009d
       
   104 </codeblock> <p>In this example: </p> <ul>
       
   105 <li id="GUID-C23A3F68-FAEB-596A-AF51-810E7429D17B"><p>the kernel stack is
       
   106 the value of <codeph>R13</codeph> under <codeph>MODE_SVC:</codeph>, i.e. <codeph>0x6571de54</codeph>. </p> </li>
       
   107 <li id="GUID-98FD71CA-BD17-5CB3-B0A8-0FBECFBF3ECF"><p>the user stack is the
       
   108 value of <codeph>R13</codeph> under <codeph>MODE_USR:</codeph>, i.e. <codeph>0x00404e00</codeph>. </p> </li>
       
   109 </ul> <p id="GUID-C265F9C5-3280-5A4F-B023-56E33D52DDE0"><b>Interrupt stacks</b> </p> <p>Use
       
   110 the <xref href="GUID-08E14B34-5144-5AA8-AA55-7AF03671676C.dita#GUID-08E14B34-5144-5AA8-AA55-7AF03671676C/GUID-0CDF0190-A445-526B-AC1F-D9D58095B18B">r</xref> command. </p> <codeblock id="GUID-28065EA2-194E-5D8D-8C1B-D85299B91431" xml:space="preserve">MODE_USR:
       
   111  R0=6571de54  R1=0000002a  R2=00000002  R3=ffffffff
       
   112  R4=0000002a  R5=f8170414  R6=6571df14  R7=6403cc50
       
   113  R8=00000001  R9=6403c44c R10=640002f8 R11=6571de70
       
   114 R12=00000020 R13=00404e00 R14=f80818c0 R15=f800bfa8
       
   115 CPSR=60000013
       
   116 MODE_FIQ:
       
   117  R8=00000000  R9=ffffffff R10=ffffffff R11=00000000
       
   118 R12=00000000 R13=64000d0c R14=c080079c SPSR=e00000dc
       
   119 MODE_IRQ:
       
   120 R13=6400110c R14=00000013 SPSR=20000013
       
   121 MODE_SVC:
       
   122 R13=6571de54 R14=f80328bc SPSR=60000010
       
   123 MODE_ABT:
       
   124 R13=6400090c R14=ccbfd0e0 SPSR=b00000d9
       
   125 MODE_UND:
       
   126 R13=6400090c R14=b5a39950 SPSR=f000009d
       
   127 </codeblock> <p>In this example: </p> <ul>
       
   128 <li id="GUID-6A48007B-973A-50F1-BCF5-31A72EC68D57"><p>the IRQ stack is the
       
   129 value of <codeph>R13</codeph> under <codeph>MODE_IRQ:</codeph>, i.e. <codeph>0x6400110c</codeph>. </p> </li>
       
   130 <li id="GUID-65CD3376-7D50-548F-A473-04B049034D0D"><p>the FRQ stack is the
       
   131 value of <codeph>R13</codeph> under <codeph>MODE_FIQ:</codeph>, i.e. <codeph>0x64000d0c</codeph>. </p> </li>
       
   132 </ul> <p id="GUID-9637574E-A9A0-509D-B9B1-C672E2B13431"><b>Kernel &amp; user stacks
       
   133 of a non-current thread</b> </p> <p>Use the output of the <xref href="GUID-08E14B34-5144-5AA8-AA55-7AF03671676C.dita#GUID-08E14B34-5144-5AA8-AA55-7AF03671676C/GUID-D0175D78-6F84-5F4F-BA90-2C591B473C69">i</xref>, <xref href="GUID-08E14B34-5144-5AA8-AA55-7AF03671676C.dita#GUID-08E14B34-5144-5AA8-AA55-7AF03671676C/GUID-1DED2B2F-E780-50A0-8325-5DA22BC7D3E0">q</xref> and <xref href="GUID-08E14B34-5144-5AA8-AA55-7AF03671676C.dita#GUID-08E14B34-5144-5AA8-AA55-7AF03671676C/GUID-FB2E24A6-9744-5169-BA90-DDF84DF1D3E5">c0</xref> commands. </p> <codeblock id="GUID-F45908AC-ADF8-5B92-AA8C-4C33D77D24B8" xml:space="preserve">THREAD at 6403c194 VPTR=f8046c18 AccessCount=5 Owner=6403bb4c
       
   134 Full name t_dmasim::Main
       
   135 Thread MState READY
       
   136 Default priority 12 WaitLink Priority 12
       
   137 ExitInfo 3,0,
       
   138 Flags 00000002, Handles 6403b418
       
   139 Supervisor stack base 6571d000 size 1000
       
   140 User stack base 00403000 size 2000
       
   141 Id=25, Alctr=00700000, Created alctr=00700000, Frame=00000000
       
   142 Trap handler=00000000, ActiveScheduler=007000c8, Exception handler=00000000
       
   143 TempObj=00000000 TempAlloc=00000000
       
   144 NThread @ 6403c44c Pri 12 NState READY
       
   145 Next=6403c44c Prev=6403c44c Att=03 iUserContextType=02
       
   146 HeldFM=00000000 WaitFM=00000000 AddrSp=6403bb4c
       
   147 Time=0 Timeslice=20 ReqCount=0
       
   148 SuspendCount=0 CsCount=1 CsFunction=00000000
       
   149 SavedSP=6571df98
       
   150 DACR f800bd2c
       
   151 R13_USR 0d404c38 R14_USR 00000001 SPSR_SVC 00000000
       
   152  R4 f8022d84  R5 6571dfd4  R6 6571dfbc  R7 f8022db8
       
   153  R8 f800bddc  R9 f800a454 R10 00000000 R11 f801daac
       
   154  PC 60000010
       
   155 </codeblock> <p>In this example: </p> <ul>
       
   156 <li id="GUID-A4217DD4-A46C-5EAE-85D3-2EEAD763B726"><p>the kernel stack is
       
   157 the value of <codeph>SavedSP</codeph>, i.e. <codeph>0x6571df98</codeph>. </p> </li>
       
   158 <li id="GUID-8220888D-7411-5AC5-AD20-89E892301188"><p>the user stack is the
       
   159 value of <codeph>R13_USR</codeph>, i.e. <codeph>0x0d404c38</codeph>. </p> </li>
       
   160 </ul> </section>
       
   161 <section id="GUID-877742A5-F07F-54B6-B871-255FAAE790EB"><title>Tracing through
       
   162 the stack heuristically</title> <p>One way of tracing through the call stack
       
   163 is to assume that every word on the stack which looks like a ROM code address
       
   164 is a saved return address. We say that this heuristic because: </p> <ul>
       
   165 <li id="GUID-B5BF6BD6-0163-55F9-A34D-EB78982848B0"><p>some data words may
       
   166 look like code addresses in ROM. </p> </li>
       
   167 <li id="GUID-0A978212-73B6-5C89-B805-84327B9CF733"><p>there may be saved return
       
   168 addresses left over from previous function calls. For example, suppose that <codeph>F()</codeph> calls <codeph>A()</codeph> and
       
   169 then <codeph>B()</codeph> in sequence. <codeph>A()</codeph> itself calls <codeph>X()</codeph>,
       
   170 which calls <codeph>Y()</codeph>. If a crash occurs in <codeph>B()</codeph>,
       
   171 the saved return addresses from the calls to <codeph>X()</codeph> and <codeph>Y()</codeph> are
       
   172 still present on the stack and may be mistaken for function calls occuring
       
   173 while <codeph>B()</codeph> is active. </p> <p>This scenario happens frequently
       
   174 when <codeph>B()</codeph> allocates a buffer (e.g. <xref href="GUID-0B9C8884-6BFF-35E2-AA6F-E4057B85AFCF.dita"><apiname>TBuf</apiname></xref>)
       
   175 on the stack which overlaps old stack frames. </p> <fig id="GUID-FED8CC0F-F1A0-59C9-B082-2D3B499D00D5">
       
   176 <image href="GUID-A328F9E3-7D91-594A-A589-E8CE5FA9227A_d0e69077_href.png" placement="inline"/>
       
   177 </fig> </li>
       
   178 </ul> <p>If you want to trace applications loaded into RAM, then stack tracing
       
   179 is more difficult because RAM-loaded DLLs are given addresses assigned at
       
   180 load time. </p> <p>On ARM, the stack pointer starts at the higher address
       
   181 end and moves 'down' towards the lower address end. This means that values
       
   182 at the top of the memory dump are more recent. You need to look back through
       
   183 this for code addresses. For ROM code this will be words with most significant
       
   184 byte in the range <codeph>0xF8</codeph> to <codeph>0xFF</codeph>, remembering
       
   185 that they are little-endian. This can either be done manually, or automatically
       
   186 using the <filepath>printsym.pl</filepath> perl script, which can be found
       
   187 in <codeph>...\epoc32\tools</codeph>. </p> <p>Let's follow this in an example
       
   188 session: </p> <ul>
       
   189 <li id="GUID-D761405E-86BD-55ED-ACC6-C6D2125FDCE7"><p>Decide whether the crash
       
   190 has been caused by a panic or an exception using the <xref href="GUID-08E14B34-5144-5AA8-AA55-7AF03671676C.dita#GUID-08E14B34-5144-5AA8-AA55-7AF03671676C/GUID-D5F2E0AF-EF03-5150-813B-DF989F12C47B">f</xref> command: </p> <codeblock id="GUID-480D9B52-C556-5733-91E2-87D7F12651FC" xml:space="preserve">.f
       
   191 Fault Category: EXAMPLE  Fault Reason: 0000002a
       
   192 ExcId 00000000 CodeAddr 00000000 DataAddr 00000000 Extra 00000000
       
   193 </codeblock> </li>
       
   194 <li id="GUID-73690262-2895-51ED-9532-E76638B0EC1E"><p>This shows that the
       
   195 crash was caused by a panic, so now use the <xref href="GUID-08E14B34-5144-5AA8-AA55-7AF03671676C.dita#GUID-08E14B34-5144-5AA8-AA55-7AF03671676C/GUID-0CDF0190-A445-526B-AC1F-D9D58095B18B">r</xref> command to find the CPU mode and the stack pointer: </p> <codeblock id="GUID-1FB9E3E1-54FF-5109-804D-2D6109626A66" xml:space="preserve">.r
       
   196 MODE_USR:
       
   197  R0=6571de54  R1=0000002a  R2=00000002  R3=ffffffff
       
   198  R4=0000002a  R5=f8170414  R6=6571df14  R7=6403cba8
       
   199  R8=00000001  R9=6403c41c R10=640002f8 R11=6571de70
       
   200 R12=00000020 R13=00404e00 R14=f80818c0 R15=f800bfa8
       
   201 CPSR=60000013
       
   202 MODE_FIQ:
       
   203  R8=00000000  R9=ffffffff R10=ffffffff R11=00000000
       
   204 R12=00000000 R13=64000d0c R14=c080079c SPSR=e00000dc
       
   205 MODE_IRQ:
       
   206 R13=6400110c R14=00000013 SPSR=20000013
       
   207 MODE_SVC:
       
   208 R13=6571de54 R14=f80328bc SPSR=60000010
       
   209 MODE_ABT:
       
   210 R13=6400090c R14=ffff0010 SPSR=400000d7
       
   211 MODE_UND:
       
   212 R13=6400090c R14=95221110 SPSR=f000009d
       
   213 </codeblock> <p>The panic happened in supervisor mode, because <codeph>CPSR
       
   214 &amp;                 0x1F == 0x13</codeph>, so <codeph>R13Svc</codeph>, i.e.
       
   215 the value of <codeph>R13</codeph> shown under <codeph>MODE_SVC:</codeph> in
       
   216 the above display, is the stack pointer to look at; this has the value <codeph>0x6571DE54</codeph>. </p> </li>
       
   217 <li id="GUID-CE74A8F7-97EF-5ACD-BA16-A35CDA293B3D"><p>Using the <xref href="GUID-08E14B34-5144-5AA8-AA55-7AF03671676C.dita#GUID-08E14B34-5144-5AA8-AA55-7AF03671676C/GUID-2A0D5950-F1A5-5EE1-87A3-840B1EAD6AAD">m</xref> command to look at memory starting at location <codeph>0x6571DE54</codeph> gives: </p> <codeblock id="GUID-BF6D6BD9-ADDE-587F-85B6-39140620B9AC" xml:space="preserve">.m6571de54+200
       
   218 6571de54: 07 00 00 10 14 04 17 f8 00 00 00 00 d4 4e 40 00 .............N@.
       
   219 6571de64: e8 de 71 65 74 de 71 65 74 fb 16 f8 88 28 03 f8 ..qet.qet....(..
       
   220 6571de74: 0c d4 03 f8 64 35 03 f8 00 00 00 00 00 00 00 00 ....d5..........
       
   221 6571de84: d0 00 00 00 14 df 71 65 a8 cb 03 64 a8 cb 03 64 ......qe...d...d
       
   222 6571de94: d0 00 00 00 14 df 71 65 1c df 71 65 ec 4e 40 00 ......qe..qe.N@.
       
   223 6571dea4: 1c c4 03 64 b4 2a 03 f8 00 00 00 00 14 df 71 65 ...d.*........qe
       
   224 6571deb4: d0 de 71 65 c4 de 71 65 b0 ab 03 f8 00 00 00 00 ..qe..qe........
       
   225 6571dec4: e0 ba 03 64 14 df 71 65 1c df 71 65 01 00 00 00 ...d..qe..qe....
       
   226 6571ded4: 1c c4 03 64 f8 02 00 64 10 df 71 65 ec de 71 65 ...d...d..qe..qe
       
   227 6571dee4: 84 da 01 f8 5c fb 16 f8 00 4e 40 00 00 00 00 00 ....\....N@.....
       
   228 6571def4: 00 4e 40 00 00 00 00 00 d3 00 00 00 ec 4e 40 00 .N@..........N@.
       
   229 6571df04: d4 df 71 65 14 df 71 65 e0 db 01 f8 c0 d9 01 f8 ..qe..qe........
       
   230 6571df14: a8 cb 03 64 e0 ba 03 64 01 00 01 00 00 00 00 00 ...d...d........
       
   231 6571df24: 00 00 00 00 d4 4e 40 00 00 00 00 30 40 00 00 00 .....N@....0@...
       
   232 6571df34: 13 00 00 60 98 df 71 65 48 df 71 65 f4 81 00 f8 ...`..qeH.qe....
       
   233 6571df44: 8c 7a 00 f8 68 df 71 65 58 df 71 65 6c df 71 65 .z..h.qeX.qel.qe
       
   234 6571df54: 60 df 71 65 0c 2b 00 f8 bc 2a 00 f8 84 df 71 65 `.qe.+...*....qe
       
   235 6571df64: 70 df 71 65 e4 7d 04 f8 08 2b 00 f8 0d 00 00 00 p.qe.}...+......
       
   236 6571df74: 0a 00 00 30 40 00 00 00 54 65 73 74 44 6d 61 53 ...0@...TestDmaS
       
   237 6571df84: 69 6d 04 f8 a9 4b 40 00 b8 df 71 65 9c df 71 65 im...K@...qe..qe
       
   238 6571df94: 2c be 00 f8 2c bd 00 f8 38 4c 40 0d 01 00 00 00 ,...,...8L@.....
       
   239 6571dfa4: 00 00 00 00 84 2d 02 f8 d4 df 71 65 bc df 71 65 .....-....qe..qe
       
   240 6571dfb4: b8 2d 02 f8 dc bd 00 f8 54 a4 00 f8 00 00 00 00 .-......T.......
       
   241 6571dfc4: ac da 01 f8 10 00 00 60 d8 df 71 65 70 74 00 f8 .......`..qept..
       
   242 6571dfd4: b8 da 01 f8 d4 4e 40 00 20 f7 16 f8 d0 4e 40 00 .....N@. ....N@.
       
   243 6571dfe4: 00 00 00 00 00 00 00 00 ec 4e 40 00 40 00 00 00 .........N@.@...
       
   244 </codeblock> <p>We can look for potential ROM addresses by scanning the log
       
   245 and look up the corresponding function name in the symbol file generated <xref href="GUID-DA62FD4F-2E74-5B2F-B703-4A40DF5F01CA.dita">using the MAKSYM tool</xref> .
       
   246 The first one is <codeph>0xF8170414</codeph> at offset <codeph>4</codeph> in
       
   247 the memory dump. </p> </li>
       
   248 <li id="GUID-3197B03A-FD94-5D78-B699-22BDCE71DD1D"><p>Alternatively, we can
       
   249 use the <filepath>printsym.pl</filepath> perl script, passing it the dump
       
   250 output. The following is part of the output: </p> <codeblock id="GUID-B4289E03-6E98-591D-9E26-CEEDC3CD9437" xml:space="preserve">R:\base\e32\rombuild&gt;perl -S printsym.pl ASSABETARM4D.symbol
       
   251 ROM Symbols from ASSABETARM4D.symbol
       
   252 Please enter data to be decoded
       
   253 6571de54: 07 00 00 10 14 04 17 f8 00 00 00 00 d4 4e 40 00 .............N@.
       
   254 = 10000007 ....    
       
   255 = f8170414 ....  etext=. + 0x0
       
   256 = 00000000 ....
       
   257 = 00404ed4 .N@.
       
   258 6571de64: e8 de 71 65 74 de 71 65 74 fb 16 f8 88 28 03 f8 ..qet.qet....(..
       
   259 = 6571dee8 ..qe
       
   260 = 6571de74 t.qe
       
   261 = f816fb74 t...  DDmaTestChannel::DoCreate(int, TDesC8 const *, TVersion const &amp;
       
   262 ) + 0x24
       
   263 = f8032888 .(..  Kern::Fault(char const *, int) + 0xc
       
   264 6571de74: 0c d4 03 f8 64 35 03 f8 00 00 00 00 00 00 00 00 ....d5..........
       
   265 = f803d40c ....  RHeap::Alloc(int) + 0xf4
       
   266 = f8033564 d5..  Kern::MutexSignal(DMutex &amp;) + 0xc
       
   267 = 00000000 ....
       
   268 = 00000000 ....
       
   269 
       
   270 [............ truncated ...............]
       
   271 
       
   272 = f801da84 ....  DLogicalDevice::ChannelCreate(DLogicalChannelBase *&amp;, TChannelC
       
   273 reateInfo &amp;) + 0xd0
       
   274 = f816fb5c \...  DDmaTestChannel::DoCreate(int, TDesC8 const *, TVersion const &amp;
       
   275 ) + 0xc
       
   276 = 00404e00 .N@.
       
   277 = 00000000 ....
       
   278 6571def4: 00 4e 40 00 00 00 00 00 d3 00 00 00 ec 4e 40 00 .N@..........N@.
       
   279 = 00404e00 .N@.
       
   280 = 00000000 ....
       
   281 = 000000d3 ....
       
   282 = 00404eec .N@.
       
   283 6571df04: d4 df 71 65 14 df 71 65 e0 db 01 f8 c0 d9 01 f8 ..qe..qe........
       
   284 = 6571dfd4 ..qe
       
   285 = 6571df14 ..qe
       
   286 = f801dbe0 ....  ExecHandler::ChannelCreate(TDesC8 const &amp;, TChannelCreateInfo &amp;
       
   287 , int) + 0x134
       
   288 = f801d9c0 ....  DLogicalDevice::ChannelCreate(DLogicalChannelBase *&amp;, TChannelC
       
   289 reateInfo &amp;) + 0xc
       
   290 
       
   291 [.......................... truncated .........................]
       
   292 
       
   293 = f8022db8 .-..  ExecHandler::DebugPrint(void *, int) + 0x34
       
   294 = f800bddc ....  A::UserDebugPrint(unsigned char const *, int, int) + 0xc
       
   295 = f800a454 T...  EpocSlowExecTable + 0xc
       
   296 = 00000000 ....
       
   297 6571dfc4: ac da 01 f8 10 00 00 60 d8 df 71 65 70 74 00 f8 .......`..qept..
       
   298 = f801daac ....  ExecHandler::ChannelCreate(TDesC8 const &amp;, TChannelCreateInfo &amp;
       
   299 , int) + 0x0
       
   300 = 60000010 ...`
       
   301 = 6571dfd8 ..qe
       
   302 = f8007470 pt..  __ArmVectorSwi + 0xd8
       
   303 6571dfd4: b8 da 01 f8 d4 4e 40 00 20 f7 16 f8 d0 4e 40 00 .....N@. ....N@.
       
   304 = f801dab8 ....  ExecHandler::ChannelCreate(TDesC8 const &amp;, TChannelCreateInfo &amp;
       
   305 , int) + 0xc
       
   306 = 00404ed4 .N@.
       
   307 = f816f720  ...  etext=. + 0x560
       
   308 = 00404ed0 .N@.
       
   309 6571dfe4: 00 00 00 00 00 00 00 00 ec 4e 40 00 40 00 00 00 .........N@.@...
       
   310 = 00000000 ....
       
   311 = 00000000 ....
       
   312 = 00404eec .N@.
       
   313 = 00000040 @...
       
   314 ^C
       
   315 R:\base\e32\rombuild&gt;
       
   316 </codeblock> <p>There are several false positives in this output (and even
       
   317 more in the truncated parts). So some study of the source code is needed to
       
   318 discard the noise and find the actual call stack. Here it is (innermost frame
       
   319 first): </p> <ul>
       
   320 <li id="GUID-C83CA525-1731-56BC-8C98-4AEEB5809780"><p> <codeph>Kern::Fault</codeph>  </p> </li>
       
   321 <li id="GUID-40B7B48A-F6A0-5CD6-9C0C-2E432FF760BA"><p> <codeph>DDmaTestChannel::DoCreate</codeph>  </p> </li>
       
   322 <li id="GUID-E9327B91-F69C-5BC1-B964-FE1B90CA314C"><p> <codeph>ExecHandler::ChannelCreate</codeph>  </p> </li>
       
   323 <li id="GUID-0391ADD8-EF56-51F9-987F-B9111903EAC7"><p> <codeph> __ArmVectorSwi</codeph>  </p> </li>
       
   324 </ul> <p>Note that for the sake of the example, a call to <xref href="GUID-C6946ECB-775F-3EC2-A56F-78F25B9FBE3D.dita#GUID-C6946ECB-775F-3EC2-A56F-78F25B9FBE3D/GUID-45337A03-5893-3D0D-948C-23BDCF8AECBD"><apiname>Kern::Fault()</apiname></xref> was
       
   325 deliberately inserted into <xref href="GUID-63F99C5E-55C4-305B-BA86-CF73B0CF1520.dita#GUID-63F99C5E-55C4-305B-BA86-CF73B0CF1520/GUID-F0A1E76C-A0E1-39C9-845C-BE19FE2EB415"><apiname>DDmaTestChannel::DoCreate()</apiname></xref>. </p> <p>All
       
   326 other function names are false positives and should be ignored. </p> </li>
       
   327 </ul> </section>
       
   328 <section id="GUID-7F160B0F-9921-578B-B9B0-7CC4CA3B24C3"><title>Walking through
       
   329 the call stack</title> <p>The heuristic method is quick but produces lots
       
   330 of false positives. Another option is to manually reconstitute the call stack
       
   331 from the memory dump. This is relatively easy for debug builds because GCC
       
   332 uses R11 as a frame pointer (FP) and generates the same prologue/epilogue
       
   333 for every function. </p> <p>For release builds, there is no generic solution.
       
   334 It is necessary to check the generated assembler code as there is no standard
       
   335 prologue/epilogue and R11 is not used as frame pointer. </p> <p>A typical
       
   336 prologue for a debug ARM function looks like this: </p> <codeblock id="GUID-9C1F71E0-5F2A-50FF-ABD2-035EB9B5B4D9" xml:space="preserve">mov        ip, sp
       
   337 stmfd    sp!, {fp, ip, lr, pc}
       
   338 sub        fp, ip, #4        /* FP now points to base of stack frame */
       
   339 sub        sp, sp, #16    /* space for local variables */
       
   340 </codeblock> <p>noting that: <codeph>SP = R13</codeph>, <codeph>FP = R11</codeph>, <codeph>IP
       
   341 =           R12</codeph>, <codeph>LR = R14</codeph>, and <codeph>PC = R15</codeph>. </p> <p>This
       
   342 code creates the following stack frame: </p> <fig id="GUID-5CE044A2-CDD0-5A09-B824-BAF46324AB27">
       
   343 <image href="GUID-F12437C5-BD96-5B43-AD76-614CFAB104D2_d0e69275_href.png" placement="inline"/>
       
   344 </fig> <p>Looking at the example session listed in when <xref href="GUID-1E43E258-A926-5D24-B0A5-8756491C687F.dita#GUID-1E43E258-A926-5D24-B0A5-8756491C687F/GUID-877742A5-F07F-54B6-B871-255FAAE790EB">tracing through the stack heuristically</xref>. in which the crash is due
       
   345 to a panic, the FP value is the R11 value; this is <codeph>0x6571de70</codeph>.
       
   346 This gives us the innermost stack frame: </p> <codeblock id="GUID-DE5FFB23-A85D-562F-858B-CFF407448E36" xml:space="preserve">6571de64:    e8 de 71 65 &lt;------------- pointer to previous stack frame 
       
   347             74 de 71 65 
       
   348             74 fb 16 f8 &lt;------------- Saved return address 
       
   349             88 28 03 f8 &lt;------------- FP points to this word
       
   350 </codeblock> <p>Looking up the saved return address, <codeph>0xf816fb74</codeph>,
       
   351 in the symbol file shows that the current function was called from <codeph>DDmaChannel::DoCreate()</codeph>. </p> <codeblock id="GUID-576615AE-2253-595C-97F5-1DC05F79B750" xml:space="preserve">f816fb50    0198    DDmaTestChannel::DoCreate(int, TDesC8 const *, TVersion const &amp;)
       
   352 f816fce8    007c    DDmaTestChannel::~DDmaTestChannel(void)
       
   353 f816fd64    0294    DDmaTestChannel::Request(int, void *, void *)
       
   354 </codeblock> <p>Using the pointer to the previous stack frame saved into the
       
   355 current frame, we can decode the next frame: </p> <codeblock id="GUID-570DB2F6-A76F-5858-816F-7A0E8562B35A" xml:space="preserve">6571ded4:    1c c4 03 64 
       
   356             f8 02 00 64 
       
   357             10 df 71 65 &lt;------------- pointer to previous stack frame 
       
   358             ec de 71 65 
       
   359 
       
   360 6571dee4:    84 da 01 f8 &lt;------------- saved return address 
       
   361             5c fb 16 f8 &lt;------------- start of second stack frame 
       
   362             00 4e 40 00 
       
   363             00 00 00 00 
       
   364 </codeblock> <p>Looking up the saved return address, <codeph>0xf801da84</codeph>,
       
   365 in the symbol file shows that <codeph>DDmaTestChannel::DoCreate()</codeph> was
       
   366 called from <codeph>DLogicalDevice::ChannelCreate()</codeph>. </p> <codeblock id="GUID-B36A9D49-5414-5CC3-8CBF-A2A0EE332B3C" xml:space="preserve">f801d9b4    00f8    DLogicalDevice::ChannelCreate(DLogicalChannelBase *&amp;, TChannelCreateInfo &amp;)
       
   367 f801daac    01b8    ExecHandler::ChannelCreate(TDesC8 const &amp;, TChannelCreateInfo &amp;, int)
       
   368 f801dc64    00e4    ExecHandler::ChannelRequest(DLogicalChannelBase *, int, void *, void *)
       
   369 </codeblock> <p>And here is the third stack frame: </p> <codeblock id="GUID-B07DEA17-BA2F-5FEA-8781-E44682BE2D1D" xml:space="preserve">6571df04:    d4 df 71 65 &lt;------------- pointer to previous stack frame 
       
   370             14 df 71 65 
       
   371             e0 db 01 f8 &lt;------------- saved return address 
       
   372             c0 d9 01 f8 &lt;------------- start of third stack frame 
       
   373 </codeblock> <p>So <codeph>DLogicalDevice::ChannelCreate()</codeph> was called
       
   374 from <codeph>ExecHandler::ChannelCreate()</codeph>. </p> <p>Note that this
       
   375 mechanical way of walking the stack is valid only for debug functions. For
       
   376 release functions, it is necessary to study the code generated by the compiler. </p> <p>For
       
   377 completness, this is a typical prologue for a debug THUMB function: </p> <codeblock id="GUID-2DC6601E-6304-5638-A1F6-F44F1AB26288" xml:space="preserve">push    { r7, lr }
       
   378 sub        sp, #28
       
   379 add        r7, sp, #12 /* R7 is THUMB frame pointer */
       
   380 </codeblock> <p>and this creates the following stack frame: </p> <fig id="GUID-85FAEE94-6D61-5D6B-84CB-6A9491927077">
       
   381 <image href="GUID-5CF162CA-4395-58AC-A318-2BF178276A57_d0e69352_href.png" placement="inline"/>
       
   382 </fig> <p>A call stack can mix ARM and THUMB frames. Odd return addresses
       
   383 are used for THUMB code and even ones for ARM code. </p> </section>
       
   384 </conbody></concept>