diff -r bf9a2104bee6 -r 5d016a880824 debuggercdi/com.nokia.carbide.cpp.debug.crashdebugger/html/DebuggingInformation/CrashDebuggerCallStack.guide05.html --- a/debuggercdi/com.nokia.carbide.cpp.debug.crashdebugger/html/DebuggingInformation/CrashDebuggerCallStack.guide05.html Thu Feb 18 14:39:30 2010 -0600 +++ b/debuggercdi/com.nokia.carbide.cpp.debug.crashdebugger/html/DebuggingInformation/CrashDebuggerCallStack.guide05.html Thu Feb 18 15:11:20 2010 -0600 @@ -1,71 +1,71 @@ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" - "http://www.w3.org/TR/html4/loose.dtd"> - <html><head> - <title>Walking through the Call Stack</title> - <link href="sysdoc-eclipse.css" type="text/css" rel="stylesheet" > - <link href="sysdoc-eclipse.css" type="text/css" rel="stylesheet" > - <link href="../../book.css" type="text/css" rel="stylesheet" > -<div class="Head1"> - <h2>Walking through the Call Stack</h2> -</div> -<div> -<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> -<p class="CodeBlock">mov ip, sp<br>stmfd sp!, {fp, ip, lr, pc}<br>sub fp, ip, #4 /* FP now points to base of stack frame */<br>sub sp, sp, #16 /* space for local variables */</p> -<p>noting that: SP = R13, FP = R11, IP -= R12, LR = R14, and PC = R15.</p> -<p>This code creates the following stack frame:</p> -<div class="Figure"> -<p class="Image"><a name=""><img src="CrashDebuggerStackFrame-01.gif" alt="" border="0"></a></p> -</div> -<p>Looking at the example session listed in when -<a href="CrashDebuggerCallStack.guide.html" title="Examining the call stack / Tracing through the stack heuristically">tracing through the stack heuristically</a>. in which the crash is due to a panic, the FP value is the -R11 value; this is 0x6571de70. This gives us the innermost stack -frame:</p> -<p class="CodeBlock">6571de64: e8 de 71 65 <------------- pointer to previous stack frame <br> 74 de 71 65 <br> 74 fb 16 f8 <------------- Saved return address <br> 88 28 03 f8 <------------- FP points to this word</p> -<p>Looking up the saved return address, 0xf816fb74, in -the symbol file shows that the current function was called from -DDmaChannel::DoCreate().</p> -<p class="CodeBlock">f816fb50 0198 DDmaTestChannel::DoCreate(int, TDesC8 const *, TVersion const &)<br>f816fce8 007c DDmaTestChannel::~DDmaTestChannel(void)<br>f816fd64 0294 DDmaTestChannel::Request(int, void *, void *)</p> -<p>Using the pointer to the previous stack frame saved into the -current frame, we can decode the next frame:</p> -<p class="CodeBlock">6571ded4: 1c c4 03 64 <br> f8 02 00 64 <br> 10 df 71 65 <------------- pointer to previous stack frame <br> ec de 71 65 <br><br>6571dee4: 84 da 01 f8 <------------- saved return address <br> 5c fb 16 f8 <------------- start of second stack frame <br> 00 4e 40 00 <br> 00 00 00 00 </p> -<p>Looking up the saved return address, 0xf801da84, in -the symbol file shows that DDmaTestChannel::DoCreate() was called -from DLogicalDevice::ChannelCreate().</p> -<p class="CodeBlock">f801d9b4 00f8 DLogicalDevice::ChannelCreate(DLogicalChannelBase *&, TChannelCreateInfo &)<br>f801daac 01b8 ExecHandler::ChannelCreate(TDesC8 const &, TChannelCreateInfo &, int)<br>f801dc64 00e4 ExecHandler::ChannelRequest(DLogicalChannelBase *, int, void *, void *)</p> -<p>And here is the third stack frame:</p> -<p class="CodeBlock">6571df04: d4 df 71 65 <------------- pointer to previous stack frame <br> 14 df 71 65 <br> e0 db 01 f8 <------------- saved return address <br> c0 d9 01 f8 <------------- start of third stack frame </p> -<p>So DLogicalDevice::ChannelCreate() was called from -ExecHandler::ChannelCreate().</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> -<p class="CodeBlock">push { r7, lr }<br>sub sp, #28<br>add r7, sp, #12 /* R7 is THUMB frame pointer */</p> -<p>and this creates the following stack frame:</p> -<div class="Figure"> -<p class="Image"><a name=""><img src="CrashDebuggerStackFrame-02.gif" alt="" border="0"></a></p> -</div> -<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> - -</div> -<h5>Related tasks</h5> -<ul> - <li><a href="CrashDebuggerCallStack.guide02.html">General Points</a></li> - <li><a href="CrashDebuggerCallStack.guide03.html">Finding the Stack</a></li> - <li><a href="CrashDebuggerCallStack.guide04.html">Tracing through the Call Stack Heuristically</a></li> -</ul> -<div id="footer">Copyright © 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> - </body> - </html> +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" + "http://www.w3.org/TR/html4/loose.dtd"> + <html><head> + <title>Walking through the Call Stack</title> + <link href="sysdoc-eclipse.css" type="text/css" rel="stylesheet" > + <link href="sysdoc-eclipse.css" type="text/css" rel="stylesheet" > + <link href="../../book.css" type="text/css" rel="stylesheet" > +<div class="Head1"> + <h2>Walking through the Call Stack</h2> +</div> +<div> +<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> +<p class="CodeBlock">mov ip, sp<br>stmfd sp!, {fp, ip, lr, pc}<br>sub fp, ip, #4 /* FP now points to base of stack frame */<br>sub sp, sp, #16 /* space for local variables */</p> +<p>noting that: SP = R13, FP = R11, IP += R12, LR = R14, and PC = R15.</p> +<p>This code creates the following stack frame:</p> +<div class="Figure"> +<p class="Image"><a name=""><img src="CrashDebuggerStackFrame-01.gif" alt="" border="0"></a></p> +</div> +<p>Looking at the example session listed in when +<a href="CrashDebuggerCallStack.guide.html" title="Examining the call stack / Tracing through the stack heuristically">tracing through the stack heuristically</a>. in which the crash is due to a panic, the FP value is the +R11 value; this is 0x6571de70. This gives us the innermost stack +frame:</p> +<p class="CodeBlock">6571de64: e8 de 71 65 <------------- pointer to previous stack frame <br> 74 de 71 65 <br> 74 fb 16 f8 <------------- Saved return address <br> 88 28 03 f8 <------------- FP points to this word</p> +<p>Looking up the saved return address, 0xf816fb74, in +the symbol file shows that the current function was called from +DDmaChannel::DoCreate().</p> +<p class="CodeBlock">f816fb50 0198 DDmaTestChannel::DoCreate(int, TDesC8 const *, TVersion const &)<br>f816fce8 007c DDmaTestChannel::~DDmaTestChannel(void)<br>f816fd64 0294 DDmaTestChannel::Request(int, void *, void *)</p> +<p>Using the pointer to the previous stack frame saved into the +current frame, we can decode the next frame:</p> +<p class="CodeBlock">6571ded4: 1c c4 03 64 <br> f8 02 00 64 <br> 10 df 71 65 <------------- pointer to previous stack frame <br> ec de 71 65 <br><br>6571dee4: 84 da 01 f8 <------------- saved return address <br> 5c fb 16 f8 <------------- start of second stack frame <br> 00 4e 40 00 <br> 00 00 00 00 </p> +<p>Looking up the saved return address, 0xf801da84, in +the symbol file shows that DDmaTestChannel::DoCreate() was called +from DLogicalDevice::ChannelCreate().</p> +<p class="CodeBlock">f801d9b4 00f8 DLogicalDevice::ChannelCreate(DLogicalChannelBase *&, TChannelCreateInfo &)<br>f801daac 01b8 ExecHandler::ChannelCreate(TDesC8 const &, TChannelCreateInfo &, int)<br>f801dc64 00e4 ExecHandler::ChannelRequest(DLogicalChannelBase *, int, void *, void *)</p> +<p>And here is the third stack frame:</p> +<p class="CodeBlock">6571df04: d4 df 71 65 <------------- pointer to previous stack frame <br> 14 df 71 65 <br> e0 db 01 f8 <------------- saved return address <br> c0 d9 01 f8 <------------- start of third stack frame </p> +<p>So DLogicalDevice::ChannelCreate() was called from +ExecHandler::ChannelCreate().</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> +<p class="CodeBlock">push { r7, lr }<br>sub sp, #28<br>add r7, sp, #12 /* R7 is THUMB frame pointer */</p> +<p>and this creates the following stack frame:</p> +<div class="Figure"> +<p class="Image"><a name=""><img src="CrashDebuggerStackFrame-02.gif" alt="" border="0"></a></p> +</div> +<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> + +</div> +<h5>Related tasks</h5> +<ul> + <li><a href="CrashDebuggerCallStack.guide02.html">General Points</a></li> + <li><a href="CrashDebuggerCallStack.guide03.html">Finding the Stack</a></li> + <li><a href="CrashDebuggerCallStack.guide04.html">Tracing through the Call Stack Heuristically</a></li> +</ul> +<div id="footer">Copyright © 2010 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> + </body> + </html> \ No newline at end of file