diff mbox

[v2,3/3] btrace, frame: fix crash in get_frame_type

Message ID A78C989F6D9628469189715575E55B233326016F@IRSMSX104.ger.corp.intel.com
State New
Headers show

Commit Message

Metzger, Markus T Feb. 10, 2016, 3:02 p.m. UTC
> -----Original Message-----
> From: Metzger, Markus T
> Sent: Wednesday, February 10, 2016 11:29 AM
> To: Pedro Alves <palves@redhat.com>
> Cc: gdb-patches@sourceware.org
> Subject: RE: [PATCH v2 3/3] btrace, frame: fix crash in get_frame_type


> > So, what would break if we internal_error'ed in
> > frame_unwind_caller_arch/pc instead or normal error, in the case that
> > there's no non-artificial frame?
> 
> Likely nothing.  The case of only-artificial-frames is not covered by the test
> suite.  I'm not sure it is even possible during live debug (ignoring the
> discussion about get_prev_frame_always).
> 
> The changes were not motivated by fails but by my attempt to make the
> callers of skip_artificial_frames handle the now-possible NULL return
> gracefully.
> 
> I ran the btrace suite including the new tests I added to cover the record
> btrace tailcall-only-frames case and they pass.  I'm running the full test suite
> now.

No new fails there, as well (64-bit IA).

I added a comment based on your statement that frame_unwind_caller_xxx
callers should check frame_unwind_caller_id and assert that skip_artificial_frames
does not return NULL.

Info frame doesn't crash.

	(gdb) info frame
	Stack level 0, frame at 0x0:
	 rip = 0x4005b0 in bar (tailcall-only.c:29); saved rip = 0x4005c2
	 called by frame at 0x0
	 source 	language c.
	 Arglist at unknown address.
	 Locals at unknown address,Registers are not available in btrace record history

This is from a tailcall-only frame stack in replay mode using the tailcall-only test.
The real caller has not been recorded.

The output isn't very helpful for record btrace since we don't record register and
memory changes.

Here's the patch:

commit a9ba851aa9a126da90f12eaa1788f2d271530535
Author: Markus Metzger <markus.t.metzger@intel.com>
Date:   Tue Jan 26 14:58:44 2016 +0100

    btrace, frame: fix crash in get_frame_type
    
    In skip_artificial_frames we repeatedly call get_prev_frame_always until we get
    a non-inline and non-tailcall frame assuming that there must be such a frame
    eventually.
    
    For record targets, however, we may have a frame chain that consists only of
    artificial frames.  This leads to a crash in get_frame_type when dereferencing a
    NULL frame pointer.
    
    Change skip_artificial_frames and skip_tailcall_frames to return NULL in such a
    case and modify each caller to cope with a NULL return.
    
    In frame_unwind_caller_pc and frame_unwind_caller_arch, we simply assert that
    the returned value is not NULL.  Their caller was supposed to check
    frame_unwind_caller_id before calling those functions.
    
    In other cases, we thrown an error.
    
    In infcmd further move the skip_tailcall_frames call to the forward-stepping
    case since we don't need a frame for reverse execution and we don't want to fail
    because of that.  Reverse-finish does make sense for a tailcall frame.
    
    2016-02-10  Markus Metzger  <markus.t.metzger@intel.com>
    
    gdb/
    	* frame.h (skip_tailcall_frames): Update comment.
    	* frame.c (skip_artificial_frames, skip_tailcall_frames): Return NULL
    	if only	artificial frames are found.  Update comment.
    	(frame_unwind_caller_id): Handle NULL return.
    	(frame_unwind_caller_pc, frame_unwind_caller_arch): Assert that
    	skip_artificial_frames does not return NULL.
    	(frame_pop): Add an error if only tailcall frames are found.
    	* infcmd.c (finish_command): Move skip_tailcall_frames call into forward-
    	execution case.  Add an error if only tailcall frames are found.
    
    testsuite/
    	* gdb.btrace/tailcall-only.exp: New.
    	* gdb.btrace/tailcall-only.c: New.
    	* gdb.btrace/x86_64-tailcall-only.S: New.
    	* gdb.btrace/i686-tailcall-only.S: New.


Intel Deutschland GmbH
Registered Address: Am Campeon 10-12, 85579 Neubiberg, Germany
Tel: +49 89 99 8853-0, www.intel.de
Managing Directors: Christin Eisenschmid, Christian Lamprechter
Chairperson of the Supervisory Board: Nicole Lau
Registered Office: Munich
Commercial Register: Amtsgericht Muenchen HRB 186928

Comments

Pedro Alves Feb. 10, 2016, 3:34 p.m. UTC | #1
On 02/10/2016 03:02 PM, Metzger, Markus T wrote:

> No new fails there, as well (64-bit IA).
> 
> I added a comment based on your statement that frame_unwind_caller_xxx
> callers should check frame_unwind_caller_id and assert that skip_artificial_frames
> does not return NULL.
> 
> Info frame doesn't crash.
> 
> 	(gdb) info frame
> 	Stack level 0, frame at 0x0:
> 	 rip = 0x4005b0 in bar (tailcall-only.c:29); saved rip = 0x4005c2
> 	 called by frame at 0x0
         ^^^^^^^^^^^^^^^

> 	 source 	language c.
> 	 Arglist at unknown address.
> 	 Locals at unknown address,Registers are not available in btrace record history
> 
> This is from a tailcall-only frame stack in replay mode using the tailcall-only test.
> The real caller has not been recorded.

Not sure how you got that, since "called by frame" seems to indicates that
the frame was not TAILCALL_FRAME:

  else if (get_frame_type (fi) == TAILCALL_FRAME)
    puts_filtered (" tail call frame");
  else if (get_frame_type (fi) == INLINE_FRAME)
    printf_filtered (" inlined into frame %d",
		     frame_relative_level (get_prev_frame (fi)));
  else
    {
      printf_filtered (" called by frame at ");
      fputs_filtered (paddress (gdbarch, get_frame_base (calling_frame_info)),
		      gdb_stdout);
    }


> 
> The output isn't very helpful for record btrace since we don't record register and
> memory changes.


So I'm mostly OK with the patch now, but I think you should dig a bit more
into the "info frame" output, since I think you _will_ internal error with a
TAILCALL_FRAME.

My remaining issue is now with the user-visible strings.

> @@ -985,6 +1007,10 @@ frame_pop (struct frame_info *this_frame)
>       entering THISFRAME.  */
>    prev_frame = skip_tailcall_frames (prev_frame);
>  
> +  /* We cannot pop tailcall frames.  */
> +  if (prev_frame == NULL)
> +    error (_("Cannot pop a tailcall frame."));
> +

I find this confusing, from a user perspective.  AFAIK, you can pop a tailcall
frame; what you can't do is pop when you don't know anything about the frame
that started the tail calling.  How about:

  if (prev_frame == NULL)
    error (_("Cannot return: tailcall caller frame not found."));

s/pop/return/, as "pop" is an internal implementation detail.

(I suggest also dropping the redundant comment.)


> +    {
> +      /* Ignore TAILCALL_FRAME type frames, they were executed already before
> +	 entering THISFRAME.  */
> +      frame = skip_tailcall_frames (frame);
> +
> +      if (frame == NULL)
> +	error (_("\"finish\" not meaningful for tailcall frames."));
> +

  if (frame == NULL)
    error (_("Cannot finish: tailcall caller frame not found."));


(I'd also be fine with dropping the "Cannot xxx:" part to make
the error messages the same in both cases.)


> +      finish_forward (sm, frame);
> +    }
>  }

