--- a/Symbian3/PDK/Source/GUID-1E43E258-A926-5D24-B0A5-8756491C687F.dita Tue Mar 30 11:42:04 2010 +0100
+++ b/Symbian3/PDK/Source/GUID-1E43E258-A926-5D24-B0A5-8756491C687F.dita Tue Mar 30 11:56:28 2010 +0100
@@ -1,384 +1,384 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies) All rights reserved. -->
-<!-- This component and the accompanying materials are made available under the terms of the License
-"Eclipse Public License v1.0" which accompanies this distribution,
-and is available at the URL "http://www.eclipse.org/legal/epl-v10.html". -->
-<!-- Initial Contributors:
- Nokia Corporation - initial contribution.
-Contributors:
--->
-<!DOCTYPE concept
- PUBLIC "-//OASIS//DTD DITA Concept//EN" "concept.dtd">
-<concept id="GUID-1E43E258-A926-5D24-B0A5-8756491C687F" xml:lang="en"><title>Call
-Stack Information Commands</title><prolog><metadata><keywords/></metadata></prolog><conbody>
-<p>Describes how to use the debug monitor commands to get information about
-the call stack. </p>
-<ul>
-<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>
-<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>
-<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>
-<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>
-</ul>
-<section id="GUID-D8F141D7-3BE2-5ADB-8A55-CFFE85E89804"><title>General points</title> <p>Tracing
-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
-memory</xref>. </p> <p>Every time a function is called, the return address
-is automatically saved into register <codeph>R14</codeph> (Link Register).
-In addition to this the return address is generally pushed onto the call stack;
-it is always pushed in debug builds but the push operation is sometimes optimized
-out in release builds. This allows you to trace back through the value of <codeph>R14</codeph> and
-these saved addresses to see the sequence of function calls. Unfortunately
-this is quite tedious to do because the stack is also used for automatic variables
-and other data. You need to work out which values on the stack refer to return
-addresses. </p> <p>When you are debugging only ROM-based code, it is relatively
-easy to identify the pushed return addresses because all code addresses will
-be in the ROM range: <codeph>0xF800000</codeph> to <codeph>0xFFEFFFFF</codeph> for
-the <xref href="GUID-D520CBC3-FCAC-5A53-AE1A-E5254ABBC6A2.dita#GUID-D520CBC3-FCAC-5A53-AE1A-E5254ABBC6A2/GUID-A5845A0C-2C88-52BB-B7DE-210C2DE481B9">moving
-model</xref>. However, there is also data in the ROM, which means that an
-address on the stack which is in the ROM range could point to data instead
-of code. If you want to trace applications loaded into RAM, i.e. anything
-not run from drive Z:, then stack tracing is more difficult because the code
-can move about and RAM-loaded code is given an address assigned at load time. </p> <p>Note
-that <xref href="GUID-DA62FD4F-2E74-5B2F-B703-4A40DF5F01CA.dita">using the MAKSYM
-tool</xref> is essential for tracing back through the stack. </p> </section>
-<section id="GUID-1EC3F2E7-6BFF-56BE-B042-DA6940CC909E"><title>Finding the
-stack</title> <p>To trace back through a thread’s kernel or user stack, you
-first need to find the stack pointer value. On the ARM, <codeph>R13</codeph> always
-points to the stack, but there are different <codeph>R13</codeph> registers
-for each processor mode: </p> <ul>
-<li id="GUID-756C8CDD-AF47-561B-BAA7-EA8FBDEE5245"><p>In thread context: </p> <ul>
-<li id="GUID-81BC92C2-6022-5EBF-BF60-C4D69131C720"><p> <codeph>R13usr</codeph> points
-to the thread’s user stack, </p> </li>
-<li id="GUID-CA6CF8C9-0BA3-5BD4-AECE-80AB3DFCFAD1"><p> <codeph>R13svc</codeph> points
-to the thread’s kernel stack. </p> </li>
-</ul> </li>
-<li id="GUID-C4A1AD73-64E8-56F7-A7DF-129B2A35FC9D"><p>When handling interrupts,
-dedicated stacks are used: </p> <ul>
-<li id="GUID-7D27A691-1479-578B-9B05-7946C8D84010"><p> <codeph>R13Fiq</codeph> points
-to the stack used when processing fast interrupts (FIQ). </p> </li>
-<li id="GUID-CE76BE0F-A6BA-55A6-8CDD-B1E40D97A42D"><p> <codeph>R13Irq</codeph> points
-to the stack used when processing general purpose interrupts (IRQ). </p> </li>
-</ul> </li>
-</ul> <p>To find out which stack to inspect, you need to know what mode the
-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
-mode</xref> is identified by the five least-significant bits of the CPSR register.
-To get the value of the CPSR register: </p> <ul>
-<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>
-<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>
-</ul> <p>The following examples show how to find the stack(s): </p> <ul>
-<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 & user stacks of the current thread after a hardware exception</xref> </p> </li>
-<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 & user stacks of the current thread after a panic</xref> </p> </li>
-<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>
-<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 & user stacks of a non-current thread</xref> </p> </li>
-</ul> <p id="GUID-4E735CB7-3171-58FB-9D93-EE86702952F6"><b>Kernel & user stacks
-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
-ExcId 00000001 CodeAddr f816c908 DataAddr 80000001 Extra c0007003
-Exc 1 Cpsr=60000010 FAR=80000001 FSR=c0007003
- R0=00000000 R1=00000000 R2=30000000 R3=80000001
- R4=00000001 R5=00403d88 R6=00002000 R7=f816c768
- R8=00000012 R9=00000040 R10=00000000 R11=00403fa4
-R12=00403d5c R13=00403d70 R14=f80906f8 R15=f816c908
-R13Svc=6571e000 R14Svc=f80074bc SpsrSvc=80000010
-</codeblock> <p>In this example: </p> <ul>
-<li id="GUID-7C35AE63-13E9-5D8D-A77F-CD1A0B9A5EF4"><p>the kernel stack is
-the value of <codeph>R13Svc</codeph>, i.e. <codeph>0x6571e00</codeph>. </p> </li>
-<li id="GUID-D70628B9-A750-5557-BACF-471D2D75A2E4"><p>the user stack is the
-value of <codeph>R13</codeph>, i.e. <codeph>0x00403d70</codeph>. </p> </li>
-</ul> <p id="GUID-FB9D2307-01D9-562A-A46F-AAD91D61C32E"><b>Kernel & user stacks
-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:
- R0=6571de54 R1=0000002a R2=00000002 R3=ffffffff
- R4=0000002a R5=f8170414 R6=6571df14 R7=6403cc50
- R8=00000001 R9=6403c44c R10=640002f8 R11=6571de70
-R12=00000020 R13=00404e00 R14=f80818c0 R15=f800bfa8
-CPSR=60000013
-MODE_FIQ:
- R8=00000000 R9=ffffffff R10=ffffffff R11=00000000
-R12=00000000 R13=64000d0c R14=c080079c SPSR=e00000dc
-MODE_IRQ:
-R13=6400110c R14=00000013 SPSR=20000013
-MODE_SVC:
-R13=6571de54 R14=f80328bc SPSR=60000010
-MODE_ABT:
-R13=6400090c R14=ccbfd0e0 SPSR=b00000d9
-MODE_UND:
-R13=6400090c R14=b5a39950 SPSR=f000009d
-</codeblock> <p>In this example: </p> <ul>
-<li id="GUID-C23A3F68-FAEB-596A-AF51-810E7429D17B"><p>the kernel stack is
-the value of <codeph>R13</codeph> under <codeph>MODE_SVC:</codeph>, i.e. <codeph>0x6571de54</codeph>. </p> </li>
-<li id="GUID-98FD71CA-BD17-5CB3-B0A8-0FBECFBF3ECF"><p>the user stack is the
-value of <codeph>R13</codeph> under <codeph>MODE_USR:</codeph>, i.e. <codeph>0x00404e00</codeph>. </p> </li>
-</ul> <p id="GUID-C265F9C5-3280-5A4F-B023-56E33D52DDE0"><b>Interrupt stacks</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-28065EA2-194E-5D8D-8C1B-D85299B91431" xml:space="preserve">MODE_USR:
- R0=6571de54 R1=0000002a R2=00000002 R3=ffffffff
- R4=0000002a R5=f8170414 R6=6571df14 R7=6403cc50
- R8=00000001 R9=6403c44c R10=640002f8 R11=6571de70
-R12=00000020 R13=00404e00 R14=f80818c0 R15=f800bfa8
-CPSR=60000013
-MODE_FIQ:
- R8=00000000 R9=ffffffff R10=ffffffff R11=00000000
-R12=00000000 R13=64000d0c R14=c080079c SPSR=e00000dc
-MODE_IRQ:
-R13=6400110c R14=00000013 SPSR=20000013
-MODE_SVC:
-R13=6571de54 R14=f80328bc SPSR=60000010
-MODE_ABT:
-R13=6400090c R14=ccbfd0e0 SPSR=b00000d9
-MODE_UND:
-R13=6400090c R14=b5a39950 SPSR=f000009d
-</codeblock> <p>In this example: </p> <ul>
-<li id="GUID-6A48007B-973A-50F1-BCF5-31A72EC68D57"><p>the IRQ stack is the
-value of <codeph>R13</codeph> under <codeph>MODE_IRQ:</codeph>, i.e. <codeph>0x6400110c</codeph>. </p> </li>
-<li id="GUID-65CD3376-7D50-548F-A473-04B049034D0D"><p>the FRQ stack is the
-value of <codeph>R13</codeph> under <codeph>MODE_FIQ:</codeph>, i.e. <codeph>0x64000d0c</codeph>. </p> </li>
-</ul> <p id="GUID-9637574E-A9A0-509D-B9B1-C672E2B13431"><b>Kernel & user stacks
-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
-Full name t_dmasim::Main
-Thread MState READY
-Default priority 12 WaitLink Priority 12
-ExitInfo 3,0,
-Flags 00000002, Handles 6403b418
-Supervisor stack base 6571d000 size 1000
-User stack base 00403000 size 2000
-Id=25, Alctr=00700000, Created alctr=00700000, Frame=00000000
-Trap handler=00000000, ActiveScheduler=007000c8, Exception handler=00000000
-TempObj=00000000 TempAlloc=00000000
-NThread @ 6403c44c Pri 12 NState READY
-Next=6403c44c Prev=6403c44c Att=03 iUserContextType=02
-HeldFM=00000000 WaitFM=00000000 AddrSp=6403bb4c
-Time=0 Timeslice=20 ReqCount=0
-SuspendCount=0 CsCount=1 CsFunction=00000000
-SavedSP=6571df98
-DACR f800bd2c
-R13_USR 0d404c38 R14_USR 00000001 SPSR_SVC 00000000
- R4 f8022d84 R5 6571dfd4 R6 6571dfbc R7 f8022db8
- R8 f800bddc R9 f800a454 R10 00000000 R11 f801daac
- PC 60000010
-</codeblock> <p>In this example: </p> <ul>
-<li id="GUID-A4217DD4-A46C-5EAE-85D3-2EEAD763B726"><p>the kernel stack is
-the value of <codeph>SavedSP</codeph>, i.e. <codeph>0x6571df98</codeph>. </p> </li>
-<li id="GUID-8220888D-7411-5AC5-AD20-89E892301188"><p>the user stack is the
-value of <codeph>R13_USR</codeph>, i.e. <codeph>0x0d404c38</codeph>. </p> </li>
-</ul> </section>
-<section id="GUID-877742A5-F07F-54B6-B871-255FAAE790EB"><title>Tracing through
-the stack heuristically</title> <p>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 address. We say that this heuristic because: </p> <ul>
-<li id="GUID-B5BF6BD6-0163-55F9-A34D-EB78982848B0"><p>some data words may
-look like code addresses in ROM. </p> </li>
-<li id="GUID-0A978212-73B6-5C89-B805-84327B9CF733"><p>there may be saved return
-addresses left over from previous function calls. For example, suppose that <codeph>F()</codeph> calls <codeph>A()</codeph> and
-then <codeph>B()</codeph> in sequence. <codeph>A()</codeph> itself calls <codeph>X()</codeph>,
-which calls <codeph>Y()</codeph>. If a crash occurs in <codeph>B()</codeph>,
-the saved return addresses from the calls to <codeph>X()</codeph> and <codeph>Y()</codeph> are
-still present on the stack and may be mistaken for function calls occuring
-while <codeph>B()</codeph> is active. </p> <p>This scenario happens frequently
-when <codeph>B()</codeph> allocates a buffer (e.g. <xref href="GUID-0B9C8884-6BFF-35E2-AA6F-E4057B85AFCF.dita"><apiname>TBuf</apiname></xref>)
-on the stack which overlaps old stack frames. </p> <fig id="GUID-FED8CC0F-F1A0-59C9-B082-2D3B499D00D5">
-<image href="GUID-A328F9E3-7D91-594A-A589-E8CE5FA9227A_d0e300312_href.png" placement="inline"/>
-</fig> </li>
-</ul> <p>If you want to trace applications loaded into RAM, then stack tracing
-is more difficult because RAM-loaded DLLs are given addresses assigned at
-load time. </p> <p>On ARM, the stack pointer starts at the higher address
-end and moves 'down' towards the lower address end. This means that values
-at the top of the memory dump are more recent. You need to look back through
-this for code addresses. For ROM code this will be words with most significant
-byte in the range <codeph>0xF8</codeph> to <codeph>0xFF</codeph>, remembering
-that they are little-endian. This can either be done manually, or automatically
-using the <filepath>printsym.pl</filepath> perl script, which can be found
-in <codeph>...\epoc32\tools</codeph>. </p> <p>Let's follow this in an example
-session: </p> <ul>
-<li id="GUID-D761405E-86BD-55ED-ACC6-C6D2125FDCE7"><p>Decide whether the crash
-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
-Fault Category: EXAMPLE Fault Reason: 0000002a
-ExcId 00000000 CodeAddr 00000000 DataAddr 00000000 Extra 00000000
-</codeblock> </li>
-<li id="GUID-73690262-2895-51ED-9532-E76638B0EC1E"><p>This shows that the
-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
-MODE_USR:
- R0=6571de54 R1=0000002a R2=00000002 R3=ffffffff
- R4=0000002a R5=f8170414 R6=6571df14 R7=6403cba8
- R8=00000001 R9=6403c41c R10=640002f8 R11=6571de70
-R12=00000020 R13=00404e00 R14=f80818c0 R15=f800bfa8
-CPSR=60000013
-MODE_FIQ:
- R8=00000000 R9=ffffffff R10=ffffffff R11=00000000
-R12=00000000 R13=64000d0c R14=c080079c SPSR=e00000dc
-MODE_IRQ:
-R13=6400110c R14=00000013 SPSR=20000013
-MODE_SVC:
-R13=6571de54 R14=f80328bc SPSR=60000010
-MODE_ABT:
-R13=6400090c R14=ffff0010 SPSR=400000d7
-MODE_UND:
-R13=6400090c R14=95221110 SPSR=f000009d
-</codeblock> <p>The panic happened in supervisor mode, because <codeph>CPSR
-& 0x1F == 0x13</codeph>, so <codeph>R13Svc</codeph>, i.e.
-the value of <codeph>R13</codeph> shown under <codeph>MODE_SVC:</codeph> in
-the above display, is the stack pointer to look at; this has the value <codeph>0x6571DE54</codeph>. </p> </li>
-<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
-6571de54: 07 00 00 10 14 04 17 f8 00 00 00 00 d4 4e 40 00 .............N@.
-6571de64: e8 de 71 65 74 de 71 65 74 fb 16 f8 88 28 03 f8 ..qet.qet....(..
-6571de74: 0c d4 03 f8 64 35 03 f8 00 00 00 00 00 00 00 00 ....d5..........
-6571de84: d0 00 00 00 14 df 71 65 a8 cb 03 64 a8 cb 03 64 ......qe...d...d
-6571de94: d0 00 00 00 14 df 71 65 1c df 71 65 ec 4e 40 00 ......qe..qe.N@.
-6571dea4: 1c c4 03 64 b4 2a 03 f8 00 00 00 00 14 df 71 65 ...d.*........qe
-6571deb4: d0 de 71 65 c4 de 71 65 b0 ab 03 f8 00 00 00 00 ..qe..qe........
-6571dec4: e0 ba 03 64 14 df 71 65 1c df 71 65 01 00 00 00 ...d..qe..qe....
-6571ded4: 1c c4 03 64 f8 02 00 64 10 df 71 65 ec de 71 65 ...d...d..qe..qe
-6571dee4: 84 da 01 f8 5c fb 16 f8 00 4e 40 00 00 00 00 00 ....\....N@.....
-6571def4: 00 4e 40 00 00 00 00 00 d3 00 00 00 ec 4e 40 00 .N@..........N@.
-6571df04: d4 df 71 65 14 df 71 65 e0 db 01 f8 c0 d9 01 f8 ..qe..qe........
-6571df14: a8 cb 03 64 e0 ba 03 64 01 00 01 00 00 00 00 00 ...d...d........
-6571df24: 00 00 00 00 d4 4e 40 00 00 00 00 30 40 00 00 00 .....N@....0@...
-6571df34: 13 00 00 60 98 df 71 65 48 df 71 65 f4 81 00 f8 ...`..qeH.qe....
-6571df44: 8c 7a 00 f8 68 df 71 65 58 df 71 65 6c df 71 65 .z..h.qeX.qel.qe
-6571df54: 60 df 71 65 0c 2b 00 f8 bc 2a 00 f8 84 df 71 65 `.qe.+...*....qe
-6571df64: 70 df 71 65 e4 7d 04 f8 08 2b 00 f8 0d 00 00 00 p.qe.}...+......
-6571df74: 0a 00 00 30 40 00 00 00 54 65 73 74 44 6d 61 53 ...0@...TestDmaS
-6571df84: 69 6d 04 f8 a9 4b 40 00 b8 df 71 65 9c df 71 65 im...K@...qe..qe
-6571df94: 2c be 00 f8 2c bd 00 f8 38 4c 40 0d 01 00 00 00 ,...,...8L@.....
-6571dfa4: 00 00 00 00 84 2d 02 f8 d4 df 71 65 bc df 71 65 .....-....qe..qe
-6571dfb4: b8 2d 02 f8 dc bd 00 f8 54 a4 00 f8 00 00 00 00 .-......T.......
-6571dfc4: ac da 01 f8 10 00 00 60 d8 df 71 65 70 74 00 f8 .......`..qept..
-6571dfd4: b8 da 01 f8 d4 4e 40 00 20 f7 16 f8 d0 4e 40 00 .....N@. ....N@.
-6571dfe4: 00 00 00 00 00 00 00 00 ec 4e 40 00 40 00 00 00 .........N@.@...
-</codeblock> <p>We can look for potential ROM addresses by scanning the log
-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> .
-The first one is <codeph>0xF8170414</codeph> at offset <codeph>4</codeph> in
-the memory dump. </p> </li>
-<li id="GUID-3197B03A-FD94-5D78-B699-22BDCE71DD1D"><p>Alternatively, we can
-use the <filepath>printsym.pl</filepath> perl script, passing it the dump
-output. The following is part of the output: </p> <codeblock id="GUID-B4289E03-6E98-591D-9E26-CEEDC3CD9437" xml:space="preserve">R:\base\e32\rombuild>perl -S printsym.pl ASSABETARM4D.symbol
-ROM Symbols from ASSABETARM4D.symbol
-Please enter data to be decoded
-6571de54: 07 00 00 10 14 04 17 f8 00 00 00 00 d4 4e 40 00 .............N@.
-= 10000007 ....
-= f8170414 .... etext=. + 0x0
-= 00000000 ....
-= 00404ed4 .N@.
-6571de64: e8 de 71 65 74 de 71 65 74 fb 16 f8 88 28 03 f8 ..qet.qet....(..
-= 6571dee8 ..qe
-= 6571de74 t.qe
-= f816fb74 t... DDmaTestChannel::DoCreate(int, TDesC8 const *, TVersion const &
-) + 0x24
-= f8032888 .(.. Kern::Fault(char const *, int) + 0xc
-6571de74: 0c d4 03 f8 64 35 03 f8 00 00 00 00 00 00 00 00 ....d5..........
-= f803d40c .... RHeap::Alloc(int) + 0xf4
-= f8033564 d5.. Kern::MutexSignal(DMutex &) + 0xc
-= 00000000 ....
-= 00000000 ....
-
-[............ truncated ...............]
-
-= f801da84 .... DLogicalDevice::ChannelCreate(DLogicalChannelBase *&, TChannelC
-reateInfo &) + 0xd0
-= f816fb5c \... DDmaTestChannel::DoCreate(int, TDesC8 const *, TVersion const &
-) + 0xc
-= 00404e00 .N@.
-= 00000000 ....
-6571def4: 00 4e 40 00 00 00 00 00 d3 00 00 00 ec 4e 40 00 .N@..........N@.
-= 00404e00 .N@.
-= 00000000 ....
-= 000000d3 ....
-= 00404eec .N@.
-6571df04: d4 df 71 65 14 df 71 65 e0 db 01 f8 c0 d9 01 f8 ..qe..qe........
-= 6571dfd4 ..qe
-= 6571df14 ..qe
-= f801dbe0 .... ExecHandler::ChannelCreate(TDesC8 const &, TChannelCreateInfo &
-, int) + 0x134
-= f801d9c0 .... DLogicalDevice::ChannelCreate(DLogicalChannelBase *&, TChannelC
-reateInfo &) + 0xc
-
-[.......................... truncated .........................]
-
-= f8022db8 .-.. ExecHandler::DebugPrint(void *, int) + 0x34
-= f800bddc .... A::UserDebugPrint(unsigned char const *, int, int) + 0xc
-= f800a454 T... EpocSlowExecTable + 0xc
-= 00000000 ....
-6571dfc4: ac da 01 f8 10 00 00 60 d8 df 71 65 70 74 00 f8 .......`..qept..
-= f801daac .... ExecHandler::ChannelCreate(TDesC8 const &, TChannelCreateInfo &
-, int) + 0x0
-= 60000010 ...`
-= 6571dfd8 ..qe
-= f8007470 pt.. __ArmVectorSwi + 0xd8
-6571dfd4: b8 da 01 f8 d4 4e 40 00 20 f7 16 f8 d0 4e 40 00 .....N@. ....N@.
-= f801dab8 .... ExecHandler::ChannelCreate(TDesC8 const &, TChannelCreateInfo &
-, int) + 0xc
-= 00404ed4 .N@.
-= f816f720 ... etext=. + 0x560
-= 00404ed0 .N@.
-6571dfe4: 00 00 00 00 00 00 00 00 ec 4e 40 00 40 00 00 00 .........N@.@...
-= 00000000 ....
-= 00000000 ....
-= 00404eec .N@.
-= 00000040 @...
-^C
-R:\base\e32\rombuild>
-</codeblock> <p>There are several false positives in this output (and even
-more in the truncated parts). So some study of the source code is needed to
-discard the noise and find the actual call stack. Here it is (innermost frame
-first): </p> <ul>
-<li id="GUID-C83CA525-1731-56BC-8C98-4AEEB5809780"><p> <codeph>Kern::Fault</codeph> </p> </li>
-<li id="GUID-40B7B48A-F6A0-5CD6-9C0C-2E432FF760BA"><p> <codeph>DDmaTestChannel::DoCreate</codeph> </p> </li>
-<li id="GUID-E9327B91-F69C-5BC1-B964-FE1B90CA314C"><p> <codeph>ExecHandler::ChannelCreate</codeph> </p> </li>
-<li id="GUID-0391ADD8-EF56-51F9-987F-B9111903EAC7"><p> <codeph> __ArmVectorSwi</codeph> </p> </li>
-</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
-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
-other function names are false positives and should be ignored. </p> </li>
-</ul> </section>
-<section id="GUID-7F160B0F-9921-578B-B9B0-7CC4CA3B24C3"><title>Walking through
-the call stack</title> <p>The heuristic method is quick but produces lots
-of false positives. Another option is to manually reconstitute the call stack
-from the memory dump. This is relatively easy for debug builds because GCC
-uses R11 as a frame pointer (FP) and generates the same prologue/epilogue
-for every function. </p> <p>For release builds, there is no generic solution.
-It is necessary to check the generated assembler code as there is no standard
-prologue/epilogue and R11 is not used as frame pointer. </p> <p>A typical
-prologue for a debug ARM function looks like this: </p> <codeblock id="GUID-9C1F71E0-5F2A-50FF-ABD2-035EB9B5B4D9" xml:space="preserve">mov ip, sp
-stmfd sp!, {fp, ip, lr, pc}
-sub fp, ip, #4 /* FP now points to base of stack frame */
-sub sp, sp, #16 /* space for local variables */
-</codeblock> <p>noting that: <codeph>SP = R13</codeph>, <codeph>FP = R11</codeph>, <codeph>IP
-= R12</codeph>, <codeph>LR = R14</codeph>, and <codeph>PC = R15</codeph>. </p> <p>This
-code creates the following stack frame: </p> <fig id="GUID-5CE044A2-CDD0-5A09-B824-BAF46324AB27">
-<image href="GUID-F12437C5-BD96-5B43-AD76-614CFAB104D2_d0e300510_href.png" placement="inline"/>
-</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
-to a panic, the FP value is the R11 value; this is <codeph>0x6571de70</codeph>.
-This gives us the innermost stack frame: </p> <codeblock id="GUID-DE5FFB23-A85D-562F-858B-CFF407448E36" xml:space="preserve">6571de64: e8 de 71 65 <------------- pointer to previous stack frame
- 74 de 71 65
- 74 fb 16 f8 <------------- Saved return address
- 88 28 03 f8 <------------- FP points to this word
-</codeblock> <p>Looking up the saved return address, <codeph>0xf816fb74</codeph>,
-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 &)
-f816fce8 007c DDmaTestChannel::~DDmaTestChannel(void)
-f816fd64 0294 DDmaTestChannel::Request(int, void *, void *)
-</codeblock> <p>Using the pointer to the previous stack frame saved into the
-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
- f8 02 00 64
- 10 df 71 65 <------------- pointer to previous stack frame
- ec de 71 65
-
-6571dee4: 84 da 01 f8 <------------- saved return address
- 5c fb 16 f8 <------------- start of second stack frame
- 00 4e 40 00
- 00 00 00 00
-</codeblock> <p>Looking up the saved return address, <codeph>0xf801da84</codeph>,
-in the symbol file shows that <codeph>DDmaTestChannel::DoCreate()</codeph> was
-called from <codeph>DLogicalDevice::ChannelCreate()</codeph>. </p> <codeblock id="GUID-B36A9D49-5414-5CC3-8CBF-A2A0EE332B3C" xml:space="preserve">f801d9b4 00f8 DLogicalDevice::ChannelCreate(DLogicalChannelBase *&, TChannelCreateInfo &)
-f801daac 01b8 ExecHandler::ChannelCreate(TDesC8 const &, TChannelCreateInfo &, int)
-f801dc64 00e4 ExecHandler::ChannelRequest(DLogicalChannelBase *, int, void *, void *)
-</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 <------------- pointer to previous stack frame
- 14 df 71 65
- e0 db 01 f8 <------------- saved return address
- c0 d9 01 f8 <------------- start of third stack frame
-</codeblock> <p>So <codeph>DLogicalDevice::ChannelCreate()</codeph> was called
-from <codeph>ExecHandler::ChannelCreate()</codeph>. </p> <p>Note that this
-mechanical way of walking the stack is valid only for debug functions. For
-release functions, it is necessary to study the code generated by the compiler. </p> <p>For
-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 }
-sub sp, #28
-add r7, sp, #12 /* R7 is THUMB frame pointer */
-</codeblock> <p>and this creates the following stack frame: </p> <fig id="GUID-85FAEE94-6D61-5D6B-84CB-6A9491927077">
-<image href="GUID-5CF162CA-4395-58AC-A318-2BF178276A57_d0e300587_href.png" placement="inline"/>
-</fig> <p>A call stack can mix ARM and THUMB frames. Odd return addresses
-are used for THUMB code and even ones for ARM code. </p> </section>
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies) All rights reserved. -->
+<!-- This component and the accompanying materials are made available under the terms of the License
+"Eclipse Public License v1.0" which accompanies this distribution,
+and is available at the URL "http://www.eclipse.org/legal/epl-v10.html". -->
+<!-- Initial Contributors:
+ Nokia Corporation - initial contribution.
+Contributors:
+-->
+<!DOCTYPE concept
+ PUBLIC "-//OASIS//DTD DITA Concept//EN" "concept.dtd">
+<concept id="GUID-1E43E258-A926-5D24-B0A5-8756491C687F" xml:lang="en"><title>Call
+Stack Information Commands</title><prolog><metadata><keywords/></metadata></prolog><conbody>
+<p>Describes how to use the debug monitor commands to get information about
+the call stack. </p>
+<ul>
+<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>
+<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>
+<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>
+<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>
+</ul>
+<section id="GUID-D8F141D7-3BE2-5ADB-8A55-CFFE85E89804"><title>General points</title> <p>Tracing
+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
+memory</xref>. </p> <p>Every time a function is called, the return address
+is automatically saved into register <codeph>R14</codeph> (Link Register).
+In addition to this the return address is generally pushed onto the call stack;
+it is always pushed in debug builds but the push operation is sometimes optimized
+out in release builds. This allows you to trace back through the value of <codeph>R14</codeph> and
+these saved addresses to see the sequence of function calls. Unfortunately
+this is quite tedious to do because the stack is also used for automatic variables
+and other data. You need to work out which values on the stack refer to return
+addresses. </p> <p>When you are debugging only ROM-based code, it is relatively
+easy to identify the pushed return addresses because all code addresses will
+be in the ROM range: <codeph>0xF800000</codeph> to <codeph>0xFFEFFFFF</codeph> for
+the <xref href="GUID-D520CBC3-FCAC-5A53-AE1A-E5254ABBC6A2.dita#GUID-D520CBC3-FCAC-5A53-AE1A-E5254ABBC6A2/GUID-A5845A0C-2C88-52BB-B7DE-210C2DE481B9">moving
+model</xref>. However, there is also data in the ROM, which means that an
+address on the stack which is in the ROM range could point to data instead
+of code. If you want to trace applications loaded into RAM, i.e. anything
+not run from drive Z:, then stack tracing is more difficult because the code
+can move about and RAM-loaded code is given an address assigned at load time. </p> <p>Note
+that <xref href="GUID-DA62FD4F-2E74-5B2F-B703-4A40DF5F01CA.dita">using the MAKSYM
+tool</xref> is essential for tracing back through the stack. </p> </section>
+<section id="GUID-1EC3F2E7-6BFF-56BE-B042-DA6940CC909E"><title>Finding the
+stack</title> <p>To trace back through a thread’s kernel or user stack, you
+first need to find the stack pointer value. On the ARM, <codeph>R13</codeph> always
+points to the stack, but there are different <codeph>R13</codeph> registers
+for each processor mode: </p> <ul>
+<li id="GUID-756C8CDD-AF47-561B-BAA7-EA8FBDEE5245"><p>In thread context: </p> <ul>
+<li id="GUID-81BC92C2-6022-5EBF-BF60-C4D69131C720"><p> <codeph>R13usr</codeph> points
+to the thread’s user stack, </p> </li>
+<li id="GUID-CA6CF8C9-0BA3-5BD4-AECE-80AB3DFCFAD1"><p> <codeph>R13svc</codeph> points
+to the thread’s kernel stack. </p> </li>
+</ul> </li>
+<li id="GUID-C4A1AD73-64E8-56F7-A7DF-129B2A35FC9D"><p>When handling interrupts,
+dedicated stacks are used: </p> <ul>
+<li id="GUID-7D27A691-1479-578B-9B05-7946C8D84010"><p> <codeph>R13Fiq</codeph> points
+to the stack used when processing fast interrupts (FIQ). </p> </li>
+<li id="GUID-CE76BE0F-A6BA-55A6-8CDD-B1E40D97A42D"><p> <codeph>R13Irq</codeph> points
+to the stack used when processing general purpose interrupts (IRQ). </p> </li>
+</ul> </li>
+</ul> <p>To find out which stack to inspect, you need to know what mode the
+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
+mode</xref> is identified by the five least-significant bits of the CPSR register.
+To get the value of the CPSR register: </p> <ul>
+<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>
+<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>
+</ul> <p>The following examples show how to find the stack(s): </p> <ul>
+<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 & user stacks of the current thread after a hardware exception</xref> </p> </li>
+<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 & user stacks of the current thread after a panic</xref> </p> </li>
+<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>
+<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 & user stacks of a non-current thread</xref> </p> </li>
+</ul> <p id="GUID-4E735CB7-3171-58FB-9D93-EE86702952F6"><b>Kernel & user stacks
+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
+ExcId 00000001 CodeAddr f816c908 DataAddr 80000001 Extra c0007003
+Exc 1 Cpsr=60000010 FAR=80000001 FSR=c0007003
+ R0=00000000 R1=00000000 R2=30000000 R3=80000001
+ R4=00000001 R5=00403d88 R6=00002000 R7=f816c768
+ R8=00000012 R9=00000040 R10=00000000 R11=00403fa4
+R12=00403d5c R13=00403d70 R14=f80906f8 R15=f816c908
+R13Svc=6571e000 R14Svc=f80074bc SpsrSvc=80000010
+</codeblock> <p>In this example: </p> <ul>
+<li id="GUID-7C35AE63-13E9-5D8D-A77F-CD1A0B9A5EF4"><p>the kernel stack is
+the value of <codeph>R13Svc</codeph>, i.e. <codeph>0x6571e00</codeph>. </p> </li>
+<li id="GUID-D70628B9-A750-5557-BACF-471D2D75A2E4"><p>the user stack is the
+value of <codeph>R13</codeph>, i.e. <codeph>0x00403d70</codeph>. </p> </li>
+</ul> <p id="GUID-FB9D2307-01D9-562A-A46F-AAD91D61C32E"><b>Kernel & user stacks
+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:
+ R0=6571de54 R1=0000002a R2=00000002 R3=ffffffff
+ R4=0000002a R5=f8170414 R6=6571df14 R7=6403cc50
+ R8=00000001 R9=6403c44c R10=640002f8 R11=6571de70
+R12=00000020 R13=00404e00 R14=f80818c0 R15=f800bfa8
+CPSR=60000013
+MODE_FIQ:
+ R8=00000000 R9=ffffffff R10=ffffffff R11=00000000
+R12=00000000 R13=64000d0c R14=c080079c SPSR=e00000dc
+MODE_IRQ:
+R13=6400110c R14=00000013 SPSR=20000013
+MODE_SVC:
+R13=6571de54 R14=f80328bc SPSR=60000010
+MODE_ABT:
+R13=6400090c R14=ccbfd0e0 SPSR=b00000d9
+MODE_UND:
+R13=6400090c R14=b5a39950 SPSR=f000009d
+</codeblock> <p>In this example: </p> <ul>
+<li id="GUID-C23A3F68-FAEB-596A-AF51-810E7429D17B"><p>the kernel stack is
+the value of <codeph>R13</codeph> under <codeph>MODE_SVC:</codeph>, i.e. <codeph>0x6571de54</codeph>. </p> </li>
+<li id="GUID-98FD71CA-BD17-5CB3-B0A8-0FBECFBF3ECF"><p>the user stack is the
+value of <codeph>R13</codeph> under <codeph>MODE_USR:</codeph>, i.e. <codeph>0x00404e00</codeph>. </p> </li>
+</ul> <p id="GUID-C265F9C5-3280-5A4F-B023-56E33D52DDE0"><b>Interrupt stacks</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-28065EA2-194E-5D8D-8C1B-D85299B91431" xml:space="preserve">MODE_USR:
+ R0=6571de54 R1=0000002a R2=00000002 R3=ffffffff
+ R4=0000002a R5=f8170414 R6=6571df14 R7=6403cc50
+ R8=00000001 R9=6403c44c R10=640002f8 R11=6571de70
+R12=00000020 R13=00404e00 R14=f80818c0 R15=f800bfa8
+CPSR=60000013
+MODE_FIQ:
+ R8=00000000 R9=ffffffff R10=ffffffff R11=00000000
+R12=00000000 R13=64000d0c R14=c080079c SPSR=e00000dc
+MODE_IRQ:
+R13=6400110c R14=00000013 SPSR=20000013
+MODE_SVC:
+R13=6571de54 R14=f80328bc SPSR=60000010
+MODE_ABT:
+R13=6400090c R14=ccbfd0e0 SPSR=b00000d9
+MODE_UND:
+R13=6400090c R14=b5a39950 SPSR=f000009d
+</codeblock> <p>In this example: </p> <ul>
+<li id="GUID-6A48007B-973A-50F1-BCF5-31A72EC68D57"><p>the IRQ stack is the
+value of <codeph>R13</codeph> under <codeph>MODE_IRQ:</codeph>, i.e. <codeph>0x6400110c</codeph>. </p> </li>
+<li id="GUID-65CD3376-7D50-548F-A473-04B049034D0D"><p>the FRQ stack is the
+value of <codeph>R13</codeph> under <codeph>MODE_FIQ:</codeph>, i.e. <codeph>0x64000d0c</codeph>. </p> </li>
+</ul> <p id="GUID-9637574E-A9A0-509D-B9B1-C672E2B13431"><b>Kernel & user stacks
+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
+Full name t_dmasim::Main
+Thread MState READY
+Default priority 12 WaitLink Priority 12
+ExitInfo 3,0,
+Flags 00000002, Handles 6403b418
+Supervisor stack base 6571d000 size 1000
+User stack base 00403000 size 2000
+Id=25, Alctr=00700000, Created alctr=00700000, Frame=00000000
+Trap handler=00000000, ActiveScheduler=007000c8, Exception handler=00000000
+TempObj=00000000 TempAlloc=00000000
+NThread @ 6403c44c Pri 12 NState READY
+Next=6403c44c Prev=6403c44c Att=03 iUserContextType=02
+HeldFM=00000000 WaitFM=00000000 AddrSp=6403bb4c
+Time=0 Timeslice=20 ReqCount=0
+SuspendCount=0 CsCount=1 CsFunction=00000000
+SavedSP=6571df98
+DACR f800bd2c
+R13_USR 0d404c38 R14_USR 00000001 SPSR_SVC 00000000
+ R4 f8022d84 R5 6571dfd4 R6 6571dfbc R7 f8022db8
+ R8 f800bddc R9 f800a454 R10 00000000 R11 f801daac
+ PC 60000010
+</codeblock> <p>In this example: </p> <ul>
+<li id="GUID-A4217DD4-A46C-5EAE-85D3-2EEAD763B726"><p>the kernel stack is
+the value of <codeph>SavedSP</codeph>, i.e. <codeph>0x6571df98</codeph>. </p> </li>
+<li id="GUID-8220888D-7411-5AC5-AD20-89E892301188"><p>the user stack is the
+value of <codeph>R13_USR</codeph>, i.e. <codeph>0x0d404c38</codeph>. </p> </li>
+</ul> </section>
+<section id="GUID-877742A5-F07F-54B6-B871-255FAAE790EB"><title>Tracing through
+the stack heuristically</title> <p>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 address. We say that this heuristic because: </p> <ul>
+<li id="GUID-B5BF6BD6-0163-55F9-A34D-EB78982848B0"><p>some data words may
+look like code addresses in ROM. </p> </li>
+<li id="GUID-0A978212-73B6-5C89-B805-84327B9CF733"><p>there may be saved return
+addresses left over from previous function calls. For example, suppose that <codeph>F()</codeph> calls <codeph>A()</codeph> and
+then <codeph>B()</codeph> in sequence. <codeph>A()</codeph> itself calls <codeph>X()</codeph>,
+which calls <codeph>Y()</codeph>. If a crash occurs in <codeph>B()</codeph>,
+the saved return addresses from the calls to <codeph>X()</codeph> and <codeph>Y()</codeph> are
+still present on the stack and may be mistaken for function calls occuring
+while <codeph>B()</codeph> is active. </p> <p>This scenario happens frequently
+when <codeph>B()</codeph> allocates a buffer (e.g. <xref href="GUID-0B9C8884-6BFF-35E2-AA6F-E4057B85AFCF.dita"><apiname>TBuf</apiname></xref>)
+on the stack which overlaps old stack frames. </p> <fig id="GUID-FED8CC0F-F1A0-59C9-B082-2D3B499D00D5">
+<image href="GUID-A328F9E3-7D91-594A-A589-E8CE5FA9227A_d0e298551_href.png" placement="inline"/>
+</fig> </li>
+</ul> <p>If you want to trace applications loaded into RAM, then stack tracing
+is more difficult because RAM-loaded DLLs are given addresses assigned at
+load time. </p> <p>On ARM, the stack pointer starts at the higher address
+end and moves 'down' towards the lower address end. This means that values
+at the top of the memory dump are more recent. You need to look back through
+this for code addresses. For ROM code this will be words with most significant
+byte in the range <codeph>0xF8</codeph> to <codeph>0xFF</codeph>, remembering
+that they are little-endian. This can either be done manually, or automatically
+using the <filepath>printsym.pl</filepath> perl script, which can be found
+in <codeph>...\epoc32\tools</codeph>. </p> <p>Let's follow this in an example
+session: </p> <ul>
+<li id="GUID-D761405E-86BD-55ED-ACC6-C6D2125FDCE7"><p>Decide whether the crash
+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
+Fault Category: EXAMPLE Fault Reason: 0000002a
+ExcId 00000000 CodeAddr 00000000 DataAddr 00000000 Extra 00000000
+</codeblock> </li>
+<li id="GUID-73690262-2895-51ED-9532-E76638B0EC1E"><p>This shows that the
+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
+MODE_USR:
+ R0=6571de54 R1=0000002a R2=00000002 R3=ffffffff
+ R4=0000002a R5=f8170414 R6=6571df14 R7=6403cba8
+ R8=00000001 R9=6403c41c R10=640002f8 R11=6571de70
+R12=00000020 R13=00404e00 R14=f80818c0 R15=f800bfa8
+CPSR=60000013
+MODE_FIQ:
+ R8=00000000 R9=ffffffff R10=ffffffff R11=00000000
+R12=00000000 R13=64000d0c R14=c080079c SPSR=e00000dc
+MODE_IRQ:
+R13=6400110c R14=00000013 SPSR=20000013
+MODE_SVC:
+R13=6571de54 R14=f80328bc SPSR=60000010
+MODE_ABT:
+R13=6400090c R14=ffff0010 SPSR=400000d7
+MODE_UND:
+R13=6400090c R14=95221110 SPSR=f000009d
+</codeblock> <p>The panic happened in supervisor mode, because <codeph>CPSR
+& 0x1F == 0x13</codeph>, so <codeph>R13Svc</codeph>, i.e.
+the value of <codeph>R13</codeph> shown under <codeph>MODE_SVC:</codeph> in
+the above display, is the stack pointer to look at; this has the value <codeph>0x6571DE54</codeph>. </p> </li>
+<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
+6571de54: 07 00 00 10 14 04 17 f8 00 00 00 00 d4 4e 40 00 .............N@.
+6571de64: e8 de 71 65 74 de 71 65 74 fb 16 f8 88 28 03 f8 ..qet.qet....(..
+6571de74: 0c d4 03 f8 64 35 03 f8 00 00 00 00 00 00 00 00 ....d5..........
+6571de84: d0 00 00 00 14 df 71 65 a8 cb 03 64 a8 cb 03 64 ......qe...d...d
+6571de94: d0 00 00 00 14 df 71 65 1c df 71 65 ec 4e 40 00 ......qe..qe.N@.
+6571dea4: 1c c4 03 64 b4 2a 03 f8 00 00 00 00 14 df 71 65 ...d.*........qe
+6571deb4: d0 de 71 65 c4 de 71 65 b0 ab 03 f8 00 00 00 00 ..qe..qe........
+6571dec4: e0 ba 03 64 14 df 71 65 1c df 71 65 01 00 00 00 ...d..qe..qe....
+6571ded4: 1c c4 03 64 f8 02 00 64 10 df 71 65 ec de 71 65 ...d...d..qe..qe
+6571dee4: 84 da 01 f8 5c fb 16 f8 00 4e 40 00 00 00 00 00 ....\....N@.....
+6571def4: 00 4e 40 00 00 00 00 00 d3 00 00 00 ec 4e 40 00 .N@..........N@.
+6571df04: d4 df 71 65 14 df 71 65 e0 db 01 f8 c0 d9 01 f8 ..qe..qe........
+6571df14: a8 cb 03 64 e0 ba 03 64 01 00 01 00 00 00 00 00 ...d...d........
+6571df24: 00 00 00 00 d4 4e 40 00 00 00 00 30 40 00 00 00 .....N@....0@...
+6571df34: 13 00 00 60 98 df 71 65 48 df 71 65 f4 81 00 f8 ...`..qeH.qe....
+6571df44: 8c 7a 00 f8 68 df 71 65 58 df 71 65 6c df 71 65 .z..h.qeX.qel.qe
+6571df54: 60 df 71 65 0c 2b 00 f8 bc 2a 00 f8 84 df 71 65 `.qe.+...*....qe
+6571df64: 70 df 71 65 e4 7d 04 f8 08 2b 00 f8 0d 00 00 00 p.qe.}...+......
+6571df74: 0a 00 00 30 40 00 00 00 54 65 73 74 44 6d 61 53 ...0@...TestDmaS
+6571df84: 69 6d 04 f8 a9 4b 40 00 b8 df 71 65 9c df 71 65 im...K@...qe..qe
+6571df94: 2c be 00 f8 2c bd 00 f8 38 4c 40 0d 01 00 00 00 ,...,...8L@.....
+6571dfa4: 00 00 00 00 84 2d 02 f8 d4 df 71 65 bc df 71 65 .....-....qe..qe
+6571dfb4: b8 2d 02 f8 dc bd 00 f8 54 a4 00 f8 00 00 00 00 .-......T.......
+6571dfc4: ac da 01 f8 10 00 00 60 d8 df 71 65 70 74 00 f8 .......`..qept..
+6571dfd4: b8 da 01 f8 d4 4e 40 00 20 f7 16 f8 d0 4e 40 00 .....N@. ....N@.
+6571dfe4: 00 00 00 00 00 00 00 00 ec 4e 40 00 40 00 00 00 .........N@.@...
+</codeblock> <p>We can look for potential ROM addresses by scanning the log
+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> .
+The first one is <codeph>0xF8170414</codeph> at offset <codeph>4</codeph> in
+the memory dump. </p> </li>
+<li id="GUID-3197B03A-FD94-5D78-B699-22BDCE71DD1D"><p>Alternatively, we can
+use the <filepath>printsym.pl</filepath> perl script, passing it the dump
+output. The following is part of the output: </p> <codeblock id="GUID-B4289E03-6E98-591D-9E26-CEEDC3CD9437" xml:space="preserve">R:\base\e32\rombuild>perl -S printsym.pl ASSABETARM4D.symbol
+ROM Symbols from ASSABETARM4D.symbol
+Please enter data to be decoded
+6571de54: 07 00 00 10 14 04 17 f8 00 00 00 00 d4 4e 40 00 .............N@.
+= 10000007 ....
+= f8170414 .... etext=. + 0x0
+= 00000000 ....
+= 00404ed4 .N@.
+6571de64: e8 de 71 65 74 de 71 65 74 fb 16 f8 88 28 03 f8 ..qet.qet....(..
+= 6571dee8 ..qe
+= 6571de74 t.qe
+= f816fb74 t... DDmaTestChannel::DoCreate(int, TDesC8 const *, TVersion const &
+) + 0x24
+= f8032888 .(.. Kern::Fault(char const *, int) + 0xc
+6571de74: 0c d4 03 f8 64 35 03 f8 00 00 00 00 00 00 00 00 ....d5..........
+= f803d40c .... RHeap::Alloc(int) + 0xf4
+= f8033564 d5.. Kern::MutexSignal(DMutex &) + 0xc
+= 00000000 ....
+= 00000000 ....
+
+[............ truncated ...............]
+
+= f801da84 .... DLogicalDevice::ChannelCreate(DLogicalChannelBase *&, TChannelC
+reateInfo &) + 0xd0
+= f816fb5c \... DDmaTestChannel::DoCreate(int, TDesC8 const *, TVersion const &
+) + 0xc
+= 00404e00 .N@.
+= 00000000 ....
+6571def4: 00 4e 40 00 00 00 00 00 d3 00 00 00 ec 4e 40 00 .N@..........N@.
+= 00404e00 .N@.
+= 00000000 ....
+= 000000d3 ....
+= 00404eec .N@.
+6571df04: d4 df 71 65 14 df 71 65 e0 db 01 f8 c0 d9 01 f8 ..qe..qe........
+= 6571dfd4 ..qe
+= 6571df14 ..qe
+= f801dbe0 .... ExecHandler::ChannelCreate(TDesC8 const &, TChannelCreateInfo &
+, int) + 0x134
+= f801d9c0 .... DLogicalDevice::ChannelCreate(DLogicalChannelBase *&, TChannelC
+reateInfo &) + 0xc
+
+[.......................... truncated .........................]
+
+= f8022db8 .-.. ExecHandler::DebugPrint(void *, int) + 0x34
+= f800bddc .... A::UserDebugPrint(unsigned char const *, int, int) + 0xc
+= f800a454 T... EpocSlowExecTable + 0xc
+= 00000000 ....
+6571dfc4: ac da 01 f8 10 00 00 60 d8 df 71 65 70 74 00 f8 .......`..qept..
+= f801daac .... ExecHandler::ChannelCreate(TDesC8 const &, TChannelCreateInfo &
+, int) + 0x0
+= 60000010 ...`
+= 6571dfd8 ..qe
+= f8007470 pt.. __ArmVectorSwi + 0xd8
+6571dfd4: b8 da 01 f8 d4 4e 40 00 20 f7 16 f8 d0 4e 40 00 .....N@. ....N@.
+= f801dab8 .... ExecHandler::ChannelCreate(TDesC8 const &, TChannelCreateInfo &
+, int) + 0xc
+= 00404ed4 .N@.
+= f816f720 ... etext=. + 0x560
+= 00404ed0 .N@.
+6571dfe4: 00 00 00 00 00 00 00 00 ec 4e 40 00 40 00 00 00 .........N@.@...
+= 00000000 ....
+= 00000000 ....
+= 00404eec .N@.
+= 00000040 @...
+^C
+R:\base\e32\rombuild>
+</codeblock> <p>There are several false positives in this output (and even
+more in the truncated parts). So some study of the source code is needed to
+discard the noise and find the actual call stack. Here it is (innermost frame
+first): </p> <ul>
+<li id="GUID-C83CA525-1731-56BC-8C98-4AEEB5809780"><p> <codeph>Kern::Fault</codeph> </p> </li>
+<li id="GUID-40B7B48A-F6A0-5CD6-9C0C-2E432FF760BA"><p> <codeph>DDmaTestChannel::DoCreate</codeph> </p> </li>
+<li id="GUID-E9327B91-F69C-5BC1-B964-FE1B90CA314C"><p> <codeph>ExecHandler::ChannelCreate</codeph> </p> </li>
+<li id="GUID-0391ADD8-EF56-51F9-987F-B9111903EAC7"><p> <codeph> __ArmVectorSwi</codeph> </p> </li>
+</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
+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
+other function names are false positives and should be ignored. </p> </li>
+</ul> </section>
+<section id="GUID-7F160B0F-9921-578B-B9B0-7CC4CA3B24C3"><title>Walking through
+the call stack</title> <p>The heuristic method is quick but produces lots
+of false positives. Another option is to manually reconstitute the call stack
+from the memory dump. This is relatively easy for debug builds because GCC
+uses R11 as a frame pointer (FP) and generates the same prologue/epilogue
+for every function. </p> <p>For release builds, there is no generic solution.
+It is necessary to check the generated assembler code as there is no standard
+prologue/epilogue and R11 is not used as frame pointer. </p> <p>A typical
+prologue for a debug ARM function looks like this: </p> <codeblock id="GUID-9C1F71E0-5F2A-50FF-ABD2-035EB9B5B4D9" xml:space="preserve">mov ip, sp
+stmfd sp!, {fp, ip, lr, pc}
+sub fp, ip, #4 /* FP now points to base of stack frame */
+sub sp, sp, #16 /* space for local variables */
+</codeblock> <p>noting that: <codeph>SP = R13</codeph>, <codeph>FP = R11</codeph>, <codeph>IP
+= R12</codeph>, <codeph>LR = R14</codeph>, and <codeph>PC = R15</codeph>. </p> <p>This
+code creates the following stack frame: </p> <fig id="GUID-5CE044A2-CDD0-5A09-B824-BAF46324AB27">
+<image href="GUID-F12437C5-BD96-5B43-AD76-614CFAB104D2_d0e298749_href.png" placement="inline"/>
+</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
+to a panic, the FP value is the R11 value; this is <codeph>0x6571de70</codeph>.
+This gives us the innermost stack frame: </p> <codeblock id="GUID-DE5FFB23-A85D-562F-858B-CFF407448E36" xml:space="preserve">6571de64: e8 de 71 65 <------------- pointer to previous stack frame
+ 74 de 71 65
+ 74 fb 16 f8 <------------- Saved return address
+ 88 28 03 f8 <------------- FP points to this word
+</codeblock> <p>Looking up the saved return address, <codeph>0xf816fb74</codeph>,
+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 &)
+f816fce8 007c DDmaTestChannel::~DDmaTestChannel(void)
+f816fd64 0294 DDmaTestChannel::Request(int, void *, void *)
+</codeblock> <p>Using the pointer to the previous stack frame saved into the
+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
+ f8 02 00 64
+ 10 df 71 65 <------------- pointer to previous stack frame
+ ec de 71 65
+
+6571dee4: 84 da 01 f8 <------------- saved return address
+ 5c fb 16 f8 <------------- start of second stack frame
+ 00 4e 40 00
+ 00 00 00 00
+</codeblock> <p>Looking up the saved return address, <codeph>0xf801da84</codeph>,
+in the symbol file shows that <codeph>DDmaTestChannel::DoCreate()</codeph> was
+called from <codeph>DLogicalDevice::ChannelCreate()</codeph>. </p> <codeblock id="GUID-B36A9D49-5414-5CC3-8CBF-A2A0EE332B3C" xml:space="preserve">f801d9b4 00f8 DLogicalDevice::ChannelCreate(DLogicalChannelBase *&, TChannelCreateInfo &)
+f801daac 01b8 ExecHandler::ChannelCreate(TDesC8 const &, TChannelCreateInfo &, int)
+f801dc64 00e4 ExecHandler::ChannelRequest(DLogicalChannelBase *, int, void *, void *)
+</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 <------------- pointer to previous stack frame
+ 14 df 71 65
+ e0 db 01 f8 <------------- saved return address
+ c0 d9 01 f8 <------------- start of third stack frame
+</codeblock> <p>So <codeph>DLogicalDevice::ChannelCreate()</codeph> was called
+from <codeph>ExecHandler::ChannelCreate()</codeph>. </p> <p>Note that this
+mechanical way of walking the stack is valid only for debug functions. For
+release functions, it is necessary to study the code generated by the compiler. </p> <p>For
+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 }
+sub sp, #28
+add r7, sp, #12 /* R7 is THUMB frame pointer */
+</codeblock> <p>and this creates the following stack frame: </p> <fig id="GUID-85FAEE94-6D61-5D6B-84CB-6A9491927077">
+<image href="GUID-5CF162CA-4395-58AC-A318-2BF178276A57_d0e298826_href.png" placement="inline"/>
+</fig> <p>A call stack can mix ARM and THUMB frames. Odd return addresses
+are used for THUMB code and even ones for ARM code. </p> </section>
</conbody></concept>
\ No newline at end of file