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