Thanks,
Pedro Alves
Metzger, Markus T Feb. 11, 2016, 9:51 a.m. UTC | #2
> -----Original Message-----
> From: Pedro Alves [mailto:palves@redhat.com]
> Sent: Wednesday, February 10, 2016 4:34 PM
> To: Metzger, Markus T <markus.t.metzger@intel.com>
> Cc: gdb-patches@sourceware.org
> Subject: Re: [PATCH v2 3/3] btrace, frame: fix crash in get_frame_type
> 
> On 02/10/2016 03:02 PM, Metzger, Markus T wrote:
> 
> > No new fails there, as well (64-bit IA).
> >
> > I added a comment based on your statement that
> frame_unwind_caller_xxx
> > callers should check frame_unwind_caller_id and assert that
> > skip_artificial_frames does not return NULL.
> >
> > Info frame doesn't crash.
> >
> > 	(gdb) info frame
> > 	Stack level 0, frame at 0x0:
> > 	 rip = 0x4005b0 in bar (tailcall-only.c:29); saved rip = 0x4005c2
> > 	 called by frame at 0x0
>          ^^^^^^^^^^^^^^^
> 
> > 	 source 	language c.
> > 	 Arglist at unknown address.
> > 	 Locals at unknown address,Registers are not available in btrace
> > record history
> >
> > This is from a tailcall-only frame stack in replay mode using the tailcall-only
> test.
> > The real caller has not been recorded.
> 
> Not sure how you got that, since "called by frame" seems to indicates that
> the frame was not TAILCALL_FRAME:

That's the sentinel frame.  I forgot to "up".  Now it crashes;-)

There are other cases where frame_unwind_caller_xxx callers don't check
frame_unwind_caller_id:

	gdb/mips-linux-tdep.c
	gdb/glibc-tdep.c
	gdb/obsd-tdep.c
	gdb/tic6x-linux-tdep.c
	gdb/sol2-tdep.c
	gdb/nios2-linux-tdep.c

They're used for skipping syscalls and ld.so.

The latter should be called via gdbarch_skip_solib_resolver (gdbarch, stop_pc)
from infrun.c.

Who is supposed to do the check in those cases?  Maybe they are already OK?

Regards,
Markus.
Intel Deutschland GmbH
Registered Address: Am Campeon 10-12, 85579 Neubiberg, Germany
Tel: +49 89 99 8853-0, www.intel.de
Managing Directors: Christin Eisenschmid, Christian Lamprechter
Chairperson of the Supervisory Board: Nicole Lau
Registered Office: Munich
Commercial Register: Amtsgericht Muenchen HRB 186928
Pedro Alves Feb. 11, 2016, 1:38 p.m. UTC | #3
On 02/11/2016 09:51 AM, Metzger, Markus T wrote:
>> -----Original Message-----
>> From: Pedro Alves [mailto:palves@redhat.com]
>> Sent: Wednesday, February 10, 2016 4:34 PM
>> To: Metzger, Markus T <markus.t.metzger@intel.com>
>> Cc: gdb-patches@sourceware.org
>> Subject: Re: [PATCH v2 3/3] btrace, frame: fix crash in get_frame_type
>>
>> On 02/10/2016 03:02 PM, Metzger, Markus T wrote:
>>
>>> No new fails there, as well (64-bit IA).
>>>
>>> I added a comment based on your statement that
>> frame_unwind_caller_xxx
>>> callers should check frame_unwind_caller_id and assert that
>>> skip_artificial_frames does not return NULL.
>>>
>>> Info frame doesn't crash.
>>>
>>> 	(gdb) info frame
>>> 	Stack level 0, frame at 0x0:
>>> 	 rip = 0x4005b0 in bar (tailcall-only.c:29); saved rip = 0x4005c2
>>> 	 called by frame at 0x0
>>          ^^^^^^^^^^^^^^^
>>
>>> 	 source 	language c.
>>> 	 Arglist at unknown address.
>>> 	 Locals at unknown address,Registers are not available in btrace
>>> record history
>>>
>>> This is from a tailcall-only frame stack in replay mode using the tailcall-only
>> test.
>>> The real caller has not been recorded.
>>
>> Not sure how you got that, since "called by frame" seems to indicates that
>> the frame was not TAILCALL_FRAME:
> 
> That's the sentinel frame.  I forgot to "up".  Now it crashes;-)
> 
> There are other cases where frame_unwind_caller_xxx callers don't check
> frame_unwind_caller_id:
> 
> 	gdb/mips-linux-tdep.c
> 	gdb/glibc-tdep.c
> 	gdb/obsd-tdep.c
> 	gdb/tic6x-linux-tdep.c
> 	gdb/sol2-tdep.c
> 	gdb/nios2-linux-tdep.c
> 
> They're used for skipping syscalls and ld.so.
> 
> The latter should be called via gdbarch_skip_solib_resolver (gdbarch, stop_pc)
> from infrun.c.
> 
> Who is supposed to do the check in those cases?  Maybe they are already OK?

In the syscall cases, we're trying to determine the next PC where to place a
breakpoint, in order to do a software single-step.  If we don't know where the
caller is, we can't single-step, so we should probably error out.  OTOH, if the
target_ops is record-like and we're single-stepping through the trace log,
we shouldn't be trying to use software single-step at all.  So I think those
are probably OK.

In the glibc_skip_solib_resolver case -- in theory, I guess it would be
possible to construct a branch trace that records a tailcall to _dl_fixup,
and that doesn't have any frame above that one?

If we don't know where the caller is, we can't skip the resolver
in one go, so best to do is probably to return 0, and let infrun's
stepping logic continue single-stepping.

Thanks,
Pedro Alves
diff mbox

Patch

diff --git a/gdb/frame.c b/gdb/frame.c
index b7832c7..9bb493e 100644
--- a/gdb/frame.c
+++ b/gdb/frame.c
@@ -420,7 +420,8 @@  fprint_frame (struct ui_file *file, struct frame_info *fi)
 
 /* Given FRAME, return the enclosing frame as found in real frames read-in from
    inferior memory.  Skip any previous frames which were made up by GDB.
-   Return the original frame if no immediate previous frames exist.  */
+   Return FRAME if FRAME is a non-artificial frame.
+   Return NULL if FRAME is the start of an artificial-only chain.  */
 
 static struct frame_info *
 skip_artificial_frames (struct frame_info *frame)
@@ -428,12 +429,17 @@  skip_artificial_frames (struct frame_info *frame)
   /* Note we use get_prev_frame_always, and not get_prev_frame.  The
      latter will truncate the frame chain, leading to this function
      unintentionally returning a null_frame_id (e.g., when the user
-     sets a backtrace limit).  This is safe, because as these frames
-     are made up by GDB, there must be a real frame in the chain
-     below.  */
+     sets a backtrace limit).
+
+     Note that for record targets we may get a frame chain that consists
+     of artificial frames only.  */
   while (get_frame_type (frame) == INLINE_FRAME
 	 || get_frame_type (frame) == TAILCALL_FRAME)
-    frame = get_prev_frame_always (frame);
+    {
+      frame = get_prev_frame_always (frame);
+      if (frame == NULL)
+	break;
+    }
 
   return frame;
 }
@@ -444,7 +450,13 @@  struct frame_info *
 skip_tailcall_frames (struct frame_info *frame)
 {
   while (get_frame_type (frame) == TAILCALL_FRAME)
-    frame = get_prev_frame (frame);
+    {
+      /* Note that for record targets we may get a frame chain that consists of
+	 tailcall frames only.  */
+      frame = get_prev_frame (frame);
+      if (frame == NULL)
+	break;
+    }
 
   return frame;
 }
@@ -507,6 +519,9 @@  frame_unwind_caller_id (struct frame_info *next_frame)
      requests the frame ID of "main()"s caller.  */
 
   next_frame = skip_artificial_frames (next_frame);
+  if (next_frame == NULL)
+    return null_frame_id;
+
   this_frame = get_prev_frame_always (next_frame);
   if (this_frame)
     return get_frame_id (skip_artificial_frames (this_frame));
@@ -880,7 +895,14 @@  frame_unwind_pc (struct frame_info *this_frame)
 CORE_ADDR
 frame_unwind_caller_pc (struct frame_info *this_frame)
 {
-  return frame_unwind_pc (skip_artificial_frames (this_frame));
+  this_frame = skip_artificial_frames (this_frame);
+
+  /* We must have a non-artificial frame.  The caller is supposed to check
+     the result of frame_unwind_caller_id (), which returns NULL_FRAME_ID
+     in this case.  */
+  gdb_assert (this_frame != NULL);
+
+  return frame_unwind_pc (this_frame);
 }
 
 int
