Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

Tail-Call-Frames.html 11KB

vor 3 Jahren
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
  2. <html>
  3. <!-- Copyright (C) 1988-2020 Free Software Foundation, Inc.
  4. Permission is granted to copy, distribute and/or modify this document
  5. under the terms of the GNU Free Documentation License, Version 1.3 or
  6. any later version published by the Free Software Foundation; with the
  7. Invariant Sections being "Free Software" and "Free Software Needs
  8. Free Documentation", with the Front-Cover Texts being "A GNU Manual,"
  9. and with the Back-Cover Texts as in (a) below.
  10. (a) The FSF's Back-Cover Text is: "You are free to copy and modify
  11. this GNU Manual. Buying copies from GNU Press supports the FSF in
  12. developing GNU and promoting software freedom." -->
  13. <!-- Created by GNU Texinfo 6.5, http://www.gnu.org/software/texinfo/ -->
  14. <head>
  15. <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  16. <title>Tail Call Frames (Debugging with GDB)</title>
  17. <meta name="description" content="Tail Call Frames (Debugging with GDB)">
  18. <meta name="keywords" content="Tail Call Frames (Debugging with GDB)">
  19. <meta name="resource-type" content="document">
  20. <meta name="distribution" content="global">
  21. <meta name="Generator" content="makeinfo">
  22. <link href="index.html#Top" rel="start" title="Top">
  23. <link href="Concept-Index.html#Concept-Index" rel="index" title="Concept Index">
  24. <link href="index.html#SEC_Contents" rel="contents" title="Table of Contents">
  25. <link href="Optimized-Code.html#Optimized-Code" rel="up" title="Optimized Code">
  26. <link href="Macros.html#Macros" rel="next" title="Macros">
  27. <link href="Inline-Functions.html#Inline-Functions" rel="prev" title="Inline Functions">
  28. <style type="text/css">
  29. <!--
  30. a.summary-letter {text-decoration: none}
  31. blockquote.indentedblock {margin-right: 0em}
  32. blockquote.smallindentedblock {margin-right: 0em; font-size: smaller}
  33. blockquote.smallquotation {font-size: smaller}
  34. div.display {margin-left: 3.2em}
  35. div.example {margin-left: 3.2em}
  36. div.lisp {margin-left: 3.2em}
  37. div.smalldisplay {margin-left: 3.2em}
  38. div.smallexample {margin-left: 3.2em}
  39. div.smalllisp {margin-left: 3.2em}
  40. kbd {font-style: oblique}
  41. pre.display {font-family: inherit}
  42. pre.format {font-family: inherit}
  43. pre.menu-comment {font-family: serif}
  44. pre.menu-preformatted {font-family: serif}
  45. pre.smalldisplay {font-family: inherit; font-size: smaller}
  46. pre.smallexample {font-size: smaller}
  47. pre.smallformat {font-family: inherit; font-size: smaller}
  48. pre.smalllisp {font-size: smaller}
  49. span.nolinebreak {white-space: nowrap}
  50. span.roman {font-family: initial; font-weight: normal}
  51. span.sansserif {font-family: sans-serif; font-weight: normal}
  52. ul.no-bullet {list-style: none}
  53. -->
  54. </style>
  55. </head>
  56. <body lang="en">
  57. <a name="Tail-Call-Frames"></a>
  58. <div class="header">
  59. <p>
  60. Previous: <a href="Inline-Functions.html#Inline-Functions" accesskey="p" rel="prev">Inline Functions</a>, Up: <a href="Optimized-Code.html#Optimized-Code" accesskey="u" rel="up">Optimized Code</a> &nbsp; [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Concept-Index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
  61. </div>
  62. <hr>
  63. <a name="Tail-Call-Frames-1"></a>
  64. <h3 class="section">11.2 Tail Call Frames</h3>
  65. <a name="index-tail-call-frames_002c-debugging"></a>
  66. <p>Function <code>B</code> can call function <code>C</code> in its very last statement. In
  67. unoptimized compilation the call of <code>C</code> is immediately followed by return
  68. instruction at the end of <code>B</code> code. Optimizing compiler may replace the
  69. call and return in function <code>B</code> into one jump to function <code>C</code>
  70. instead. Such use of a jump instruction is called <em>tail call</em>.
  71. </p>
  72. <p>During execution of function <code>C</code>, there will be no indication in the
  73. function call stack frames that it was tail-called from <code>B</code>. If function
  74. <code>A</code> regularly calls function <code>B</code> which tail-calls function <code>C</code>,
  75. then <small>GDB</small> will see <code>A</code> as the caller of <code>C</code>. However, in
  76. some cases <small>GDB</small> can determine that <code>C</code> was tail-called from
  77. <code>B</code>, and it will then create fictitious call frame for that, with the
  78. return address set up as if <code>B</code> called <code>C</code> normally.
  79. </p>
  80. <p>This functionality is currently supported only by DWARF 2 debugging format and
  81. the compiler has to produce &lsquo;<samp>DW_TAG_call_site</samp>&rsquo; tags. With
  82. <small>GCC</small>, you need to specify <samp>-O -g</samp> during compilation, to get
  83. this information.
  84. </p>
  85. <p><kbd>info frame</kbd> command (see <a href="Frame-Info.html#Frame-Info">Frame Info</a>) will indicate the tail call frame
  86. kind by text <code>tail call frame</code> such as in this sample <small>GDB</small> output:
  87. </p>
  88. <div class="smallexample">
  89. <pre class="smallexample">(gdb) x/i $pc - 2
  90. 0x40066b &lt;b(int, double)+11&gt;: jmp 0x400640 &lt;c(int, double)&gt;
  91. (gdb) info frame
  92. Stack level 1, frame at 0x7fffffffda30:
  93. rip = 0x40066d in b (amd64-entry-value.cc:59); saved rip 0x4004c5
  94. tail call frame, caller of frame at 0x7fffffffda30
  95. source language c++.
  96. Arglist at unknown address.
  97. Locals at unknown address, Previous frame's sp is 0x7fffffffda30
  98. </pre></div>
  99. <p>The detection of all the possible code path executions can find them ambiguous.
  100. There is no execution history stored (possible <a href="Reverse-Execution.html#Reverse-Execution">Reverse Execution</a> is never
  101. used for this purpose) and the last known caller could have reached the known
  102. callee by multiple different jump sequences. In such case <small>GDB</small> still
  103. tries to show at least all the unambiguous top tail callers and all the
  104. unambiguous bottom tail calees, if any.
  105. </p>
  106. <dl compact="compact">
  107. <dd><a name="set-debug-entry_002dvalues"></a></dd>
  108. <dt><code>set debug entry-values</code></dt>
  109. <dd><a name="index-set-debug-entry_002dvalues"></a>
  110. <p>When set to on, enables printing of analysis messages for both frame argument
  111. values at function entry and tail calls. It will show all the possible valid
  112. tail calls code paths it has considered. It will also print the intersection
  113. of them with the final unambiguous (possibly partial or even empty) code path
  114. result.
  115. </p>
  116. </dd>
  117. <dt><code>show debug entry-values</code></dt>
  118. <dd><a name="index-show-debug-entry_002dvalues"></a>
  119. <p>Show the current state of analysis messages printing for both frame argument
  120. values at function entry and tail calls.
  121. </p></dd>
  122. </dl>
  123. <p>The analysis messages for tail calls can for example show why the virtual tail
  124. call frame for function <code>c</code> has not been recognized (due to the indirect
  125. reference by variable <code>x</code>):
  126. </p>
  127. <div class="smallexample">
  128. <pre class="smallexample">static void __attribute__((noinline, noclone)) c (void);
  129. void (*x) (void) = c;
  130. static void __attribute__((noinline, noclone)) a (void) { x++; }
  131. static void __attribute__((noinline, noclone)) c (void) { a (); }
  132. int main (void) { x (); return 0; }
  133. Breakpoint 1, DW_OP_entry_value resolving cannot find
  134. DW_TAG_call_site 0x40039a in main
  135. a () at t.c:3
  136. 3 static void __attribute__((noinline, noclone)) a (void) { x++; }
  137. (gdb) bt
  138. #0 a () at t.c:3
  139. #1 0x000000000040039a in main () at t.c:5
  140. </pre></div>
  141. <p>Another possibility is an ambiguous virtual tail call frames resolution:
  142. </p>
  143. <div class="smallexample">
  144. <pre class="smallexample">int i;
  145. static void __attribute__((noinline, noclone)) f (void) { i++; }
  146. static void __attribute__((noinline, noclone)) e (void) { f (); }
  147. static void __attribute__((noinline, noclone)) d (void) { f (); }
  148. static void __attribute__((noinline, noclone)) c (void) { d (); }
  149. static void __attribute__((noinline, noclone)) b (void)
  150. { if (i) c (); else e (); }
  151. static void __attribute__((noinline, noclone)) a (void) { b (); }
  152. int main (void) { a (); return 0; }
  153. tailcall: initial: 0x4004d2(a) 0x4004ce(b) 0x4004b2(c) 0x4004a2(d)
  154. tailcall: compare: 0x4004d2(a) 0x4004cc(b) 0x400492(e)
  155. tailcall: reduced: 0x4004d2(a) |
  156. (gdb) bt
  157. #0 f () at t.c:2
  158. #1 0x00000000004004d2 in a () at t.c:8
  159. #2 0x0000000000400395 in main () at t.c:9
  160. </pre></div>
  161. <p>Frames #0 and #2 are real, #1 is a virtual tail call frame.
  162. The code can have possible execution paths <code>main&rarr;a&rarr;b&rarr;c&rarr;d&rarr;f</code> or
  163. <code>main&rarr;a&rarr;b&rarr;e&rarr;f</code>, <small>GDB</small> cannot find which one from the inferior state.
  164. </p>
  165. <p><code>initial:</code> state shows some random possible calling sequence <small>GDB</small>
  166. has found. It then finds another possible calling sequence - that one is
  167. prefixed by <code>compare:</code>. The non-ambiguous intersection of these two is
  168. printed as the <code>reduced:</code> calling sequence. That one could have many
  169. further <code>compare:</code> and <code>reduced:</code> statements as long as there remain
  170. any non-ambiguous sequence entries.
  171. </p>
  172. <p>For the frame of function <code>b</code> in both cases there are different possible
  173. <code>$pc</code> values (<code>0x4004cc</code> or <code>0x4004ce</code>), therefore this frame is
  174. also ambiguous. The only non-ambiguous frame is the one for function <code>a</code>,
  175. therefore this one is displayed to the user while the ambiguous frames are
  176. omitted.
  177. </p>
  178. <p>There can be also reasons why printing of frame argument values at function
  179. entry may fail:
  180. </p>
  181. <div class="smallexample">
  182. <pre class="smallexample">int v;
  183. static void __attribute__((noinline, noclone)) c (int i) { v++; }
  184. static void __attribute__((noinline, noclone)) a (int i);
  185. static void __attribute__((noinline, noclone)) b (int i) { a (i); }
  186. static void __attribute__((noinline, noclone)) a (int i)
  187. { if (i) b (i - 1); else c (0); }
  188. int main (void) { a (5); return 0; }
  189. (gdb) bt
  190. #0 c (i=i@entry=0) at t.c:2
  191. #1 0x0000000000400428 in a (DW_OP_entry_value resolving has found
  192. function &quot;a&quot; at 0x400420 can call itself via tail calls
  193. i=&lt;optimized out&gt;) at t.c:6
  194. #2 0x000000000040036e in main () at t.c:7
  195. </pre></div>
  196. <p><small>GDB</small> cannot find out from the inferior state if and how many times did
  197. function <code>a</code> call itself (via function <code>b</code>) as these calls would be
  198. tail calls. Such tail calls would modify the <code>i</code> variable, therefore
  199. <small>GDB</small> cannot be sure the value it knows would be right - <small>GDB</small>
  200. prints <code>&lt;optimized out&gt;</code> instead.
  201. </p>
  202. <hr>
  203. <div class="header">
  204. <p>
  205. Previous: <a href="Inline-Functions.html#Inline-Functions" accesskey="p" rel="prev">Inline Functions</a>, Up: <a href="Optimized-Code.html#Optimized-Code" accesskey="u" rel="up">Optimized Code</a> &nbsp; [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Concept-Index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
  206. </div>
  207. </body>
  208. </html>