171 the saved return addresses from the calls to <codeph>X()</codeph> and <codeph>Y()</codeph> are |
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 |
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 |
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>) |
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"> |
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_d0e298551_href.png" placement="inline"/> |
176 <image href="GUID-A328F9E3-7D91-594A-A589-E8CE5FA9227A_d0e296153_href.png" placement="inline"/> |
177 </fig> </li> |
177 </fig> </li> |
178 </ul> <p>If you want to trace applications loaded into RAM, then stack tracing |
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 |
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 |
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 |
181 end and moves 'down' towards the lower address end. This means that values |
338 sub fp, ip, #4 /* FP now points to base of stack frame */ |
338 sub fp, ip, #4 /* FP now points to base of stack frame */ |
339 sub sp, sp, #16 /* space for local variables */ |
339 sub sp, sp, #16 /* space for local variables */ |
340 </codeblock> <p>noting that: <codeph>SP = R13</codeph>, <codeph>FP = R11</codeph>, <codeph>IP |
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 |
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"> |
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_d0e298749_href.png" placement="inline"/> |
343 <image href="GUID-F12437C5-BD96-5B43-AD76-614CFAB104D2_d0e296351_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 |
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>. |
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 <------------- pointer to previous stack frame |
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 <------------- pointer to previous stack frame |
347 74 de 71 65 |
347 74 de 71 65 |
348 74 fb 16 f8 <------------- Saved return address |
348 74 fb 16 f8 <------------- Saved return address |
376 release functions, it is necessary to study the code generated by the compiler. </p> <p>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 } |
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 |
378 sub sp, #28 |
379 add r7, sp, #12 /* R7 is THUMB frame pointer */ |
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"> |
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_d0e298826_href.png" placement="inline"/> |
381 <image href="GUID-5CF162CA-4395-58AC-A318-2BF178276A57_d0e296428_href.png" placement="inline"/> |
382 </fig> <p>A call stack can mix ARM and THUMB frames. Odd return addresses |
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> |
383 are used for THUMB code and even ones for ARM code. </p> </section> |
384 </conbody></concept> |
384 </conbody></concept> |