@@ -985,6 +1007,10 @@  frame_pop (struct frame_info *this_frame)
      entering THISFRAME.  */
   prev_frame = skip_tailcall_frames (prev_frame);
 
+  /* We cannot pop tailcall frames.  */
+  if (prev_frame == NULL)
+    error (_("Cannot pop a tailcall frame."));
+
   /* Make a copy of all the register values unwound from this frame.
      Save them in a scratch buffer so that there isn't a race between
      trying to extract the old values from the current regcache while
@@ -2571,7 +2597,14 @@  frame_unwind_arch (struct frame_info *next_frame)
 struct gdbarch *
 frame_unwind_caller_arch (struct frame_info *next_frame)
 {
-  return frame_unwind_arch (skip_artificial_frames (next_frame));
+  next_frame = skip_artificial_frames (next_frame);
+
+  /* We must have a non-artificial frame.  The caller is supposed to check
+     the result of frame_unwind_caller_id (), which returns NULL_FRAME_ID
+     in this case.  */
+  gdb_assert (next_frame != NULL);
+
+  return frame_unwind_arch (next_frame);
 }
 
 /* Gets the language of FRAME.  */
diff --git a/gdb/frame.h b/gdb/frame.h
index 7e8b01e..8ee64f1 100644
--- a/gdb/frame.h
+++ b/gdb/frame.h
@@ -821,7 +821,8 @@  extern int frame_unwinder_is (struct frame_info *fi,
 extern enum language get_frame_language (struct frame_info *frame);
 
 /* Return the first non-tailcall frame above FRAME or FRAME if it is not a
-   tailcall frame.  */
+   tailcall frame.  Return NULL if FRAME is the start of a tailcall-only
+   chain.  */
 
 extern struct frame_info *skip_tailcall_frames (struct frame_info *frame);
 
diff --git a/gdb/infcmd.c b/gdb/infcmd.c
index 930dc61..938f8fa 100644
--- a/gdb/infcmd.c
+++ b/gdb/infcmd.c
@@ -2000,10 +2000,6 @@  finish_command (char *arg, int from_tty)
       return;
     }
 
-  /* Ignore TAILCALL_FRAME type frames, they were executed already before
-     entering THISFRAME.  */
-  frame = skip_tailcall_frames (frame);
-
   /* Find the function we will return from.  */
 
   sm->function = find_pc_function (get_frame_pc (get_selected_frame (NULL)));
@@ -2030,7 +2026,16 @@  finish_command (char *arg, int from_tty)
   if (execution_direction == EXEC_REVERSE)
     finish_backward (sm);
   else
-    finish_forward (sm, frame);
+    {
+      /* Ignore TAILCALL_FRAME type frames, they were executed already before
+	 entering THISFRAME.  */
+      frame = skip_tailcall_frames (frame);
+
+      if (frame == NULL)
+	error (_("\"finish\" not meaningful for tailcall frames."));
+
+      finish_forward (sm, frame);
+    }
 }
 

 
