old-cross-binutils/gdb/testsuite/gdb.trace
Pedro Alves 5ce0145de7 "tfind" across unavailable-stack frames.
Like when stepping, the current stack frame location is expected to be
printed as result of tfind command, if that results in moving to a
different function.  In tfind_1 we see:

  if (from_tty
      && (has_stack_frames () || traceframe_number >= 0))
    {
      enum print_what print_what;

      /* NOTE: in imitation of the step command, try to determine
         whether we have made a transition from one function to
         another.  If so, we'll print the "stack frame" (ie. the new
         function and it's arguments) -- otherwise we'll just show the
         new source line.  */

      if (frame_id_eq (old_frame_id,
                       get_frame_id (get_current_frame ())))
        print_what = SRC_LINE;
      else
        print_what = SRC_AND_LOC;

      print_stack_frame (get_selected_frame (NULL), 1, print_what, 1);
      do_displays ();
    }

However, when we haven't collected any registers in the tracepoint
(collect $regs), that doesn't actually work:

 (gdb) tstart
 (gdb) info tracepoints
 Num     Type           Disp Enb Address    What
 1       tracepoint     keep y   0x080483b7 in func0
                                            at ../.././../git/gdb/testsuite/gdb.trace/circ.c:28
         collect testload
     installed on target
 2       tracepoint     keep y   0x080483bc in func1
                                            at ../.././../git/gdb/testsuite/gdb.trace/circ.c:32
         collect testload
     installed on target
 (gdb) c
 Continuing.

 Breakpoint 3, end () at ../.././../git/gdb/testsuite/gdb.trace/circ.c:72
 72    }
 (gdb) tstop
 (gdb) tfind start
 Found trace frame 0, tracepoint 1
 #0  func0 () at ../.././../git/gdb/testsuite/gdb.trace/circ.c:28
 28    }
 (gdb) tfind
 Found trace frame 1, tracepoint 2
 32    }
 (gdb)

When we don't have info about the stack available
(UNWIND_UNAVAILABLE), frames end up with outer_frame_id as frame ID.
And in the scenario above, the issue is that both frames before and
after the second tfind (the frames for func0 an func1) have the same
id (outer_frame_id), so the frame_id_eq check returns false, even
though the frames were of different functions.  GDB knows that,
because the PC is inferred from the tracepoint's address, even if no
registers were collected.

To fix this, this patch adds support for frame ids with a valid code
address, but <unavailable> stack address, and then makes the unwinders
use that instead of the catch-all outer_frame_id for such frames.  The
frame_id_eq check in tfind_1 then automatically does the right thing
as expected.

I tested with --directory=gdb.trace/ , before/after the patch, and
compared the resulting gdb.logs, then adjusted the tests to expect the
extra output that came out.  Turns out that was only circ.exp, the
original test that actually brought this issue to light.

Tested on x86_64 Fedora 17, native and gdbserver.

gdb/
2013-12-17  Pedro Alves  <palves@redhat.com>

	* frame.h (enum frame_id_stack_status): New enum.
	(struct frame_id) <stack_addr>: Adjust comment.
	<stack_addr_p>: Delete field, replaced with ...
	<stack_status>: ... this new field.
	(frame_id_build_unavailable_stack): Declare.
	* frame.c (frame_addr_hash, fprint_field, outer_frame_id)
	(frame_id_build_special): Adjust.
	(frame_id_build_unavailable_stack): New function.
	(frame_id_build, frame_id_build_wild): Adjust.
	(frame_id_p, frame_id_eq, frame_id_inner): Adjust to take into
	account frames with unavailable stack.

	* amd64-tdep.c (amd64_frame_this_id)
	(amd64_sigtramp_frame_this_id, amd64_epilogue_frame_this_id): Use
	frame_id_build_unavailable_stack.
	* dwarf2-frame.c (dwarf2_frame_this_id): Likewise.
	* i386-tdep.c (i386_frame_this_id, i386_epilogue_frame_this_id)
	(i386_sigtramp_frame_this_id):  Likewise.

gdb/testsuite/
2013-12-17  Pedro Alves  <palves@redhat.com>

	* gdb.trace/circ.exp: Expect frame info to be printed when
	switching between frames with unavailable stack, but different
	functions.
2013-12-17 20:47:36 +00:00
..
actions-changed.c
actions-changed.exp
actions.c
actions.exp * gdb.trace/actions.exp (check_tracepoint): Don't use a full file 2013-06-21 17:18:45 +00:00
ax.exp
backtrace.exp gdb/ 2013-07-31 00:44:42 +00:00
change-loc-1.c
change-loc-2.c
change-loc.c
change-loc.exp
change-loc.h
circ.c
circ.exp "tfind" across unavailable-stack frames. 2013-12-17 20:47:36 +00:00
collection.c
collection.exp gdb/ 2013-08-09 00:35:40 +00:00
deltrace.exp
disconnected-tracing.c
disconnected-tracing.exp testsuite: Persistent gdbserver cleanup 2013-10-25 14:03:00 +00:00
entry-values.c gdb/testsuite/ 2013-08-24 01:54:59 +00:00
entry-values.exp gdb/testsuite/ 2013-10-02 18:09:26 +00:00
ftrace.c
ftrace.exp
infotrace.exp
Makefile.in
mi-trace-frame-collected.exp gdb/testsuite/ 2013-06-26 08:28:27 +00:00
mi-trace-unavailable.exp Add options to skip unavailable locals 2013-08-27 05:20:57 +00:00
mi-traceframe-changed.exp fix up gdb.trace 2013-11-04 11:02:06 -07:00
mi-tracepoint-changed.exp
mi-tsv-changed.exp
packetlen.exp
passc-dyn.exp
passcount.exp
pending.c
pending.exp
pendshr1.c
pendshr2.c
qtro.c
qtro.exp
range-stepping.c
range-stepping.exp
read-memory.c gdb/testsuite/ 2013-07-18 23:04:00 +00:00
read-memory.exp gdb/ 2013-07-18 23:09:49 +00:00
report.exp
save-trace.exp
stap-trace.c
stap-trace.exp
status-stop.c
status-stop.exp
strace.c
strace.exp
tfile.c fix up gdb.trace 2013-11-04 11:02:06 -07:00
tfile.exp fix up gdb.trace 2013-11-04 11:02:06 -07:00
tfind.exp
trace-break.c
trace-break.exp
trace-buffer-size.c
trace-buffer-size.exp
trace-mt.c
trace-mt.exp
trace-unavailable.c Teach -data-list-register-values to not include unavailable registers 2013-06-20 00:39:11 +00:00
tracecmd.exp
tspeed.c
tspeed.exp
tstatus.exp
tsv.exp Upload tsv earlier in remote_start_remote 2013-06-25 13:01:28 +00:00
unavailable-dwarf-piece.c Convert the unavailable vector to be bit, not byte, based. 2013-12-17 17:24:15 +00:00
unavailable-dwarf-piece.exp Convert the unavailable vector to be bit, not byte, based. 2013-12-17 17:24:15 +00:00
unavailable.cc
unavailable.exp Print entirely unavailable struct/union values as a single <unavailable>. 2013-11-28 18:54:20 +00:00
while-dyn.exp
while-stepping.exp