diff --git a/gdb/testsuite/gdb.btrace/i686-tailcall-only.S b/gdb/testsuite/gdb.btrace/i686-tailcall-only.S
new file mode 100644
index 0000000..a89f2f2
--- /dev/null
+++ b/gdb/testsuite/gdb.btrace/i686-tailcall-only.S
@@ -0,0 +1,447 @@ 
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2016 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+
+   This file has been generated using:
+   gcc -m32 -march=i686 -S -O2 -dA -g tailcall-only.c -o i686-tailcall-only.S
+ */
+
+	.file	"tailcall-only.c"
+	.text
+.Ltext0:
+	.p2align 4,,15
+	.type	bar_1, @function
+bar_1:
+.LFB0:
+	.file 1 "tailcall-only.c"
+	# tailcall-only.c:22
+	.loc 1 22 0
+	.cfi_startproc
+# BLOCK 2 freq:10000 seq:0
+# PRED: ENTRY [100.0%]  (FALLTHRU)
+	# tailcall-only.c:24
+	.loc 1 24 0
+	movl	$42, %eax
+# SUCC: EXIT [100.0%]
+	ret
+	.cfi_endproc
+.LFE0:
+	.size	bar_1, .-bar_1
+	.p2align 4,,15
+	.type	bar, @function
+bar:
+.LFB1:
+	# tailcall-only.c:28
+	.loc 1 28 0
+	.cfi_startproc
+# BLOCK 2 freq:10000 seq:0
+# PRED: ENTRY [100.0%]  (FALLTHRU)
+	# tailcall-only.c:29
+	.loc 1 29 0
+	jmp	bar_1
+# SUCC: EXIT [100.0%]  (ABNORMAL,SIBCALL)
+.LVL0:
+	.cfi_endproc
+.LFE1:
+	.size	bar, .-bar
+	.p2align 4,,15
+	.type	foo_1, @function
+foo_1:
+.LFB2:
+	# tailcall-only.c:34
+	.loc 1 34 0
+	.cfi_startproc
+# BLOCK 2 freq:10000 seq:0
+# PRED: ENTRY [100.0%]  (FALLTHRU)
+	# tailcall-only.c:35
+	.loc 1 35 0
+	jmp	bar
+# SUCC: EXIT [100.0%]  (ABNORMAL,SIBCALL)
+.LVL1:
+	.cfi_endproc
+.LFE2:
+	.size	foo_1, .-foo_1
+	.p2align 4,,15
+	.type	foo, @function
+foo:
+.LFB3:
+	# tailcall-only.c:40
+	.loc 1 40 0
+	.cfi_startproc
+# BLOCK 2 freq:10000 seq:0
+# PRED: ENTRY [100.0%]  (FALLTHRU)
+	# tailcall-only.c:41
+	.loc 1 41 0
+	jmp	foo_1
+# SUCC: EXIT [100.0%]  (ABNORMAL,SIBCALL)
+.LVL2:
+	.cfi_endproc
+.LFE3:
+	.size	foo, .-foo
+	.section	.text.startup,"ax",@progbits
+	.p2align 4,,15
+	.globl	main
+	.type	main, @function
+main:
+.LFB4:
+	# tailcall-only.c:46
+	.loc 1 46 0
+	.cfi_startproc
+# BLOCK 2 freq:10000 seq:0
+# PRED: ENTRY [100.0%]  (FALLTHRU)
+	# tailcall-only.c:49
+	.loc 1 49 0
+	call	foo
+.LVL3:
+	# tailcall-only.c:50
+	.loc 1 50 0
+	addl	$1, %eax
+.LVL4:
+# SUCC: EXIT [100.0%]
+	# tailcall-only.c:53
+	.loc 1 53 0
+	ret
+	.cfi_endproc
+.LFE4:
+	.size	main, .-main
+	.text
+.Letext0:
+	.section	.debug_info,"",@progbits
+.Ldebug_info0:
+	.long	0xd5	# Length of Compilation Unit Info
+	.value	0x4	# DWARF version number
+	.long	.Ldebug_abbrev0	# Offset Into Abbrev. Section
+	.byte	0x4	# Pointer Size (in bytes)
+	.uleb128 0x1	# (DIE (0xb) DW_TAG_compile_unit)
+	.long	.LASF1	# DW_AT_producer: "GNU C 4.8.3 20140911 (Red Hat 4.8.3-9) -m32 -march=i686 -g -O2"
+	.byte	0x1	# DW_AT_language
+	.long	.LASF2	# DW_AT_name: "tailcall-only.c"
+	.long	.LASF3	# DW_AT_comp_dir: ""
+	.long	.Ldebug_ranges0+0	# DW_AT_ranges
+	.long	0	# DW_AT_low_pc
+	.long	.Ldebug_line0	# DW_AT_stmt_list
+	.uleb128 0x2	# (DIE (0x25) DW_TAG_subprogram)
+	.long	.LASF4	# DW_AT_name: "bar_1"
+	.byte	0x1	# DW_AT_decl_file (tailcall-only.c)
+	.byte	0x15	# DW_AT_decl_line
+			# DW_AT_prototyped
+	.long	0x3a	# DW_AT_type
+	.long	.LFB0	# DW_AT_low_pc
+	.long	.LFE0-.LFB0	# DW_AT_high_pc
+	.uleb128 0x1	# DW_AT_frame_base
+	.byte	0x9c	# DW_OP_call_frame_cfa
+			# DW_AT_GNU_all_call_sites
+	.uleb128 0x3	# (DIE (0x3a) DW_TAG_base_type)
+	.byte	0x4	# DW_AT_byte_size
+	.byte	0x5	# DW_AT_encoding
+	.ascii "int\0"	# DW_AT_name
+	.uleb128 0x4	# (DIE (0x41) DW_TAG_subprogram)
+	.ascii "bar\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (tailcall-only.c)
+	.byte	0x1b	# DW_AT_decl_line
+			# DW_AT_prototyped
+	.long	0x3a	# DW_AT_type
+	.long	.LFB1	# DW_AT_low_pc
+	.long	.LFE1-.LFB1	# DW_AT_high_pc
+	.uleb128 0x1	# DW_AT_frame_base
+	.byte	0x9c	# DW_OP_call_frame_cfa
+			# DW_AT_GNU_all_call_sites
+	.long	0x64	# DW_AT_sibling
+	.uleb128 0x5	# (DIE (0x5a) DW_TAG_GNU_call_site)
+	.long	.LVL0	# DW_AT_low_pc
+			# DW_AT_GNU_tail_call
+	.long	0x25	# DW_AT_abstract_origin
+	.byte	0	# end of children of DIE 0x41
+	.uleb128 0x6	# (DIE (0x64) DW_TAG_subprogram)
+	.long	.LASF0	# DW_AT_name: "foo_1"
+	.byte	0x1	# DW_AT_decl_file (tailcall-only.c)
+	.byte	0x21	# DW_AT_decl_line
+			# DW_AT_prototyped
+	.long	0x3a	# DW_AT_type
+	.long	.LFB2	# DW_AT_low_pc
+	.long	.LFE2-.LFB2	# DW_AT_high_pc
+	.uleb128 0x1	# DW_AT_frame_base
+	.byte	0x9c	# DW_OP_call_frame_cfa
+			# DW_AT_GNU_all_call_sites
+	.long	0x87	# DW_AT_sibling
+	.uleb128 0x5	# (DIE (0x7d) DW_TAG_GNU_call_site)
+	.long	.LVL1	# DW_AT_low_pc
+			# DW_AT_GNU_tail_call
+	.long	0x41	# DW_AT_abstract_origin
+	.byte	0	# end of children of DIE 0x64
+	.uleb128 0x4	# (DIE (0x87) DW_TAG_subprogram)
+	.ascii "foo\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (tailcall-only.c)
+	.byte	0x27	# DW_AT_decl_line
+			# DW_AT_prototyped
+	.long	0x3a	# DW_AT_type
+	.long	.LFB3	# DW_AT_low_pc
+	.long	.LFE3-.LFB3	# DW_AT_high_pc
+	.uleb128 0x1	# DW_AT_frame_base
+	.byte	0x9c	# DW_OP_call_frame_cfa
+			# DW_AT_GNU_all_call_sites
+	.long	0xaa	# DW_AT_sibling
+	.uleb128 0x5	# (DIE (0xa0) DW_TAG_GNU_call_site)
+	.long	.LVL2	# DW_AT_low_pc
+			# DW_AT_GNU_tail_call
+	.long	0x64	# DW_AT_abstract_origin
+	.byte	0	# end of children of DIE 0x87
+	.uleb128 0x7	# (DIE (0xaa) DW_TAG_subprogram)
+			# DW_AT_external
+	.long	.LASF5	# DW_AT_name: "main"
+	.byte	0x1	# DW_AT_decl_file (tailcall-only.c)
+	.byte	0x2d	# DW_AT_decl_line
+			# DW_AT_prototyped
+	.long	0x3a	# DW_AT_type
+	.long	.LFB4	# DW_AT_low_pc
+	.long	.LFE4-.LFB4	# DW_AT_high_pc
+	.uleb128 0x1	# DW_AT_frame_base
+	.byte	0x9c	# DW_OP_call_frame_cfa
+			# DW_AT_GNU_all_call_sites
+	.uleb128 0x8	# (DIE (0xbf) DW_TAG_variable)
+	.long	.LASF6	# DW_AT_name: "answer"
+	.byte	0x1	# DW_AT_decl_file (tailcall-only.c)
+	.byte	0x2f	# DW_AT_decl_line
+	.long	0x3a	# DW_AT_type
+	.long	.LLST0	# DW_AT_location
+	.uleb128 0x9	# (DIE (0xce) DW_TAG_GNU_call_site)
+	.long	.LVL3	# DW_AT_low_pc
+	.long	0x87	# DW_AT_abstract_origin
+	.byte	0	# end of children of DIE 0xaa
+	.byte	0	# end of children of DIE 0xb
+	.section	.debug_abbrev,"",@progbits
+.Ldebug_abbrev0:
+	.uleb128 0x1	# (abbrev code)
+	.uleb128 0x11	# (TAG: DW_TAG_compile_unit)
+	.byte	0x1	# DW_children_yes
+	.uleb128 0x25	# (DW_AT_producer)
+	.uleb128 0xe	# (DW_FORM_strp)
+	.uleb128 0x13	# (DW_AT_language)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x3	# (DW_AT_name)
+	.uleb128 0xe	# (DW_FORM_strp)
+	.uleb128 0x1b	# (DW_AT_comp_dir)
+	.uleb128 0xe	# (DW_FORM_strp)
+	.uleb128 0x55	# (DW_AT_ranges)
+	.uleb128 0x17	# (DW_FORM_sec_offset)
+	.uleb128 0x11	# (DW_AT_low_pc)
+	.uleb128 0x1	# (DW_FORM_addr)
+	.uleb128 0x10	# (DW_AT_stmt_list)
+	.uleb128 0x17	# (DW_FORM_sec_offset)
+	.byte	0
+	.byte	0
+	.uleb128 0x2	# (abbrev code)
+	.uleb128 0x2e	# (TAG: DW_TAG_subprogram)
+	.byte	0	# DW_children_no
+	.uleb128 0x3	# (DW_AT_name)
+	.uleb128 0xe	# (DW_FORM_strp)
+	.uleb128 0x3a	# (DW_AT_decl_file)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x3b	# (DW_AT_decl_line)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x27	# (DW_AT_prototyped)
+	.uleb128 0x19	# (DW_FORM_flag_present)
+	.uleb128 0x49	# (DW_AT_type)
+	.uleb128 0x13	# (DW_FORM_ref4)
+	.uleb128 0x11	# (DW_AT_low_pc)
+	.uleb128 0x1	# (DW_FORM_addr)
+	.uleb128 0x12	# (DW_AT_high_pc)
+	.uleb128 0x6	# (DW_FORM_data4)
+	.uleb128 0x40	# (DW_AT_frame_base)
+	.uleb128 0x18	# (DW_FORM_exprloc)
+	.uleb128 0x2117	# (DW_AT_GNU_all_call_sites)
+	.uleb128 0x19	# (DW_FORM_flag_present)
+	.byte	0
+	.byte	0
+	.uleb128 0x3	# (abbrev code)
+	.uleb128 0x24	# (TAG: DW_TAG_base_type)
+	.byte	0	# DW_children_no
+	.uleb128 0xb	# (DW_AT_byte_size)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x3e	# (DW_AT_encoding)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x3	# (DW_AT_name)
+	.uleb128 0x8	# (DW_FORM_string)
+	.byte	0
+	.byte	0
+	.uleb128 0x4	# (abbrev code)
+	.uleb128 0x2e	# (TAG: DW_TAG_subprogram)
+	.byte	0x1	# DW_children_yes
+	.uleb128 0x3	# (DW_AT_name)
+	.uleb128 0x8	# (DW_FORM_string)
+	.uleb128 0x3a	# (DW_AT_decl_file)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x3b	# (DW_AT_decl_line)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x27	# (DW_AT_prototyped)
+	.uleb128 0x19	# (DW_FORM_flag_present)
+	.uleb128 0x49	# (DW_AT_type)
+	.uleb128 0x13	# (DW_FORM_ref4)
+	.uleb128 0x11	# (DW_AT_low_pc)
+	.uleb128 0x1	# (DW_FORM_addr)
+	.uleb128 0x12	# (DW_AT_high_pc)
+	.uleb128 0x6	# (DW_FORM_data4)
+	.uleb128 0x40	# (DW_AT_frame_base)
+	.uleb128 0x18	# (DW_FORM_exprloc)
+	.uleb128 0x2117	# (DW_AT_GNU_all_call_sites)
+	.uleb128 0x19	# (DW_FORM_flag_present)
+	.uleb128 0x1	# (DW_AT_sibling)
+	.uleb128 0x13	# (DW_FORM_ref4)
+	.byte	0
+	.byte	0
+	.uleb128 0x5	# (abbrev code)
+	.uleb128 0x4109	# (TAG: DW_TAG_GNU_call_site)
+	.byte	0	# DW_children_no
+	.uleb128 0x11	# (DW_AT_low_pc)
+	.uleb128 0x1	# (DW_FORM_addr)
+	.uleb128 0x2115	# (DW_AT_GNU_tail_call)
+	.uleb128 0x19	# (DW_FORM_flag_present)
+	.uleb128 0x31	# (DW_AT_abstract_origin)
+	.uleb128 0x13	# (DW_FORM_ref4)
+	.byte	0
+	.byte	0
+	.uleb128 0x6	# (abbrev code)
+	.uleb128 0x2e	# (TAG: DW_TAG_subprogram)
+	.byte	0x1	# DW_children_yes
+	.uleb128 0x3	# (DW_AT_name)
+	.uleb128 0xe	# (DW_FORM_strp)
+	.uleb128 0x3a	# (DW_AT_decl_file)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x3b	# (DW_AT_decl_line)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x27	# (DW_AT_prototyped)
+	.uleb128 0x19	# (DW_FORM_flag_present)
+	.uleb128 0x49	# (DW_AT_type)
+	.uleb128 0x13	# (DW_FORM_ref4)
+	.uleb128 0x11	# (DW_AT_low_pc)
+	.uleb128 0x1	# (DW_FORM_addr)
+	.uleb128 0x12	# (DW_AT_high_pc)
+	.uleb128 0x6	# (DW_FORM_data4)
+	.uleb128 0x40	# (DW_AT_frame_base)
+	.uleb128 0x18	# (DW_FORM_exprloc)
+	.uleb128 0x2117	# (DW_AT_GNU_all_call_sites)
+	.uleb128 0x19	# (DW_FORM_flag_present)
+	.uleb128 0x1	# (DW_AT_sibling)
+	.uleb128 0x13	# (DW_FORM_ref4)
+	.byte	0
+	.byte	0
+	.uleb128 0x7	# (abbrev code)
+	.uleb128 0x2e	# (TAG: DW_TAG_subprogram)
+	.byte	0x1	# DW_children_yes
+	.uleb128 0x3f	# (DW_AT_external)
+	.uleb128 0x19	# (DW_FORM_flag_present)
+	.uleb128 0x3	# (DW_AT_name)
+	.uleb128 0xe	# (DW_FORM_strp)
+	.uleb128 0x3a	# (DW_AT_decl_file)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x3b	# (DW_AT_decl_line)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x27	# (DW_AT_prototyped)
+	.uleb128 0x19	# (DW_FORM_flag_present)
+	.uleb128 0x49	# (DW_AT_type)
+	.uleb128 0x13	# (DW_FORM_ref4)
+	.uleb128 0x11	# (DW_AT_low_pc)
+	.uleb128 0x1	# (DW_FORM_addr)
+	.uleb128 0x12	# (DW_AT_high_pc)
+	.uleb128 0x6	# (DW_FORM_data4)
+	.uleb128 0x40	# (DW_AT_frame_base)
+	.uleb128 0x18	# (DW_FORM_exprloc)
+	.uleb128 0x2117	# (DW_AT_GNU_all_call_sites)
+	.uleb128 0x19	# (DW_FORM_flag_present)
+	.byte	0
+	.byte	0
+	.uleb128 0x8	# (abbrev code)
+	.uleb128 0x34	# (TAG: DW_TAG_variable)
+	.byte	0	# DW_children_no
+	.uleb128 0x3	# (DW_AT_name)
+	.uleb128 0xe	# (DW_FORM_strp)
+	.uleb128 0x3a	# (DW_AT_decl_file)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x3b	# (DW_AT_decl_line)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x49	# (DW_AT_type)
+	.uleb128 0x13	# (DW_FORM_ref4)
+	.uleb128 0x2	# (DW_AT_location)
+	.uleb128 0x17	# (DW_FORM_sec_offset)
+	.byte	0
+	.byte	0
+	.uleb128 0x9	# (abbrev code)
+	.uleb128 0x4109	# (TAG: DW_TAG_GNU_call_site)
+	.byte	0	# DW_children_no
+	.uleb128 0x11	# (DW_AT_low_pc)
+	.uleb128 0x1	# (DW_FORM_addr)
+	.uleb128 0x31	# (DW_AT_abstract_origin)
+	.uleb128 0x13	# (DW_FORM_ref4)
+	.byte	0
+	.byte	0
+	.byte	0
+	.section	.debug_loc,"",@progbits
+.Ldebug_loc0:
+.LLST0:
+	.long	.LVL3	# Location list begin address (*.LLST0)
+	.long	.LVL4	# Location list end address (*.LLST0)
+	.value	0x3	# Location expression size
+	.byte	0x70	# DW_OP_breg0
+	.sleb128 1
+	.byte	0x9f	# DW_OP_stack_value
+	.long	.LVL4	# Location list begin address (*.LLST0)
+	.long	.LFE4	# Location list end address (*.LLST0)
+	.value	0x1	# Location expression size
+	.byte	0x50	# DW_OP_reg0
+	.long	0	# Location list terminator begin (*.LLST0)
+	.long	0	# Location list terminator end (*.LLST0)
+	.section	.debug_aranges,"",@progbits
+	.long	0x24	# Length of Address Ranges Info
+	.value	0x2	# DWARF Version
+	.long	.Ldebug_info0	# Offset of Compilation Unit Info
+	.byte	0x4	# Size of Address
+	.byte	0	# Size of Segment Descriptor
+	.value	0	# Pad to 8 byte boundary
+	.value	0
+	.long	.Ltext0	# Address
+	.long	.Letext0-.Ltext0	# Length
+	.long	.LFB4	# Address
+	.long	.LFE4-.LFB4	# Length
+	.long	0
+	.long	0
+	.section	.debug_ranges,"",@progbits
+.Ldebug_ranges0:
+	.long	.Ltext0	# Offset 0
+	.long	.Letext0
+	.long	.LFB4	# Offset 0x8
+	.long	.LFE4
+	.long	0
+	.long	0
+	.section	.debug_line,"",@progbits
+.Ldebug_line0:
+	.section	.debug_str,"MS",@progbits,1
+.LASF4:
+	.string	"bar_1"
+.LASF2:
+	.string	"tailcall-only.c"
+.LASF1:
+	.string	"GNU C 4.8.3 20140911 (Red Hat 4.8.3-9) -m32 -march=i686 -g -O2"
+.LASF6:
+	.string	"answer"
+.LASF5:
+	.string	"main"
+.LASF3:
+	.string	""
+.LASF0:
+	.string	"foo_1"
+	.ident	"GCC: (GNU) 4.8.3 20140911 (Red Hat 4.8.3-9)"
+	.section	.note.GNU-stack,"",@progbits
diff --git a/gdb/testsuite/gdb.btrace/tailcall-only.c b/gdb/testsuite/gdb.btrace/tailcall-only.c
new file mode 100644
index 0000000..5913ddc
--- /dev/null
+++ b/gdb/testsuite/gdb.btrace/tailcall-only.c
@@ -0,0 +1,53 @@ 
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2016 Free Software Foundation, Inc.
+
+   Contributed by Intel Corp. <markus.t.metzger@intel.com>
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+static __attribute__ ((noinline)) int
+bar_1 (void)
+{
+  return 42;
+}
+
+static __attribute__ ((noinline)) int
+bar (void)
+{
+  return bar_1 ();
+}
+
+static __attribute__ ((noinline)) int
+foo_1 (void)
+{
+  return bar ();
+}
+
+static __attribute__ ((noinline)) int
+foo (void)
+{
+  return foo_1 ();
+}
+
+int
+main (void)
+{
+  int answer;
+
+  answer = foo ();
+  answer += 1;
+
+  return answer;
+}
diff --git a/gdb/testsuite/gdb.btrace/tailcall-only.exp b/gdb/testsuite/gdb.btrace/tailcall-only.exp
new file mode 100644
index 0000000..1137be1
--- /dev/null
+++ b/gdb/testsuite/gdb.btrace/tailcall-only.exp
@@ -0,0 +1,93 @@ 
+# This testcase is part of GDB, the GNU debugger.
+#
+# Copyright 2016 Free Software Foundation, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+#
+# This is a variant of tailcall.exp where the entire trace contains only tail
+# calls.  This used to cause a crash in get_frame_type.
+#
+
+# check for btrace support
+if { [skip_btrace_tests] } { return -1 }
+
+# This test requires the compiler to generate a tail call.  To guarantee that
+# we always get one, we use an assembly source file.
+#
+# We use different assembly sources based on the target architecture.
+#
+# Luckily, they are similar enough that a single test script can handle
+# both.
+set opts {}
+if [info exists COMPILE] {
+    # make check RUNTESTFLAGS="gdb.btrace/tailcall-only.exp COMPILE=1"
+    standard_testfile tailcall-only.c
+    lappend opts debug optimize=-O2
+} elseif {[istarget "x86_64-*-*"]} {
+	standard_testfile x86_64-tailcall-only.S
+} elseif {[istarget "i?86-*-*"]} {
+	standard_testfile i686-tailcall-only.S
+} else {
+    verbose "Skipping ${testfile}."
+    return
+}
+
+if [prepare_for_testing tailcall-only.exp $testfile $srcfile $opts] {
+    return -1
+}
+if ![runto_main] {
+    return -1
+}
+
+# we want to see the full trace for this test
+gdb_test_no_output "set record function-call-history-size 0"
+
+# trace foo
+gdb_test "step" ".*" "prepare for recording"
+gdb_test_no_output "record btrace"
+gdb_test "stepi 4" ".*" "record branch trace"
+
+# for debugging
+gdb_test "info record" ".*"
+
+# show the branch trace with calls indented
+gdb_test "record function-call-history /c 1" [multi_line \
+  "1\tfoo" \
+  "2\t  foo_1" \
+  "3\t    bar" \
+  "4\t      bar_1"
+  ] "function-call-history"
+
+# We can step
+gdb_test "record goto begin" ".*foo.*"
+gdb_test "stepi" ".*foo_1.*" "step into foo_1"
+gdb_test "step" ".*bar.*" "step into bar"
+gdb_test "stepi" ".*bar_1.*" "step into bar_1"
+
+# We can neither finish nor return.
+gdb_test "finish" "\"finish\" not meaningful for tailcall frames.*"
+gdb_test_multiple "return" "return" {
+  -re "Make .* return now.*y or n. $" {
+    send_gdb "y\n"
+    exp_continue
+  }
+  -re "Cannot pop a tailcall frame.*$gdb_prompt $" {
+    pass "return"
+  }
+}
+
+# But we can reverse-finish
+gdb_test "reverse-finish" ".*bar.*"
+gdb_test "reverse-step" ".*foo_1.*"
diff --git a/gdb/testsuite/gdb.btrace/x86_64-tailcall-only.S b/gdb/testsuite/gdb.btrace/x86_64-tailcall-only.S
new file mode 100644
index 0000000..710288a
--- /dev/null
+++ b/gdb/testsuite/gdb.btrace/x86_64-tailcall-only.S
@@ -0,0 +1,446 @@ 
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2016 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+
+   This file has been generated using:
+   gcc -S -O2 -dA -g tailcall-only.c -o x86_64-tailcall-only.S  */
+
+	.file	"tailcall-only.c"
+	.text
+.Ltext0:
+	.p2align 4,,15
+	.type	bar_1, @function
+bar_1:
+.LFB0:
+	.file 1 "tailcall-only.c"
+	# tailcall-only.c:22
+	.loc 1 22 0
+	.cfi_startproc
+# BLOCK 2 freq:10000 seq:0
+# PRED: ENTRY [100.0%]  (FALLTHRU)
+	# tailcall-only.c:24
+	.loc 1 24 0
+	movl	$42, %eax
+# SUCC: EXIT [100.0%]
+	ret
+	.cfi_endproc
+.LFE0:
+	.size	bar_1, .-bar_1
+	.p2align 4,,15
+	.type	bar, @function
+bar:
+.LFB1:
+	# tailcall-only.c:28
+	.loc 1 28 0
+	.cfi_startproc
+# BLOCK 2 freq:10000 seq:0
+# PRED: ENTRY [100.0%]  (FALLTHRU)
+	# tailcall-only.c:29
+	.loc 1 29 0
+	jmp	bar_1
+# SUCC: EXIT [100.0%]  (ABNORMAL,SIBCALL)
+.LVL0:
+	.cfi_endproc
+.LFE1:
+	.size	bar, .-bar
+	.p2align 4,,15
+	.type	foo_1, @function
+foo_1:
+.LFB2:
+	# tailcall-only.c:34
+	.loc 1 34 0
+	.cfi_startproc
+# BLOCK 2 freq:10000 seq:0
+# PRED: ENTRY [100.0%]  (FALLTHRU)
+	# tailcall-only.c:35
+	.loc 1 35 0
+	jmp	bar
+# SUCC: EXIT [100.0%]  (ABNORMAL,SIBCALL)
+.LVL1:
+	.cfi_endproc
+.LFE2:
+	.size	foo_1, .-foo_1
+	.p2align 4,,15
+	.type	foo, @function
+foo:
+.LFB3:
+	# tailcall-only.c:40
+	.loc 1 40 0
+	.cfi_startproc
+# BLOCK 2 freq:10000 seq:0
+# PRED: ENTRY [100.0%]  (FALLTHRU)
+	# tailcall-only.c:41
+	.loc 1 41 0
+	jmp	foo_1
+# SUCC: EXIT [100.0%]  (ABNORMAL,SIBCALL)
+.LVL2:
+	.cfi_endproc
+.LFE3:
+	.size	foo, .-foo
+	.section	.text.startup,"ax",@progbits
+	.p2align 4,,15
+	.globl	main
+	.type	main, @function
+main:
+.LFB4:
+	# tailcall-only.c:46
+	.loc 1 46 0
+	.cfi_startproc
+# BLOCK 2 freq:10000 seq:0
+# PRED: ENTRY [100.0%]  (FALLTHRU)
+	# tailcall-only.c:49
+	.loc 1 49 0
+	call	foo
+.LVL3:
+	# tailcall-only.c:50
+	.loc 1 50 0
+	addl	$1, %eax
+.LVL4:
+# SUCC: EXIT [100.0%]
+	# tailcall-only.c:53
+	.loc 1 53 0
+	ret
+	.cfi_endproc
+.LFE4:
+	.size	main, .-main
+	.text
+.Letext0:
+	.section	.debug_info,"",@progbits
+.Ldebug_info0:
+	.long	0x111	# Length of Compilation Unit Info
+	.value	0x4	# DWARF version number
+	.long	.Ldebug_abbrev0	# Offset Into Abbrev. Section
+	.byte	0x8	# Pointer Size (in bytes)
+	.uleb128 0x1	# (DIE (0xb) DW_TAG_compile_unit)
+	.long	.LASF1	# DW_AT_producer: "GNU C 4.8.3 20140911 (Red Hat 4.8.3-9) -mtune=generic -march=x86-64 -g -O2"
+	.byte	0x1	# DW_AT_language
+	.long	.LASF2	# DW_AT_name: "tailcall-only.c"
+	.long	.LASF3	# DW_AT_comp_dir: ""
+	.long	.Ldebug_ranges0+0	# DW_AT_ranges
+	.quad	0	# DW_AT_low_pc
+	.long	.Ldebug_line0	# DW_AT_stmt_list
+	.uleb128 0x2	# (DIE (0x29) DW_TAG_subprogram)
+	.long	.LASF4	# DW_AT_name: "bar_1"
+	.byte	0x1	# DW_AT_decl_file (tailcall-only.c)
+	.byte	0x15	# DW_AT_decl_line
+			# DW_AT_prototyped
+	.long	0x46	# DW_AT_type
+	.quad	.LFB0	# DW_AT_low_pc
+	.quad	.LFE0-.LFB0	# DW_AT_high_pc
+	.uleb128 0x1	# DW_AT_frame_base
+	.byte	0x9c	# DW_OP_call_frame_cfa
+			# DW_AT_GNU_all_call_sites
+	.uleb128 0x3	# (DIE (0x46) DW_TAG_base_type)
+	.byte	0x4	# DW_AT_byte_size
+	.byte	0x5	# DW_AT_encoding
+	.ascii "int\0"	# DW_AT_name
+	.uleb128 0x4	# (DIE (0x4d) DW_TAG_subprogram)
+	.ascii "bar\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (tailcall-only.c)
+	.byte	0x1b	# DW_AT_decl_line
+			# DW_AT_prototyped
+	.long	0x46	# DW_AT_type
+	.quad	.LFB1	# DW_AT_low_pc
+	.quad	.LFE1-.LFB1	# DW_AT_high_pc
+	.uleb128 0x1	# DW_AT_frame_base
+	.byte	0x9c	# DW_OP_call_frame_cfa
+			# DW_AT_GNU_all_call_sites
+	.long	0x7c	# DW_AT_sibling
+	.uleb128 0x5	# (DIE (0x6e) DW_TAG_GNU_call_site)
+	.quad	.LVL0	# DW_AT_low_pc
+			# DW_AT_GNU_tail_call
+	.long	0x29	# DW_AT_abstract_origin
+	.byte	0	# end of children of DIE 0x4d
+	.uleb128 0x6	# (DIE (0x7c) DW_TAG_subprogram)
+	.long	.LASF0	# DW_AT_name: "foo_1"
+	.byte	0x1	# DW_AT_decl_file (tailcall-only.c)
+	.byte	0x21	# DW_AT_decl_line
+			# DW_AT_prototyped
+	.long	0x46	# DW_AT_type
+	.quad	.LFB2	# DW_AT_low_pc
+	.quad	.LFE2-.LFB2	# DW_AT_high_pc
+	.uleb128 0x1	# DW_AT_frame_base
+	.byte	0x9c	# DW_OP_call_frame_cfa
+			# DW_AT_GNU_all_call_sites
+	.long	0xab	# DW_AT_sibling
+	.uleb128 0x5	# (DIE (0x9d) DW_TAG_GNU_call_site)
+	.quad	.LVL1	# DW_AT_low_pc
+			# DW_AT_GNU_tail_call
+	.long	0x4d	# DW_AT_abstract_origin
+	.byte	0	# end of children of DIE 0x7c
+	.uleb128 0x4	# (DIE (0xab) DW_TAG_subprogram)
+	.ascii "foo\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (tailcall-only.c)
+	.byte	0x27	# DW_AT_decl_line
+			# DW_AT_prototyped
+	.long	0x46	# DW_AT_type
+	.quad	.LFB3	# DW_AT_low_pc
+	.quad	.LFE3-.LFB3	# DW_AT_high_pc
+	.uleb128 0x1	# DW_AT_frame_base
+	.byte	0x9c	# DW_OP_call_frame_cfa
+			# DW_AT_GNU_all_call_sites
+	.long	0xda	# DW_AT_sibling
+	.uleb128 0x5	# (DIE (0xcc) DW_TAG_GNU_call_site)
+	.quad	.LVL2	# DW_AT_low_pc
+			# DW_AT_GNU_tail_call
+	.long	0x7c	# DW_AT_abstract_origin
+	.byte	0	# end of children of DIE 0xab
+	.uleb128 0x7	# (DIE (0xda) DW_TAG_subprogram)
+			# DW_AT_external
+	.long	.LASF5	# DW_AT_name: "main"
+	.byte	0x1	# DW_AT_decl_file (tailcall-only.c)
+	.byte	0x2d	# DW_AT_decl_line
+			# DW_AT_prototyped
+	.long	0x46	# DW_AT_type
+	.quad	.LFB4	# DW_AT_low_pc
+	.quad	.LFE4-.LFB4	# DW_AT_high_pc
+	.uleb128 0x1	# DW_AT_frame_base
+	.byte	0x9c	# DW_OP_call_frame_cfa
+			# DW_AT_GNU_all_call_sites
+	.uleb128 0x8	# (DIE (0xf7) DW_TAG_variable)
+	.long	.LASF6	# DW_AT_name: "answer"
+	.byte	0x1	# DW_AT_decl_file (tailcall-only.c)
+	.byte	0x2f	# DW_AT_decl_line
+	.long	0x46	# DW_AT_type
+	.long	.LLST0	# DW_AT_location
+	.uleb128 0x9	# (DIE (0x106) DW_TAG_GNU_call_site)
+	.quad	.LVL3	# DW_AT_low_pc
+	.long	0xab	# DW_AT_abstract_origin
+	.byte	0	# end of children of DIE 0xda
+	.byte	0	# end of children of DIE 0xb
+	.section	.debug_abbrev,"",@progbits
+.Ldebug_abbrev0:
+	.uleb128 0x1	# (abbrev code)
+	.uleb128 0x11	# (TAG: DW_TAG_compile_unit)
+	.byte	0x1	# DW_children_yes
+	.uleb128 0x25	# (DW_AT_producer)
+	.uleb128 0xe	# (DW_FORM_strp)
+	.uleb128 0x13	# (DW_AT_language)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x3	# (DW_AT_name)
+	.uleb128 0xe	# (DW_FORM_strp)
+	.uleb128 0x1b	# (DW_AT_comp_dir)
+	.uleb128 0xe	# (DW_FORM_strp)
+	.uleb128 0x55	# (DW_AT_ranges)
+	.uleb128 0x17	# (DW_FORM_sec_offset)
+	.uleb128 0x11	# (DW_AT_low_pc)
+	.uleb128 0x1	# (DW_FORM_addr)
+	.uleb128 0x10	# (DW_AT_stmt_list)
+	.uleb128 0x17	# (DW_FORM_sec_offset)
+	.byte	0
+	.byte	0
+	.uleb128 0x2	# (abbrev code)
+	.uleb128 0x2e	# (TAG: DW_TAG_subprogram)
+	.byte	0	# DW_children_no
+	.uleb128 0x3	# (DW_AT_name)
+	.uleb128 0xe	# (DW_FORM_strp)
+	.uleb128 0x3a	# (DW_AT_decl_file)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x3b	# (DW_AT_decl_line)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x27	# (DW_AT_prototyped)
+	.uleb128 0x19	# (DW_FORM_flag_present)
+	.uleb128 0x49	# (DW_AT_type)
+	.uleb128 0x13	# (DW_FORM_ref4)
+	.uleb128 0x11	# (DW_AT_low_pc)
+	.uleb128 0x1	# (DW_FORM_addr)
+	.uleb128 0x12	# (DW_AT_high_pc)
+	.uleb128 0x7	# (DW_FORM_data8)
+	.uleb128 0x40	# (DW_AT_frame_base)
+	.uleb128 0x18	# (DW_FORM_exprloc)
+	.uleb128 0x2117	# (DW_AT_GNU_all_call_sites)
+	.uleb128 0x19	# (DW_FORM_flag_present)
+	.byte	0
+	.byte	0
+	.uleb128 0x3	# (abbrev code)
+	.uleb128 0x24	# (TAG: DW_TAG_base_type)
+	.byte	0	# DW_children_no
+	.uleb128 0xb	# (DW_AT_byte_size)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x3e	# (DW_AT_encoding)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x3	# (DW_AT_name)
+	.uleb128 0x8	# (DW_FORM_string)
+	.byte	0
+	.byte	0
+	.uleb128 0x4	# (abbrev code)
+	.uleb128 0x2e	# (TAG: DW_TAG_subprogram)
+	.byte	0x1	# DW_children_yes
+	.uleb128 0x3	# (DW_AT_name)
+	.uleb128 0x8	# (DW_FORM_string)
+	.uleb128 0x3a	# (DW_AT_decl_file)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x3b	# (DW_AT_decl_line)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x27	# (DW_AT_prototyped)
+	.uleb128 0x19	# (DW_FORM_flag_present)
+	.uleb128 0x49	# (DW_AT_type)
+	.uleb128 0x13	# (DW_FORM_ref4)
+	.uleb128 0x11	# (DW_AT_low_pc)
+	.uleb128 0x1	# (DW_FORM_addr)
+	.uleb128 0x12	# (DW_AT_high_pc)
+	.uleb128 0x7	# (DW_FORM_data8)
+	.uleb128 0x40	# (DW_AT_frame_base)
+	.uleb128 0x18	# (DW_FORM_exprloc)
+	.uleb128 0x2117	# (DW_AT_GNU_all_call_sites)
+	.uleb128 0x19	# (DW_FORM_flag_present)
+	.uleb128 0x1	# (DW_AT_sibling)
+	.uleb128 0x13	# (DW_FORM_ref4)
+	.byte	0
+	.byte	0
+	.uleb128 0x5	# (abbrev code)
+	.uleb128 0x4109	# (TAG: DW_TAG_GNU_call_site)
+	.byte	0	# DW_children_no
+	.uleb128 0x11	# (DW_AT_low_pc)
+	.uleb128 0x1	# (DW_FORM_addr)
+	.uleb128 0x2115	# (DW_AT_GNU_tail_call)
+	.uleb128 0x19	# (DW_FORM_flag_present)
+	.uleb128 0x31	# (DW_AT_abstract_origin)
+	.uleb128 0x13	# (DW_FORM_ref4)
+	.byte	0
+	.byte	0
+	.uleb128 0x6	# (abbrev code)
+	.uleb128 0x2e	# (TAG: DW_TAG_subprogram)
+	.byte	0x1	# DW_children_yes
+	.uleb128 0x3	# (DW_AT_name)
+	.uleb128 0xe	# (DW_FORM_strp)
+	.uleb128 0x3a	# (DW_AT_decl_file)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x3b	# (DW_AT_decl_line)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x27	# (DW_AT_prototyped)
+	.uleb128 0x19	# (DW_FORM_flag_present)
+	.uleb128 0x49	# (DW_AT_type)
+	.uleb128 0x13	# (DW_FORM_ref4)
+	.uleb128 0x11	# (DW_AT_low_pc)
+	.uleb128 0x1	# (DW_FORM_addr)
+	.uleb128 0x12	# (DW_AT_high_pc)
+	.uleb128 0x7	# (DW_FORM_data8)
+	.uleb128 0x40	# (DW_AT_frame_base)
+	.uleb128 0x18	# (DW_FORM_exprloc)
+	.uleb128 0x2117	# (DW_AT_GNU_all_call_sites)
+	.uleb128 0x19	# (DW_FORM_flag_present)
+	.uleb128 0x1	# (DW_AT_sibling)
+	.uleb128 0x13	# (DW_FORM_ref4)
+	.byte	0
+	.byte	0
+	.uleb128 0x7	# (abbrev code)
+	.uleb128 0x2e	# (TAG: DW_TAG_subprogram)
+	.byte	0x1	# DW_children_yes
+	.uleb128 0x3f	# (DW_AT_external)
+	.uleb128 0x19	# (DW_FORM_flag_present)
+	.uleb128 0x3	# (DW_AT_name)
+	.uleb128 0xe	# (DW_FORM_strp)
+	.uleb128 0x3a	# (DW_AT_decl_file)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x3b	# (DW_AT_decl_line)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x27	# (DW_AT_prototyped)
+	.uleb128 0x19	# (DW_FORM_flag_present)
+	.uleb128 0x49	# (DW_AT_type)
+	.uleb128 0x13	# (DW_FORM_ref4)
+	.uleb128 0x11	# (DW_AT_low_pc)
+	.uleb128 0x1	# (DW_FORM_addr)
+	.uleb128 0x12	# (DW_AT_high_pc)
+	.uleb128 0x7	# (DW_FORM_data8)
+	.uleb128 0x40	# (DW_AT_frame_base)
+	.uleb128 0x18	# (DW_FORM_exprloc)
+	.uleb128 0x2117	# (DW_AT_GNU_all_call_sites)
+	.uleb128 0x19	# (DW_FORM_flag_present)
+	.byte	0
+	.byte	0
+	.uleb128 0x8	# (abbrev code)
+	.uleb128 0x34	# (TAG: DW_TAG_variable)
+	.byte	0	# DW_children_no
+	.uleb128 0x3	# (DW_AT_name)
+	.uleb128 0xe	# (DW_FORM_strp)
+	.uleb128 0x3a	# (DW_AT_decl_file)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x3b	# (DW_AT_decl_line)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x49	# (DW_AT_type)
+	.uleb128 0x13	# (DW_FORM_ref4)
+	.uleb128 0x2	# (DW_AT_location)
+	.uleb128 0x17	# (DW_FORM_sec_offset)
+	.byte	0
+	.byte	0
+	.uleb128 0x9	# (abbrev code)
+	.uleb128 0x4109	# (TAG: DW_TAG_GNU_call_site)
+	.byte	0	# DW_children_no
+	.uleb128 0x11	# (DW_AT_low_pc)
+	.uleb128 0x1	# (DW_FORM_addr)
+	.uleb128 0x31	# (DW_AT_abstract_origin)
+	.uleb128 0x13	# (DW_FORM_ref4)
+	.byte	0
+	.byte	0
+	.byte	0
+	.section	.debug_loc,"",@progbits
+.Ldebug_loc0:
+.LLST0:
+	.quad	.LVL3	# Location list begin address (*.LLST0)
+	.quad	.LVL4	# Location list end address (*.LLST0)
+	.value	0x3	# Location expression size
+	.byte	0x70	# DW_OP_breg0
+	.sleb128 1
+	.byte	0x9f	# DW_OP_stack_value
+	.quad	.LVL4	# Location list begin address (*.LLST0)
+	.quad	.LFE4	# Location list end address (*.LLST0)
+	.value	0x1	# Location expression size
+	.byte	0x50	# DW_OP_reg0
+	.quad	0	# Location list terminator begin (*.LLST0)
+	.quad	0	# Location list terminator end (*.LLST0)
+	.section	.debug_aranges,"",@progbits
+	.long	0x3c	# Length of Address Ranges Info
+	.value	0x2	# DWARF Version
+	.long	.Ldebug_info0	# Offset of Compilation Unit Info
+	.byte	0x8	# Size of Address
+	.byte	0	# Size of Segment Descriptor
+	.value	0	# Pad to 16 byte boundary
+	.value	0
+	.quad	.Ltext0	# Address
+	.quad	.Letext0-.Ltext0	# Length
+	.quad	.LFB4	# Address
+	.quad	.LFE4-.LFB4	# Length
+	.quad	0
+	.quad	0
+	.section	.debug_ranges,"",@progbits
+.Ldebug_ranges0:
+	.quad	.Ltext0	# Offset 0
+	.quad	.Letext0
+	.quad	.LFB4	# Offset 0x10
+	.quad	.LFE4
+	.quad	0
+	.quad	0
+	.section	.debug_line,"",@progbits
+.Ldebug_line0:
+	.section	.debug_str,"MS",@progbits,1
+.LASF4:
+	.string	"bar_1"
+.LASF2:
+	.string	"tailcall-only.c"
+.LASF1:
+	.string	"GNU C 4.8.3 20140911 (Red Hat 4.8.3-9) -mtune=generic -march=x86-64 -g -O2"
+.LASF6:
+	.string	"answer"
+.LASF5:
+	.string	"main"
+.LASF3:
+	.string	""
+.LASF0:
+	.string	"foo_1"
+	.ident	"GCC: (GNU) 4.8.3 20140911 (Red Hat 4.8.3-9)"
+	.section	.note.GNU-stack,"",@progbits