1 /* Branch trace support for GDB, the GNU debugger.
3 Copyright (C) 2013-2019 Free Software Foundation, Inc.
5 Contributed by Intel Corp. <markus.t.metzger@intel.com>
7 This file is part of GDB.
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>. */
24 #include "record-btrace.h"
25 #include "gdbthread.h"
29 #include "observable.h"
30 #include "cli/cli-utils.h"
34 #include "filenames.h"
36 #include "frame-unwind.h"
39 #include "event-loop.h"
41 #include "common/vec.h"
45 static const target_info record_btrace_target_info
= {
47 N_("Branch tracing target"),
48 N_("Collect control-flow trace and provide the execution history.")
51 /* The target_ops of record-btrace. */
53 class record_btrace_target final
: public target_ops
56 const target_info
&info () const override
57 { return record_btrace_target_info
; }
59 strata
stratum () const override
{ return record_stratum
; }
61 void close () override
;
62 void async (int) override
;
64 void detach (inferior
*inf
, int from_tty
) override
65 { record_detach (this, inf
, from_tty
); }
67 void disconnect (const char *, int) override
;
69 void mourn_inferior () override
70 { record_mourn_inferior (this); }
73 { record_kill (this); }
75 enum record_method
record_method (ptid_t ptid
) override
;
77 void stop_recording () override
;
78 void info_record () override
;
80 void insn_history (int size
, gdb_disassembly_flags flags
) override
;
81 void insn_history_from (ULONGEST from
, int size
,
82 gdb_disassembly_flags flags
) override
;
83 void insn_history_range (ULONGEST begin
, ULONGEST end
,
84 gdb_disassembly_flags flags
) override
;
85 void call_history (int size
, record_print_flags flags
) override
;
86 void call_history_from (ULONGEST begin
, int size
, record_print_flags flags
)
88 void call_history_range (ULONGEST begin
, ULONGEST end
, record_print_flags flags
)
91 bool record_is_replaying (ptid_t ptid
) override
;
92 bool record_will_replay (ptid_t ptid
, int dir
) override
;
93 void record_stop_replaying () override
;
95 enum target_xfer_status
xfer_partial (enum target_object object
,
98 const gdb_byte
*writebuf
,
99 ULONGEST offset
, ULONGEST len
,
100 ULONGEST
*xfered_len
) override
;
102 int insert_breakpoint (struct gdbarch
*,
103 struct bp_target_info
*) override
;
104 int remove_breakpoint (struct gdbarch
*, struct bp_target_info
*,
105 enum remove_bp_reason
) override
;
107 void fetch_registers (struct regcache
*, int) override
;
109 void store_registers (struct regcache
*, int) override
;
110 void prepare_to_store (struct regcache
*) override
;
112 const struct frame_unwind
*get_unwinder () override
;
114 const struct frame_unwind
*get_tailcall_unwinder () override
;
116 void commit_resume () override
;
117 void resume (ptid_t
, int, enum gdb_signal
) override
;
118 ptid_t
wait (ptid_t
, struct target_waitstatus
*, int) override
;
120 void stop (ptid_t
) override
;
121 void update_thread_list () override
;
122 bool thread_alive (ptid_t ptid
) override
;
123 void goto_record_begin () override
;
124 void goto_record_end () override
;
125 void goto_record (ULONGEST insn
) override
;
127 bool can_execute_reverse () override
;
129 bool stopped_by_sw_breakpoint () override
;
130 bool supports_stopped_by_sw_breakpoint () override
;
132 bool stopped_by_hw_breakpoint () override
;
133 bool supports_stopped_by_hw_breakpoint () override
;
135 enum exec_direction_kind
execution_direction () override
;
136 void prepare_to_generate_core () override
;
137 void done_generating_core () override
;
140 static record_btrace_target record_btrace_ops
;
142 /* Initialize the record-btrace target ops. */
144 /* Token associated with a new-thread observer enabling branch tracing
145 for the new thread. */
146 static const gdb::observers::token record_btrace_thread_observer_token
{};
148 /* Memory access types used in set/show record btrace replay-memory-access. */
149 static const char replay_memory_access_read_only
[] = "read-only";
150 static const char replay_memory_access_read_write
[] = "read-write";
151 static const char *const replay_memory_access_types
[] =
153 replay_memory_access_read_only
,
154 replay_memory_access_read_write
,
158 /* The currently allowed replay memory access type. */
159 static const char *replay_memory_access
= replay_memory_access_read_only
;
161 /* The cpu state kinds. */
162 enum record_btrace_cpu_state_kind
169 /* The current cpu state. */
170 static enum record_btrace_cpu_state_kind record_btrace_cpu_state
= CS_AUTO
;
172 /* The current cpu for trace decode. */
173 static struct btrace_cpu record_btrace_cpu
;
175 /* Command lists for "set/show record btrace". */
176 static struct cmd_list_element
*set_record_btrace_cmdlist
;
177 static struct cmd_list_element
*show_record_btrace_cmdlist
;
179 /* The execution direction of the last resume we got. See record-full.c. */
180 static enum exec_direction_kind record_btrace_resume_exec_dir
= EXEC_FORWARD
;
182 /* The async event handler for reverse/replay execution. */
183 static struct async_event_handler
*record_btrace_async_inferior_event_handler
;
185 /* A flag indicating that we are currently generating a core file. */
186 static int record_btrace_generating_corefile
;
188 /* The current branch trace configuration. */
189 static struct btrace_config record_btrace_conf
;
191 /* Command list for "record btrace". */
192 static struct cmd_list_element
*record_btrace_cmdlist
;
194 /* Command lists for "set/show record btrace bts". */
195 static struct cmd_list_element
*set_record_btrace_bts_cmdlist
;
196 static struct cmd_list_element
*show_record_btrace_bts_cmdlist
;
198 /* Command lists for "set/show record btrace pt". */
199 static struct cmd_list_element
*set_record_btrace_pt_cmdlist
;
200 static struct cmd_list_element
*show_record_btrace_pt_cmdlist
;
202 /* Command list for "set record btrace cpu". */
203 static struct cmd_list_element
*set_record_btrace_cpu_cmdlist
;
205 /* Print a record-btrace debug message. Use do ... while (0) to avoid
206 ambiguities when used in if statements. */
208 #define DEBUG(msg, args...) \
211 if (record_debug != 0) \
212 fprintf_unfiltered (gdb_stdlog, \
213 "[record-btrace] " msg "\n", ##args); \
218 /* Return the cpu configured by the user. Returns NULL if the cpu was
219 configured as auto. */
220 const struct btrace_cpu
*
221 record_btrace_get_cpu (void)
223 switch (record_btrace_cpu_state
)
229 record_btrace_cpu
.vendor
= CV_UNKNOWN
;
232 return &record_btrace_cpu
;
235 error (_("Internal error: bad record btrace cpu state."));
238 /* Update the branch trace for the current thread and return a pointer to its
241 Throws an error if there is no thread or no trace. This function never
244 static struct thread_info
*
245 require_btrace_thread (void)
249 if (inferior_ptid
== null_ptid
)
250 error (_("No thread."));
252 thread_info
*tp
= inferior_thread ();
254 validate_registers_access ();
256 btrace_fetch (tp
, record_btrace_get_cpu ());
258 if (btrace_is_empty (tp
))
259 error (_("No trace."));
264 /* Update the branch trace for the current thread and return a pointer to its
265 branch trace information struct.
267 Throws an error if there is no thread or no trace. This function never
270 static struct btrace_thread_info
*
271 require_btrace (void)
273 struct thread_info
*tp
;
275 tp
= require_btrace_thread ();
280 /* Enable branch tracing for one thread. Warn on errors. */
283 record_btrace_enable_warn (struct thread_info
*tp
)
287 btrace_enable (tp
, &record_btrace_conf
);
289 CATCH (error
, RETURN_MASK_ERROR
)
291 warning ("%s", error
.message
);
296 /* Enable automatic tracing of new threads. */
299 record_btrace_auto_enable (void)
301 DEBUG ("attach thread observer");
303 gdb::observers::new_thread
.attach (record_btrace_enable_warn
,
304 record_btrace_thread_observer_token
);
307 /* Disable automatic tracing of new threads. */
310 record_btrace_auto_disable (void)
312 DEBUG ("detach thread observer");
314 gdb::observers::new_thread
.detach (record_btrace_thread_observer_token
);
317 /* The record-btrace async event handler function. */
320 record_btrace_handle_async_inferior_event (gdb_client_data data
)
322 inferior_event_handler (INF_REG_EVENT
, NULL
);
325 /* See record-btrace.h. */
328 record_btrace_push_target (void)
332 record_btrace_auto_enable ();
334 push_target (&record_btrace_ops
);
336 record_btrace_async_inferior_event_handler
337 = create_async_event_handler (record_btrace_handle_async_inferior_event
,
339 record_btrace_generating_corefile
= 0;
341 format
= btrace_format_short_string (record_btrace_conf
.format
);
342 gdb::observers::record_changed
.notify (current_inferior (), 1, "btrace", format
);
345 /* Disable btrace on a set of threads on scope exit. */
347 struct scoped_btrace_disable
349 scoped_btrace_disable () = default;
351 DISABLE_COPY_AND_ASSIGN (scoped_btrace_disable
);
353 ~scoped_btrace_disable ()
355 for (thread_info
*tp
: m_threads
)
359 void add_thread (thread_info
*thread
)
361 m_threads
.push_front (thread
);
370 std::forward_list
<thread_info
*> m_threads
;
373 /* Open target record-btrace. */
376 record_btrace_target_open (const char *args
, int from_tty
)
378 /* If we fail to enable btrace for one thread, disable it for the threads for
379 which it was successfully enabled. */
380 scoped_btrace_disable btrace_disable
;
386 if (!target_has_execution
)
387 error (_("The program is not being run."));
389 for (thread_info
*tp
: all_non_exited_threads ())
390 if (args
== NULL
|| *args
== 0 || number_is_in_list (args
, tp
->global_num
))
392 btrace_enable (tp
, &record_btrace_conf
);
394 btrace_disable
.add_thread (tp
);
397 record_btrace_push_target ();
399 btrace_disable
.discard ();
402 /* The stop_recording method of target record-btrace. */
405 record_btrace_target::stop_recording ()
407 DEBUG ("stop recording");
409 record_btrace_auto_disable ();
411 for (thread_info
*tp
: all_non_exited_threads ())
412 if (tp
->btrace
.target
!= NULL
)
416 /* The disconnect method of target record-btrace. */
419 record_btrace_target::disconnect (const char *args
,
422 struct target_ops
*beneath
= this->beneath ();
424 /* Do not stop recording, just clean up GDB side. */
425 unpush_target (this);
427 /* Forward disconnect. */
428 beneath
->disconnect (args
, from_tty
);
431 /* The close method of target record-btrace. */
434 record_btrace_target::close ()
436 if (record_btrace_async_inferior_event_handler
!= NULL
)
437 delete_async_event_handler (&record_btrace_async_inferior_event_handler
);
439 /* Make sure automatic recording gets disabled even if we did not stop
440 recording before closing the record-btrace target. */
441 record_btrace_auto_disable ();
443 /* We should have already stopped recording.
444 Tear down btrace in case we have not. */
445 for (thread_info
*tp
: all_non_exited_threads ())
446 btrace_teardown (tp
);
449 /* The async method of target record-btrace. */
452 record_btrace_target::async (int enable
)
455 mark_async_event_handler (record_btrace_async_inferior_event_handler
);
457 clear_async_event_handler (record_btrace_async_inferior_event_handler
);
459 this->beneath ()->async (enable
);
462 /* Adjusts the size and returns a human readable size suffix. */
465 record_btrace_adjust_size (unsigned int *size
)
471 if ((sz
& ((1u << 30) - 1)) == 0)
476 else if ((sz
& ((1u << 20) - 1)) == 0)
481 else if ((sz
& ((1u << 10) - 1)) == 0)
490 /* Print a BTS configuration. */
493 record_btrace_print_bts_conf (const struct btrace_config_bts
*conf
)
501 suffix
= record_btrace_adjust_size (&size
);
502 printf_unfiltered (_("Buffer size: %u%s.\n"), size
, suffix
);
506 /* Print an Intel Processor Trace configuration. */
509 record_btrace_print_pt_conf (const struct btrace_config_pt
*conf
)
517 suffix
= record_btrace_adjust_size (&size
);
518 printf_unfiltered (_("Buffer size: %u%s.\n"), size
, suffix
);
522 /* Print a branch tracing configuration. */
525 record_btrace_print_conf (const struct btrace_config
*conf
)
527 printf_unfiltered (_("Recording format: %s.\n"),
528 btrace_format_string (conf
->format
));
530 switch (conf
->format
)
532 case BTRACE_FORMAT_NONE
:
535 case BTRACE_FORMAT_BTS
:
536 record_btrace_print_bts_conf (&conf
->bts
);
539 case BTRACE_FORMAT_PT
:
540 record_btrace_print_pt_conf (&conf
->pt
);
544 internal_error (__FILE__
, __LINE__
, _("Unkown branch trace format."));
547 /* The info_record method of target record-btrace. */
550 record_btrace_target::info_record ()
552 struct btrace_thread_info
*btinfo
;
553 const struct btrace_config
*conf
;
554 struct thread_info
*tp
;
555 unsigned int insns
, calls
, gaps
;
559 tp
= find_thread_ptid (inferior_ptid
);
561 error (_("No thread."));
563 validate_registers_access ();
565 btinfo
= &tp
->btrace
;
567 conf
= ::btrace_conf (btinfo
);
569 record_btrace_print_conf (conf
);
571 btrace_fetch (tp
, record_btrace_get_cpu ());
577 if (!btrace_is_empty (tp
))
579 struct btrace_call_iterator call
;
580 struct btrace_insn_iterator insn
;
582 btrace_call_end (&call
, btinfo
);
583 btrace_call_prev (&call
, 1);
584 calls
= btrace_call_number (&call
);
586 btrace_insn_end (&insn
, btinfo
);
587 insns
= btrace_insn_number (&insn
);
589 /* If the last instruction is not a gap, it is the current instruction
590 that is not actually part of the record. */
591 if (btrace_insn_get (&insn
) != NULL
)
594 gaps
= btinfo
->ngaps
;
597 printf_unfiltered (_("Recorded %u instructions in %u functions (%u gaps) "
598 "for thread %s (%s).\n"), insns
, calls
, gaps
,
599 print_thread_id (tp
),
600 target_pid_to_str (tp
->ptid
).c_str ());
602 if (btrace_is_replaying (tp
))
603 printf_unfiltered (_("Replay in progress. At instruction %u.\n"),
604 btrace_insn_number (btinfo
->replay
));
607 /* Print a decode error. */
610 btrace_ui_out_decode_error (struct ui_out
*uiout
, int errcode
,
611 enum btrace_format format
)
613 const char *errstr
= btrace_decode_error (format
, errcode
);
615 uiout
->text (_("["));
616 /* ERRCODE > 0 indicates notifications on BTRACE_FORMAT_PT. */
617 if (!(format
== BTRACE_FORMAT_PT
&& errcode
> 0))
619 uiout
->text (_("decode error ("));
620 uiout
->field_int ("errcode", errcode
);
621 uiout
->text (_("): "));
623 uiout
->text (errstr
);
624 uiout
->text (_("]\n"));
627 /* Print an unsigned int. */
630 ui_out_field_uint (struct ui_out
*uiout
, const char *fld
, unsigned int val
)
632 uiout
->field_fmt (fld
, "%u", val
);
635 /* A range of source lines. */
637 struct btrace_line_range
639 /* The symtab this line is from. */
640 struct symtab
*symtab
;
642 /* The first line (inclusive). */
645 /* The last line (exclusive). */
649 /* Construct a line range. */
651 static struct btrace_line_range
652 btrace_mk_line_range (struct symtab
*symtab
, int begin
, int end
)
654 struct btrace_line_range range
;
656 range
.symtab
= symtab
;
663 /* Add a line to a line range. */
665 static struct btrace_line_range
666 btrace_line_range_add (struct btrace_line_range range
, int line
)
668 if (range
.end
<= range
.begin
)
670 /* This is the first entry. */
672 range
.end
= line
+ 1;
674 else if (line
< range
.begin
)
676 else if (range
.end
< line
)
682 /* Return non-zero if RANGE is empty, zero otherwise. */
685 btrace_line_range_is_empty (struct btrace_line_range range
)
687 return range
.end
<= range
.begin
;
690 /* Return non-zero if LHS contains RHS, zero otherwise. */
693 btrace_line_range_contains_range (struct btrace_line_range lhs
,
694 struct btrace_line_range rhs
)
696 return ((lhs
.symtab
== rhs
.symtab
)
697 && (lhs
.begin
<= rhs
.begin
)
698 && (rhs
.end
<= lhs
.end
));
701 /* Find the line range associated with PC. */
703 static struct btrace_line_range
704 btrace_find_line_range (CORE_ADDR pc
)
706 struct btrace_line_range range
;
707 struct linetable_entry
*lines
;
708 struct linetable
*ltable
;
709 struct symtab
*symtab
;
712 symtab
= find_pc_line_symtab (pc
);
714 return btrace_mk_line_range (NULL
, 0, 0);
716 ltable
= SYMTAB_LINETABLE (symtab
);
718 return btrace_mk_line_range (symtab
, 0, 0);
720 nlines
= ltable
->nitems
;
721 lines
= ltable
->item
;
723 return btrace_mk_line_range (symtab
, 0, 0);
725 range
= btrace_mk_line_range (symtab
, 0, 0);
726 for (i
= 0; i
< nlines
- 1; i
++)
728 if ((lines
[i
].pc
== pc
) && (lines
[i
].line
!= 0))
729 range
= btrace_line_range_add (range
, lines
[i
].line
);
735 /* Print source lines in LINES to UIOUT.
737 UI_ITEM_CHAIN is a cleanup chain for the last source line and the
738 instructions corresponding to that source line. When printing a new source
739 line, we do the cleanups for the open chain and open a new cleanup chain for
740 the new source line. If the source line range in LINES is not empty, this
741 function will leave the cleanup chain for the last printed source line open
742 so instructions can be added to it. */
745 btrace_print_lines (struct btrace_line_range lines
, struct ui_out
*uiout
,
746 gdb::optional
<ui_out_emit_tuple
> *src_and_asm_tuple
,
747 gdb::optional
<ui_out_emit_list
> *asm_list
,
748 gdb_disassembly_flags flags
)
750 print_source_lines_flags psl_flags
;
752 if (flags
& DISASSEMBLY_FILENAME
)
753 psl_flags
|= PRINT_SOURCE_LINES_FILENAME
;
755 for (int line
= lines
.begin
; line
< lines
.end
; ++line
)
759 src_and_asm_tuple
->emplace (uiout
, "src_and_asm_line");
761 print_source_lines (lines
.symtab
, line
, line
+ 1, psl_flags
);
763 asm_list
->emplace (uiout
, "line_asm_insn");
767 /* Disassemble a section of the recorded instruction trace. */
770 btrace_insn_history (struct ui_out
*uiout
,
771 const struct btrace_thread_info
*btinfo
,
772 const struct btrace_insn_iterator
*begin
,
773 const struct btrace_insn_iterator
*end
,
774 gdb_disassembly_flags flags
)
776 DEBUG ("itrace (0x%x): [%u; %u)", (unsigned) flags
,
777 btrace_insn_number (begin
), btrace_insn_number (end
));
779 flags
|= DISASSEMBLY_SPECULATIVE
;
781 struct gdbarch
*gdbarch
= target_gdbarch ();
782 btrace_line_range last_lines
= btrace_mk_line_range (NULL
, 0, 0);
784 ui_out_emit_list
list_emitter (uiout
, "asm_insns");
786 gdb::optional
<ui_out_emit_tuple
> src_and_asm_tuple
;
787 gdb::optional
<ui_out_emit_list
> asm_list
;
789 gdb_pretty_print_disassembler
disasm (gdbarch
);
791 for (btrace_insn_iterator it
= *begin
; btrace_insn_cmp (&it
, end
) != 0;
792 btrace_insn_next (&it
, 1))
794 const struct btrace_insn
*insn
;
796 insn
= btrace_insn_get (&it
);
798 /* A NULL instruction indicates a gap in the trace. */
801 const struct btrace_config
*conf
;
803 conf
= btrace_conf (btinfo
);
805 /* We have trace so we must have a configuration. */
806 gdb_assert (conf
!= NULL
);
808 uiout
->field_fmt ("insn-number", "%u",
809 btrace_insn_number (&it
));
812 btrace_ui_out_decode_error (uiout
, btrace_insn_get_error (&it
),
817 struct disasm_insn dinsn
;
819 if ((flags
& DISASSEMBLY_SOURCE
) != 0)
821 struct btrace_line_range lines
;
823 lines
= btrace_find_line_range (insn
->pc
);
824 if (!btrace_line_range_is_empty (lines
)
825 && !btrace_line_range_contains_range (last_lines
, lines
))
827 btrace_print_lines (lines
, uiout
, &src_and_asm_tuple
, &asm_list
,
831 else if (!src_and_asm_tuple
.has_value ())
833 gdb_assert (!asm_list
.has_value ());
835 src_and_asm_tuple
.emplace (uiout
, "src_and_asm_line");
837 /* No source information. */
838 asm_list
.emplace (uiout
, "line_asm_insn");
841 gdb_assert (src_and_asm_tuple
.has_value ());
842 gdb_assert (asm_list
.has_value ());
845 memset (&dinsn
, 0, sizeof (dinsn
));
846 dinsn
.number
= btrace_insn_number (&it
);
847 dinsn
.addr
= insn
->pc
;
849 if ((insn
->flags
& BTRACE_INSN_FLAG_SPECULATIVE
) != 0)
850 dinsn
.is_speculative
= 1;
852 disasm
.pretty_print_insn (uiout
, &dinsn
, flags
);
857 /* The insn_history method of target record-btrace. */
860 record_btrace_target::insn_history (int size
, gdb_disassembly_flags flags
)
862 struct btrace_thread_info
*btinfo
;
863 struct btrace_insn_history
*history
;
864 struct btrace_insn_iterator begin
, end
;
865 struct ui_out
*uiout
;
866 unsigned int context
, covered
;
868 uiout
= current_uiout
;
869 ui_out_emit_tuple
tuple_emitter (uiout
, "insn history");
870 context
= abs (size
);
872 error (_("Bad record instruction-history-size."));
874 btinfo
= require_btrace ();
875 history
= btinfo
->insn_history
;
878 struct btrace_insn_iterator
*replay
;
880 DEBUG ("insn-history (0x%x): %d", (unsigned) flags
, size
);
882 /* If we're replaying, we start at the replay position. Otherwise, we
883 start at the tail of the trace. */
884 replay
= btinfo
->replay
;
888 btrace_insn_end (&begin
, btinfo
);
890 /* We start from here and expand in the requested direction. Then we
891 expand in the other direction, as well, to fill up any remaining
896 /* We want the current position covered, as well. */
897 covered
= btrace_insn_next (&end
, 1);
898 covered
+= btrace_insn_prev (&begin
, context
- covered
);
899 covered
+= btrace_insn_next (&end
, context
- covered
);
903 covered
= btrace_insn_next (&end
, context
);
904 covered
+= btrace_insn_prev (&begin
, context
- covered
);
909 begin
= history
->begin
;
912 DEBUG ("insn-history (0x%x): %d, prev: [%u; %u)", (unsigned) flags
, size
,
913 btrace_insn_number (&begin
), btrace_insn_number (&end
));
918 covered
= btrace_insn_prev (&begin
, context
);
923 covered
= btrace_insn_next (&end
, context
);
928 btrace_insn_history (uiout
, btinfo
, &begin
, &end
, flags
);
932 printf_unfiltered (_("At the start of the branch trace record.\n"));
934 printf_unfiltered (_("At the end of the branch trace record.\n"));
937 btrace_set_insn_history (btinfo
, &begin
, &end
);
940 /* The insn_history_range method of target record-btrace. */
943 record_btrace_target::insn_history_range (ULONGEST from
, ULONGEST to
,
944 gdb_disassembly_flags flags
)
946 struct btrace_thread_info
*btinfo
;
947 struct btrace_insn_iterator begin
, end
;
948 struct ui_out
*uiout
;
949 unsigned int low
, high
;
952 uiout
= current_uiout
;
953 ui_out_emit_tuple
tuple_emitter (uiout
, "insn history");
957 DEBUG ("insn-history (0x%x): [%u; %u)", (unsigned) flags
, low
, high
);
959 /* Check for wrap-arounds. */
960 if (low
!= from
|| high
!= to
)
961 error (_("Bad range."));
964 error (_("Bad range."));
966 btinfo
= require_btrace ();
968 found
= btrace_find_insn_by_number (&begin
, btinfo
, low
);
970 error (_("Range out of bounds."));
972 found
= btrace_find_insn_by_number (&end
, btinfo
, high
);
975 /* Silently truncate the range. */
976 btrace_insn_end (&end
, btinfo
);
980 /* We want both begin and end to be inclusive. */
981 btrace_insn_next (&end
, 1);
984 btrace_insn_history (uiout
, btinfo
, &begin
, &end
, flags
);
985 btrace_set_insn_history (btinfo
, &begin
, &end
);
988 /* The insn_history_from method of target record-btrace. */
991 record_btrace_target::insn_history_from (ULONGEST from
, int size
,
992 gdb_disassembly_flags flags
)
994 ULONGEST begin
, end
, context
;
996 context
= abs (size
);
998 error (_("Bad record instruction-history-size."));
1007 begin
= from
- context
+ 1;
1012 end
= from
+ context
- 1;
1014 /* Check for wrap-around. */
1019 insn_history_range (begin
, end
, flags
);
1022 /* Print the instruction number range for a function call history line. */
1025 btrace_call_history_insn_range (struct ui_out
*uiout
,
1026 const struct btrace_function
*bfun
)
1028 unsigned int begin
, end
, size
;
1030 size
= bfun
->insn
.size ();
1031 gdb_assert (size
> 0);
1033 begin
= bfun
->insn_offset
;
1034 end
= begin
+ size
- 1;
1036 ui_out_field_uint (uiout
, "insn begin", begin
);
1038 ui_out_field_uint (uiout
, "insn end", end
);
1041 /* Compute the lowest and highest source line for the instructions in BFUN
1042 and return them in PBEGIN and PEND.
1043 Ignore instructions that can't be mapped to BFUN, e.g. instructions that
1044 result from inlining or macro expansion. */
1047 btrace_compute_src_line_range (const struct btrace_function
*bfun
,
1048 int *pbegin
, int *pend
)
1050 struct symtab
*symtab
;
1061 symtab
= symbol_symtab (sym
);
1063 for (const btrace_insn
&insn
: bfun
->insn
)
1065 struct symtab_and_line sal
;
1067 sal
= find_pc_line (insn
.pc
, 0);
1068 if (sal
.symtab
!= symtab
|| sal
.line
== 0)
1071 begin
= std::min (begin
, sal
.line
);
1072 end
= std::max (end
, sal
.line
);
1080 /* Print the source line information for a function call history line. */
1083 btrace_call_history_src_line (struct ui_out
*uiout
,
1084 const struct btrace_function
*bfun
)
1093 uiout
->field_string ("file",
1094 symtab_to_filename_for_display (symbol_symtab (sym
)),
1095 ui_out_style_kind::FILE);
1097 btrace_compute_src_line_range (bfun
, &begin
, &end
);
1102 uiout
->field_int ("min line", begin
);
1108 uiout
->field_int ("max line", end
);
1111 /* Get the name of a branch trace function. */
1114 btrace_get_bfun_name (const struct btrace_function
*bfun
)
1116 struct minimal_symbol
*msym
;
1126 return SYMBOL_PRINT_NAME (sym
);
1127 else if (msym
!= NULL
)
1128 return MSYMBOL_PRINT_NAME (msym
);
1133 /* Disassemble a section of the recorded function trace. */
1136 btrace_call_history (struct ui_out
*uiout
,
1137 const struct btrace_thread_info
*btinfo
,
1138 const struct btrace_call_iterator
*begin
,
1139 const struct btrace_call_iterator
*end
,
1142 struct btrace_call_iterator it
;
1143 record_print_flags flags
= (enum record_print_flag
) int_flags
;
1145 DEBUG ("ftrace (0x%x): [%u; %u)", int_flags
, btrace_call_number (begin
),
1146 btrace_call_number (end
));
1148 for (it
= *begin
; btrace_call_cmp (&it
, end
) < 0; btrace_call_next (&it
, 1))
1150 const struct btrace_function
*bfun
;
1151 struct minimal_symbol
*msym
;
1154 bfun
= btrace_call_get (&it
);
1158 /* Print the function index. */
1159 ui_out_field_uint (uiout
, "index", bfun
->number
);
1162 /* Indicate gaps in the trace. */
1163 if (bfun
->errcode
!= 0)
1165 const struct btrace_config
*conf
;
1167 conf
= btrace_conf (btinfo
);
1169 /* We have trace so we must have a configuration. */
1170 gdb_assert (conf
!= NULL
);
1172 btrace_ui_out_decode_error (uiout
, bfun
->errcode
, conf
->format
);
1177 if ((flags
& RECORD_PRINT_INDENT_CALLS
) != 0)
1179 int level
= bfun
->level
+ btinfo
->level
, i
;
1181 for (i
= 0; i
< level
; ++i
)
1186 uiout
->field_string ("function", SYMBOL_PRINT_NAME (sym
),
1187 ui_out_style_kind::FUNCTION
);
1188 else if (msym
!= NULL
)
1189 uiout
->field_string ("function", MSYMBOL_PRINT_NAME (msym
),
1190 ui_out_style_kind::FUNCTION
);
1191 else if (!uiout
->is_mi_like_p ())
1192 uiout
->field_string ("function", "??",
1193 ui_out_style_kind::FUNCTION
);
1195 if ((flags
& RECORD_PRINT_INSN_RANGE
) != 0)
1197 uiout
->text (_("\tinst "));
1198 btrace_call_history_insn_range (uiout
, bfun
);
1201 if ((flags
& RECORD_PRINT_SRC_LINE
) != 0)
1203 uiout
->text (_("\tat "));
1204 btrace_call_history_src_line (uiout
, bfun
);
1211 /* The call_history method of target record-btrace. */
1214 record_btrace_target::call_history (int size
, record_print_flags flags
)
1216 struct btrace_thread_info
*btinfo
;
1217 struct btrace_call_history
*history
;
1218 struct btrace_call_iterator begin
, end
;
1219 struct ui_out
*uiout
;
1220 unsigned int context
, covered
;
1222 uiout
= current_uiout
;
1223 ui_out_emit_tuple
tuple_emitter (uiout
, "insn history");
1224 context
= abs (size
);
1226 error (_("Bad record function-call-history-size."));
1228 btinfo
= require_btrace ();
1229 history
= btinfo
->call_history
;
1230 if (history
== NULL
)
1232 struct btrace_insn_iterator
*replay
;
1234 DEBUG ("call-history (0x%x): %d", (int) flags
, size
);
1236 /* If we're replaying, we start at the replay position. Otherwise, we
1237 start at the tail of the trace. */
1238 replay
= btinfo
->replay
;
1241 begin
.btinfo
= btinfo
;
1242 begin
.index
= replay
->call_index
;
1245 btrace_call_end (&begin
, btinfo
);
1247 /* We start from here and expand in the requested direction. Then we
1248 expand in the other direction, as well, to fill up any remaining
1253 /* We want the current position covered, as well. */
1254 covered
= btrace_call_next (&end
, 1);
1255 covered
+= btrace_call_prev (&begin
, context
- covered
);
1256 covered
+= btrace_call_next (&end
, context
- covered
);
1260 covered
= btrace_call_next (&end
, context
);
1261 covered
+= btrace_call_prev (&begin
, context
- covered
);
1266 begin
= history
->begin
;
1269 DEBUG ("call-history (0x%x): %d, prev: [%u; %u)", (int) flags
, size
,
1270 btrace_call_number (&begin
), btrace_call_number (&end
));
1275 covered
= btrace_call_prev (&begin
, context
);
1280 covered
= btrace_call_next (&end
, context
);
1285 btrace_call_history (uiout
, btinfo
, &begin
, &end
, flags
);
1289 printf_unfiltered (_("At the start of the branch trace record.\n"));
1291 printf_unfiltered (_("At the end of the branch trace record.\n"));
1294 btrace_set_call_history (btinfo
, &begin
, &end
);
1297 /* The call_history_range method of target record-btrace. */
1300 record_btrace_target::call_history_range (ULONGEST from
, ULONGEST to
,
1301 record_print_flags flags
)
1303 struct btrace_thread_info
*btinfo
;
1304 struct btrace_call_iterator begin
, end
;
1305 struct ui_out
*uiout
;
1306 unsigned int low
, high
;
1309 uiout
= current_uiout
;
1310 ui_out_emit_tuple
tuple_emitter (uiout
, "func history");
1314 DEBUG ("call-history (0x%x): [%u; %u)", (int) flags
, low
, high
);
1316 /* Check for wrap-arounds. */
1317 if (low
!= from
|| high
!= to
)
1318 error (_("Bad range."));
1321 error (_("Bad range."));
1323 btinfo
= require_btrace ();
1325 found
= btrace_find_call_by_number (&begin
, btinfo
, low
);
1327 error (_("Range out of bounds."));
1329 found
= btrace_find_call_by_number (&end
, btinfo
, high
);
1332 /* Silently truncate the range. */
1333 btrace_call_end (&end
, btinfo
);
1337 /* We want both begin and end to be inclusive. */
1338 btrace_call_next (&end
, 1);
1341 btrace_call_history (uiout
, btinfo
, &begin
, &end
, flags
);
1342 btrace_set_call_history (btinfo
, &begin
, &end
);
1345 /* The call_history_from method of target record-btrace. */
1348 record_btrace_target::call_history_from (ULONGEST from
, int size
,
1349 record_print_flags flags
)
1351 ULONGEST begin
, end
, context
;
1353 context
= abs (size
);
1355 error (_("Bad record function-call-history-size."));
1364 begin
= from
- context
+ 1;
1369 end
= from
+ context
- 1;
1371 /* Check for wrap-around. */
1376 call_history_range ( begin
, end
, flags
);
1379 /* The record_method method of target record-btrace. */
1382 record_btrace_target::record_method (ptid_t ptid
)
1384 struct thread_info
* const tp
= find_thread_ptid (ptid
);
1387 error (_("No thread."));
1389 if (tp
->btrace
.target
== NULL
)
1390 return RECORD_METHOD_NONE
;
1392 return RECORD_METHOD_BTRACE
;
1395 /* The record_is_replaying method of target record-btrace. */
1398 record_btrace_target::record_is_replaying (ptid_t ptid
)
1400 for (thread_info
*tp
: all_non_exited_threads (ptid
))
1401 if (btrace_is_replaying (tp
))
1407 /* The record_will_replay method of target record-btrace. */
1410 record_btrace_target::record_will_replay (ptid_t ptid
, int dir
)
1412 return dir
== EXEC_REVERSE
|| record_is_replaying (ptid
);
1415 /* The xfer_partial method of target record-btrace. */
1417 enum target_xfer_status
1418 record_btrace_target::xfer_partial (enum target_object object
,
1419 const char *annex
, gdb_byte
*readbuf
,
1420 const gdb_byte
*writebuf
, ULONGEST offset
,
1421 ULONGEST len
, ULONGEST
*xfered_len
)
1423 /* Filter out requests that don't make sense during replay. */
1424 if (replay_memory_access
== replay_memory_access_read_only
1425 && !record_btrace_generating_corefile
1426 && record_is_replaying (inferior_ptid
))
1430 case TARGET_OBJECT_MEMORY
:
1432 struct target_section
*section
;
1434 /* We do not allow writing memory in general. */
1435 if (writebuf
!= NULL
)
1438 return TARGET_XFER_UNAVAILABLE
;
1441 /* We allow reading readonly memory. */
1442 section
= target_section_by_addr (this, offset
);
1443 if (section
!= NULL
)
1445 /* Check if the section we found is readonly. */
1446 if ((bfd_get_section_flags (section
->the_bfd_section
->owner
,
1447 section
->the_bfd_section
)
1448 & SEC_READONLY
) != 0)
1450 /* Truncate the request to fit into this section. */
1451 len
= std::min (len
, section
->endaddr
- offset
);
1457 return TARGET_XFER_UNAVAILABLE
;
1462 /* Forward the request. */
1463 return this->beneath ()->xfer_partial (object
, annex
, readbuf
, writebuf
,
1464 offset
, len
, xfered_len
);
1467 /* The insert_breakpoint method of target record-btrace. */
1470 record_btrace_target::insert_breakpoint (struct gdbarch
*gdbarch
,
1471 struct bp_target_info
*bp_tgt
)
1476 /* Inserting breakpoints requires accessing memory. Allow it for the
1477 duration of this function. */
1478 old
= replay_memory_access
;
1479 replay_memory_access
= replay_memory_access_read_write
;
1484 ret
= this->beneath ()->insert_breakpoint (gdbarch
, bp_tgt
);
1486 CATCH (except
, RETURN_MASK_ALL
)
1488 replay_memory_access
= old
;
1489 throw_exception (except
);
1492 replay_memory_access
= old
;
1497 /* The remove_breakpoint method of target record-btrace. */
1500 record_btrace_target::remove_breakpoint (struct gdbarch
*gdbarch
,
1501 struct bp_target_info
*bp_tgt
,
1502 enum remove_bp_reason reason
)
1507 /* Removing breakpoints requires accessing memory. Allow it for the
1508 duration of this function. */
1509 old
= replay_memory_access
;
1510 replay_memory_access
= replay_memory_access_read_write
;
1515 ret
= this->beneath ()->remove_breakpoint (gdbarch
, bp_tgt
, reason
);
1517 CATCH (except
, RETURN_MASK_ALL
)
1519 replay_memory_access
= old
;
1520 throw_exception (except
);
1523 replay_memory_access
= old
;
1528 /* The fetch_registers method of target record-btrace. */
1531 record_btrace_target::fetch_registers (struct regcache
*regcache
, int regno
)
1533 struct btrace_insn_iterator
*replay
;
1534 struct thread_info
*tp
;
1536 tp
= find_thread_ptid (regcache
->ptid ());
1537 gdb_assert (tp
!= NULL
);
1539 replay
= tp
->btrace
.replay
;
1540 if (replay
!= NULL
&& !record_btrace_generating_corefile
)
1542 const struct btrace_insn
*insn
;
1543 struct gdbarch
*gdbarch
;
1546 gdbarch
= regcache
->arch ();
1547 pcreg
= gdbarch_pc_regnum (gdbarch
);
1551 /* We can only provide the PC register. */
1552 if (regno
>= 0 && regno
!= pcreg
)
1555 insn
= btrace_insn_get (replay
);
1556 gdb_assert (insn
!= NULL
);
1558 regcache
->raw_supply (regno
, &insn
->pc
);
1561 this->beneath ()->fetch_registers (regcache
, regno
);
1564 /* The store_registers method of target record-btrace. */
1567 record_btrace_target::store_registers (struct regcache
*regcache
, int regno
)
1569 if (!record_btrace_generating_corefile
1570 && record_is_replaying (regcache
->ptid ()))
1571 error (_("Cannot write registers while replaying."));
1573 gdb_assert (may_write_registers
!= 0);
1575 this->beneath ()->store_registers (regcache
, regno
);
1578 /* The prepare_to_store method of target record-btrace. */
1581 record_btrace_target::prepare_to_store (struct regcache
*regcache
)
1583 if (!record_btrace_generating_corefile
1584 && record_is_replaying (regcache
->ptid ()))
1587 this->beneath ()->prepare_to_store (regcache
);
1590 /* The branch trace frame cache. */
1592 struct btrace_frame_cache
1595 struct thread_info
*tp
;
1597 /* The frame info. */
1598 struct frame_info
*frame
;
1600 /* The branch trace function segment. */
1601 const struct btrace_function
*bfun
;
1604 /* A struct btrace_frame_cache hash table indexed by NEXT. */
1606 static htab_t bfcache
;
1608 /* hash_f for htab_create_alloc of bfcache. */
1611 bfcache_hash (const void *arg
)
1613 const struct btrace_frame_cache
*cache
1614 = (const struct btrace_frame_cache
*) arg
;
1616 return htab_hash_pointer (cache
->frame
);
1619 /* eq_f for htab_create_alloc of bfcache. */
1622 bfcache_eq (const void *arg1
, const void *arg2
)
1624 const struct btrace_frame_cache
*cache1
1625 = (const struct btrace_frame_cache
*) arg1
;
1626 const struct btrace_frame_cache
*cache2
1627 = (const struct btrace_frame_cache
*) arg2
;
1629 return cache1
->frame
== cache2
->frame
;
1632 /* Create a new btrace frame cache. */
1634 static struct btrace_frame_cache
*
1635 bfcache_new (struct frame_info
*frame
)
1637 struct btrace_frame_cache
*cache
;
1640 cache
= FRAME_OBSTACK_ZALLOC (struct btrace_frame_cache
);
1641 cache
->frame
= frame
;
1643 slot
= htab_find_slot (bfcache
, cache
, INSERT
);
1644 gdb_assert (*slot
== NULL
);
1650 /* Extract the branch trace function from a branch trace frame. */
1652 static const struct btrace_function
*
1653 btrace_get_frame_function (struct frame_info
*frame
)
1655 const struct btrace_frame_cache
*cache
;
1656 struct btrace_frame_cache pattern
;
1659 pattern
.frame
= frame
;
1661 slot
= htab_find_slot (bfcache
, &pattern
, NO_INSERT
);
1665 cache
= (const struct btrace_frame_cache
*) *slot
;
1669 /* Implement stop_reason method for record_btrace_frame_unwind. */
1671 static enum unwind_stop_reason
1672 record_btrace_frame_unwind_stop_reason (struct frame_info
*this_frame
,
1675 const struct btrace_frame_cache
*cache
;
1676 const struct btrace_function
*bfun
;
1678 cache
= (const struct btrace_frame_cache
*) *this_cache
;
1680 gdb_assert (bfun
!= NULL
);
1683 return UNWIND_UNAVAILABLE
;
1685 return UNWIND_NO_REASON
;
1688 /* Implement this_id method for record_btrace_frame_unwind. */
1691 record_btrace_frame_this_id (struct frame_info
*this_frame
, void **this_cache
,
1692 struct frame_id
*this_id
)
1694 const struct btrace_frame_cache
*cache
;
1695 const struct btrace_function
*bfun
;
1696 struct btrace_call_iterator it
;
1697 CORE_ADDR code
, special
;
1699 cache
= (const struct btrace_frame_cache
*) *this_cache
;
1702 gdb_assert (bfun
!= NULL
);
1704 while (btrace_find_call_by_number (&it
, &cache
->tp
->btrace
, bfun
->prev
) != 0)
1705 bfun
= btrace_call_get (&it
);
1707 code
= get_frame_func (this_frame
);
1708 special
= bfun
->number
;
1710 *this_id
= frame_id_build_unavailable_stack_special (code
, special
);
1712 DEBUG ("[frame] %s id: (!stack, pc=%s, special=%s)",
1713 btrace_get_bfun_name (cache
->bfun
),
1714 core_addr_to_string_nz (this_id
->code_addr
),
1715 core_addr_to_string_nz (this_id
->special_addr
));
1718 /* Implement prev_register method for record_btrace_frame_unwind. */
1720 static struct value
*
1721 record_btrace_frame_prev_register (struct frame_info
*this_frame
,
1725 const struct btrace_frame_cache
*cache
;
1726 const struct btrace_function
*bfun
, *caller
;
1727 struct btrace_call_iterator it
;
1728 struct gdbarch
*gdbarch
;
1732 gdbarch
= get_frame_arch (this_frame
);
1733 pcreg
= gdbarch_pc_regnum (gdbarch
);
1734 if (pcreg
< 0 || regnum
!= pcreg
)
1735 throw_error (NOT_AVAILABLE_ERROR
,
1736 _("Registers are not available in btrace record history"));
1738 cache
= (const struct btrace_frame_cache
*) *this_cache
;
1740 gdb_assert (bfun
!= NULL
);
1742 if (btrace_find_call_by_number (&it
, &cache
->tp
->btrace
, bfun
->up
) == 0)
1743 throw_error (NOT_AVAILABLE_ERROR
,
1744 _("No caller in btrace record history"));
1746 caller
= btrace_call_get (&it
);
1748 if ((bfun
->flags
& BFUN_UP_LINKS_TO_RET
) != 0)
1749 pc
= caller
->insn
.front ().pc
;
1752 pc
= caller
->insn
.back ().pc
;
1753 pc
+= gdb_insn_length (gdbarch
, pc
);
1756 DEBUG ("[frame] unwound PC in %s on level %d: %s",
1757 btrace_get_bfun_name (bfun
), bfun
->level
,
1758 core_addr_to_string_nz (pc
));
1760 return frame_unwind_got_address (this_frame
, regnum
, pc
);
1763 /* Implement sniffer method for record_btrace_frame_unwind. */
1766 record_btrace_frame_sniffer (const struct frame_unwind
*self
,
1767 struct frame_info
*this_frame
,
1770 const struct btrace_function
*bfun
;
1771 struct btrace_frame_cache
*cache
;
1772 struct thread_info
*tp
;
1773 struct frame_info
*next
;
1775 /* THIS_FRAME does not contain a reference to its thread. */
1776 tp
= inferior_thread ();
1779 next
= get_next_frame (this_frame
);
1782 const struct btrace_insn_iterator
*replay
;
1784 replay
= tp
->btrace
.replay
;
1786 bfun
= &replay
->btinfo
->functions
[replay
->call_index
];
1790 const struct btrace_function
*callee
;
1791 struct btrace_call_iterator it
;
1793 callee
= btrace_get_frame_function (next
);
1794 if (callee
== NULL
|| (callee
->flags
& BFUN_UP_LINKS_TO_TAILCALL
) != 0)
1797 if (btrace_find_call_by_number (&it
, &tp
->btrace
, callee
->up
) == 0)
1800 bfun
= btrace_call_get (&it
);
1806 DEBUG ("[frame] sniffed frame for %s on level %d",
1807 btrace_get_bfun_name (bfun
), bfun
->level
);
1809 /* This is our frame. Initialize the frame cache. */
1810 cache
= bfcache_new (this_frame
);
1814 *this_cache
= cache
;
1818 /* Implement sniffer method for record_btrace_tailcall_frame_unwind. */
1821 record_btrace_tailcall_frame_sniffer (const struct frame_unwind
*self
,
1822 struct frame_info
*this_frame
,
1825 const struct btrace_function
*bfun
, *callee
;
1826 struct btrace_frame_cache
*cache
;
1827 struct btrace_call_iterator it
;
1828 struct frame_info
*next
;
1829 struct thread_info
*tinfo
;
1831 next
= get_next_frame (this_frame
);
1835 callee
= btrace_get_frame_function (next
);
1839 if ((callee
->flags
& BFUN_UP_LINKS_TO_TAILCALL
) == 0)
1842 tinfo
= inferior_thread ();
1843 if (btrace_find_call_by_number (&it
, &tinfo
->btrace
, callee
->up
) == 0)
1846 bfun
= btrace_call_get (&it
);
1848 DEBUG ("[frame] sniffed tailcall frame for %s on level %d",
1849 btrace_get_bfun_name (bfun
), bfun
->level
);
1851 /* This is our frame. Initialize the frame cache. */
1852 cache
= bfcache_new (this_frame
);
1856 *this_cache
= cache
;
1861 record_btrace_frame_dealloc_cache (struct frame_info
*self
, void *this_cache
)
1863 struct btrace_frame_cache
*cache
;
1866 cache
= (struct btrace_frame_cache
*) this_cache
;
1868 slot
= htab_find_slot (bfcache
, cache
, NO_INSERT
);
1869 gdb_assert (slot
!= NULL
);
1871 htab_remove_elt (bfcache
, cache
);
1874 /* btrace recording does not store previous memory content, neither the stack
1875 frames content. Any unwinding would return errorneous results as the stack
1876 contents no longer matches the changed PC value restored from history.
1877 Therefore this unwinder reports any possibly unwound registers as
1880 const struct frame_unwind record_btrace_frame_unwind
=
1883 record_btrace_frame_unwind_stop_reason
,
1884 record_btrace_frame_this_id
,
1885 record_btrace_frame_prev_register
,
1887 record_btrace_frame_sniffer
,
1888 record_btrace_frame_dealloc_cache
1891 const struct frame_unwind record_btrace_tailcall_frame_unwind
=
1894 record_btrace_frame_unwind_stop_reason
,
1895 record_btrace_frame_this_id
,
1896 record_btrace_frame_prev_register
,
1898 record_btrace_tailcall_frame_sniffer
,
1899 record_btrace_frame_dealloc_cache
1902 /* Implement the get_unwinder method. */
1904 const struct frame_unwind
*
1905 record_btrace_target::get_unwinder ()
1907 return &record_btrace_frame_unwind
;
1910 /* Implement the get_tailcall_unwinder method. */
1912 const struct frame_unwind
*
1913 record_btrace_target::get_tailcall_unwinder ()
1915 return &record_btrace_tailcall_frame_unwind
;
1918 /* Return a human-readable string for FLAG. */
1921 btrace_thread_flag_to_str (enum btrace_thread_flag flag
)
1929 return "reverse-step";
1935 return "reverse-cont";
1944 /* Indicate that TP should be resumed according to FLAG. */
1947 record_btrace_resume_thread (struct thread_info
*tp
,
1948 enum btrace_thread_flag flag
)
1950 struct btrace_thread_info
*btinfo
;
1952 DEBUG ("resuming thread %s (%s): %x (%s)", print_thread_id (tp
),
1953 target_pid_to_str (tp
->ptid
).c_str (), flag
,
1954 btrace_thread_flag_to_str (flag
));
1956 btinfo
= &tp
->btrace
;
1958 /* Fetch the latest branch trace. */
1959 btrace_fetch (tp
, record_btrace_get_cpu ());
1961 /* A resume request overwrites a preceding resume or stop request. */
1962 btinfo
->flags
&= ~(BTHR_MOVE
| BTHR_STOP
);
1963 btinfo
->flags
|= flag
;
1966 /* Get the current frame for TP. */
1968 static struct frame_id
1969 get_thread_current_frame_id (struct thread_info
*tp
)
1974 /* Set current thread, which is implicitly used by
1975 get_current_frame. */
1976 scoped_restore_current_thread restore_thread
;
1978 switch_to_thread (tp
);
1980 /* Clear the executing flag to allow changes to the current frame.
1981 We are not actually running, yet. We just started a reverse execution
1982 command or a record goto command.
1983 For the latter, EXECUTING is false and this has no effect.
1984 For the former, EXECUTING is true and we're in wait, about to
1985 move the thread. Since we need to recompute the stack, we temporarily
1986 set EXECUTING to flase. */
1987 executing
= tp
->executing
;
1988 set_executing (inferior_ptid
, false);
1993 id
= get_frame_id (get_current_frame ());
1995 CATCH (except
, RETURN_MASK_ALL
)
1997 /* Restore the previous execution state. */
1998 set_executing (inferior_ptid
, executing
);
2000 throw_exception (except
);
2004 /* Restore the previous execution state. */
2005 set_executing (inferior_ptid
, executing
);
2010 /* Start replaying a thread. */
2012 static struct btrace_insn_iterator
*
2013 record_btrace_start_replaying (struct thread_info
*tp
)
2015 struct btrace_insn_iterator
*replay
;
2016 struct btrace_thread_info
*btinfo
;
2018 btinfo
= &tp
->btrace
;
2021 /* We can't start replaying without trace. */
2022 if (btinfo
->functions
.empty ())
2025 /* GDB stores the current frame_id when stepping in order to detects steps
2027 Since frames are computed differently when we're replaying, we need to
2028 recompute those stored frames and fix them up so we can still detect
2029 subroutines after we started replaying. */
2032 struct frame_id frame_id
;
2033 int upd_step_frame_id
, upd_step_stack_frame_id
;
2035 /* The current frame without replaying - computed via normal unwind. */
2036 frame_id
= get_thread_current_frame_id (tp
);
2038 /* Check if we need to update any stepping-related frame id's. */
2039 upd_step_frame_id
= frame_id_eq (frame_id
,
2040 tp
->control
.step_frame_id
);
2041 upd_step_stack_frame_id
= frame_id_eq (frame_id
,
2042 tp
->control
.step_stack_frame_id
);
2044 /* We start replaying at the end of the branch trace. This corresponds
2045 to the current instruction. */
2046 replay
= XNEW (struct btrace_insn_iterator
);
2047 btrace_insn_end (replay
, btinfo
);
2049 /* Skip gaps at the end of the trace. */
2050 while (btrace_insn_get (replay
) == NULL
)
2054 steps
= btrace_insn_prev (replay
, 1);
2056 error (_("No trace."));
2059 /* We're not replaying, yet. */
2060 gdb_assert (btinfo
->replay
== NULL
);
2061 btinfo
->replay
= replay
;
2063 /* Make sure we're not using any stale registers. */
2064 registers_changed_thread (tp
);
2066 /* The current frame with replaying - computed via btrace unwind. */
2067 frame_id
= get_thread_current_frame_id (tp
);
2069 /* Replace stepping related frames where necessary. */
2070 if (upd_step_frame_id
)
2071 tp
->control
.step_frame_id
= frame_id
;
2072 if (upd_step_stack_frame_id
)
2073 tp
->control
.step_stack_frame_id
= frame_id
;
2075 CATCH (except
, RETURN_MASK_ALL
)
2077 xfree (btinfo
->replay
);
2078 btinfo
->replay
= NULL
;
2080 registers_changed_thread (tp
);
2082 throw_exception (except
);
2089 /* Stop replaying a thread. */
2092 record_btrace_stop_replaying (struct thread_info
*tp
)
2094 struct btrace_thread_info
*btinfo
;
2096 btinfo
= &tp
->btrace
;
2098 xfree (btinfo
->replay
);
2099 btinfo
->replay
= NULL
;
2101 /* Make sure we're not leaving any stale registers. */
2102 registers_changed_thread (tp
);
2105 /* Stop replaying TP if it is at the end of its execution history. */
2108 record_btrace_stop_replaying_at_end (struct thread_info
*tp
)
2110 struct btrace_insn_iterator
*replay
, end
;
2111 struct btrace_thread_info
*btinfo
;
2113 btinfo
= &tp
->btrace
;
2114 replay
= btinfo
->replay
;
2119 btrace_insn_end (&end
, btinfo
);
2121 if (btrace_insn_cmp (replay
, &end
) == 0)
2122 record_btrace_stop_replaying (tp
);
2125 /* The resume method of target record-btrace. */
2128 record_btrace_target::resume (ptid_t ptid
, int step
, enum gdb_signal signal
)
2130 enum btrace_thread_flag flag
, cflag
;
2132 DEBUG ("resume %s: %s%s", target_pid_to_str (ptid
).c_str (),
2133 ::execution_direction
== EXEC_REVERSE
? "reverse-" : "",
2134 step
? "step" : "cont");
2136 /* Store the execution direction of the last resume.
2138 If there is more than one resume call, we have to rely on infrun
2139 to not change the execution direction in-between. */
2140 record_btrace_resume_exec_dir
= ::execution_direction
;
2142 /* As long as we're not replaying, just forward the request.
2144 For non-stop targets this means that no thread is replaying. In order to
2145 make progress, we may need to explicitly move replaying threads to the end
2146 of their execution history. */
2147 if ((::execution_direction
!= EXEC_REVERSE
)
2148 && !record_is_replaying (minus_one_ptid
))
2150 this->beneath ()->resume (ptid
, step
, signal
);
2154 /* Compute the btrace thread flag for the requested move. */
2155 if (::execution_direction
== EXEC_REVERSE
)
2157 flag
= step
== 0 ? BTHR_RCONT
: BTHR_RSTEP
;
2162 flag
= step
== 0 ? BTHR_CONT
: BTHR_STEP
;
2166 /* We just indicate the resume intent here. The actual stepping happens in
2167 record_btrace_wait below.
2169 For all-stop targets, we only step INFERIOR_PTID and continue others. */
2170 if (!target_is_non_stop_p ())
2172 gdb_assert (inferior_ptid
.matches (ptid
));
2174 for (thread_info
*tp
: all_non_exited_threads (ptid
))
2176 if (tp
->ptid
.matches (inferior_ptid
))
2177 record_btrace_resume_thread (tp
, flag
);
2179 record_btrace_resume_thread (tp
, cflag
);
2184 for (thread_info
*tp
: all_non_exited_threads (ptid
))
2185 record_btrace_resume_thread (tp
, flag
);
2188 /* Async support. */
2189 if (target_can_async_p ())
2192 mark_async_event_handler (record_btrace_async_inferior_event_handler
);
2196 /* The commit_resume method of target record-btrace. */
2199 record_btrace_target::commit_resume ()
2201 if ((::execution_direction
!= EXEC_REVERSE
)
2202 && !record_is_replaying (minus_one_ptid
))
2203 beneath ()->commit_resume ();
2206 /* Cancel resuming TP. */
2209 record_btrace_cancel_resume (struct thread_info
*tp
)
2211 enum btrace_thread_flag flags
;
2213 flags
= tp
->btrace
.flags
& (BTHR_MOVE
| BTHR_STOP
);
2217 DEBUG ("cancel resume thread %s (%s): %x (%s)",
2218 print_thread_id (tp
),
2219 target_pid_to_str (tp
->ptid
).c_str (), flags
,
2220 btrace_thread_flag_to_str (flags
));
2222 tp
->btrace
.flags
&= ~(BTHR_MOVE
| BTHR_STOP
);
2223 record_btrace_stop_replaying_at_end (tp
);
2226 /* Return a target_waitstatus indicating that we ran out of history. */
2228 static struct target_waitstatus
2229 btrace_step_no_history (void)
2231 struct target_waitstatus status
;
2233 status
.kind
= TARGET_WAITKIND_NO_HISTORY
;
2238 /* Return a target_waitstatus indicating that a step finished. */
2240 static struct target_waitstatus
2241 btrace_step_stopped (void)
2243 struct target_waitstatus status
;
2245 status
.kind
= TARGET_WAITKIND_STOPPED
;
2246 status
.value
.sig
= GDB_SIGNAL_TRAP
;
2251 /* Return a target_waitstatus indicating that a thread was stopped as
2254 static struct target_waitstatus
2255 btrace_step_stopped_on_request (void)
2257 struct target_waitstatus status
;
2259 status
.kind
= TARGET_WAITKIND_STOPPED
;
2260 status
.value
.sig
= GDB_SIGNAL_0
;
2265 /* Return a target_waitstatus indicating a spurious stop. */
2267 static struct target_waitstatus
2268 btrace_step_spurious (void)
2270 struct target_waitstatus status
;
2272 status
.kind
= TARGET_WAITKIND_SPURIOUS
;
2277 /* Return a target_waitstatus indicating that the thread was not resumed. */
2279 static struct target_waitstatus
2280 btrace_step_no_resumed (void)
2282 struct target_waitstatus status
;
2284 status
.kind
= TARGET_WAITKIND_NO_RESUMED
;
2289 /* Return a target_waitstatus indicating that we should wait again. */
2291 static struct target_waitstatus
2292 btrace_step_again (void)
2294 struct target_waitstatus status
;
2296 status
.kind
= TARGET_WAITKIND_IGNORE
;
2301 /* Clear the record histories. */
2304 record_btrace_clear_histories (struct btrace_thread_info
*btinfo
)
2306 xfree (btinfo
->insn_history
);
2307 xfree (btinfo
->call_history
);
2309 btinfo
->insn_history
= NULL
;
2310 btinfo
->call_history
= NULL
;
2313 /* Check whether TP's current replay position is at a breakpoint. */
2316 record_btrace_replay_at_breakpoint (struct thread_info
*tp
)
2318 struct btrace_insn_iterator
*replay
;
2319 struct btrace_thread_info
*btinfo
;
2320 const struct btrace_insn
*insn
;
2322 btinfo
= &tp
->btrace
;
2323 replay
= btinfo
->replay
;
2328 insn
= btrace_insn_get (replay
);
2332 return record_check_stopped_by_breakpoint (tp
->inf
->aspace
, insn
->pc
,
2333 &btinfo
->stop_reason
);
2336 /* Step one instruction in forward direction. */
2338 static struct target_waitstatus
2339 record_btrace_single_step_forward (struct thread_info
*tp
)
2341 struct btrace_insn_iterator
*replay
, end
, start
;
2342 struct btrace_thread_info
*btinfo
;
2344 btinfo
= &tp
->btrace
;
2345 replay
= btinfo
->replay
;
2347 /* We're done if we're not replaying. */
2349 return btrace_step_no_history ();
2351 /* Check if we're stepping a breakpoint. */
2352 if (record_btrace_replay_at_breakpoint (tp
))
2353 return btrace_step_stopped ();
2355 /* Skip gaps during replay. If we end up at a gap (at the end of the trace),
2356 jump back to the instruction at which we started. */
2362 /* We will bail out here if we continue stepping after reaching the end
2363 of the execution history. */
2364 steps
= btrace_insn_next (replay
, 1);
2368 return btrace_step_no_history ();
2371 while (btrace_insn_get (replay
) == NULL
);
2373 /* Determine the end of the instruction trace. */
2374 btrace_insn_end (&end
, btinfo
);
2376 /* The execution trace contains (and ends with) the current instruction.
2377 This instruction has not been executed, yet, so the trace really ends
2378 one instruction earlier. */
2379 if (btrace_insn_cmp (replay
, &end
) == 0)
2380 return btrace_step_no_history ();
2382 return btrace_step_spurious ();
2385 /* Step one instruction in backward direction. */
2387 static struct target_waitstatus
2388 record_btrace_single_step_backward (struct thread_info
*tp
)
2390 struct btrace_insn_iterator
*replay
, start
;
2391 struct btrace_thread_info
*btinfo
;
2393 btinfo
= &tp
->btrace
;
2394 replay
= btinfo
->replay
;
2396 /* Start replaying if we're not already doing so. */
2398 replay
= record_btrace_start_replaying (tp
);
2400 /* If we can't step any further, we reached the end of the history.
2401 Skip gaps during replay. If we end up at a gap (at the beginning of
2402 the trace), jump back to the instruction at which we started. */
2408 steps
= btrace_insn_prev (replay
, 1);
2412 return btrace_step_no_history ();
2415 while (btrace_insn_get (replay
) == NULL
);
2417 /* Check if we're stepping a breakpoint.
2419 For reverse-stepping, this check is after the step. There is logic in
2420 infrun.c that handles reverse-stepping separately. See, for example,
2421 proceed and adjust_pc_after_break.
2423 This code assumes that for reverse-stepping, PC points to the last
2424 de-executed instruction, whereas for forward-stepping PC points to the
2425 next to-be-executed instruction. */
2426 if (record_btrace_replay_at_breakpoint (tp
))
2427 return btrace_step_stopped ();
2429 return btrace_step_spurious ();
2432 /* Step a single thread. */
2434 static struct target_waitstatus
2435 record_btrace_step_thread (struct thread_info
*tp
)
2437 struct btrace_thread_info
*btinfo
;
2438 struct target_waitstatus status
;
2439 enum btrace_thread_flag flags
;
2441 btinfo
= &tp
->btrace
;
2443 flags
= btinfo
->flags
& (BTHR_MOVE
| BTHR_STOP
);
2444 btinfo
->flags
&= ~(BTHR_MOVE
| BTHR_STOP
);
2446 DEBUG ("stepping thread %s (%s): %x (%s)", print_thread_id (tp
),
2447 target_pid_to_str (tp
->ptid
).c_str (), flags
,
2448 btrace_thread_flag_to_str (flags
));
2450 /* We can't step without an execution history. */
2451 if ((flags
& BTHR_MOVE
) != 0 && btrace_is_empty (tp
))
2452 return btrace_step_no_history ();
2457 internal_error (__FILE__
, __LINE__
, _("invalid stepping type."));
2460 return btrace_step_stopped_on_request ();
2463 status
= record_btrace_single_step_forward (tp
);
2464 if (status
.kind
!= TARGET_WAITKIND_SPURIOUS
)
2467 return btrace_step_stopped ();
2470 status
= record_btrace_single_step_backward (tp
);
2471 if (status
.kind
!= TARGET_WAITKIND_SPURIOUS
)
2474 return btrace_step_stopped ();
2477 status
= record_btrace_single_step_forward (tp
);
2478 if (status
.kind
!= TARGET_WAITKIND_SPURIOUS
)
2481 btinfo
->flags
|= flags
;
2482 return btrace_step_again ();
2485 status
= record_btrace_single_step_backward (tp
);
2486 if (status
.kind
!= TARGET_WAITKIND_SPURIOUS
)
2489 btinfo
->flags
|= flags
;
2490 return btrace_step_again ();
2493 /* We keep threads moving at the end of their execution history. The wait
2494 method will stop the thread for whom the event is reported. */
2495 if (status
.kind
== TARGET_WAITKIND_NO_HISTORY
)
2496 btinfo
->flags
|= flags
;
2501 /* Announce further events if necessary. */
2504 record_btrace_maybe_mark_async_event
2505 (const std::vector
<thread_info
*> &moving
,
2506 const std::vector
<thread_info
*> &no_history
)
2508 bool more_moving
= !moving
.empty ();
2509 bool more_no_history
= !no_history
.empty ();;
2511 if (!more_moving
&& !more_no_history
)
2515 DEBUG ("movers pending");
2517 if (more_no_history
)
2518 DEBUG ("no-history pending");
2520 mark_async_event_handler (record_btrace_async_inferior_event_handler
);
2523 /* The wait method of target record-btrace. */
2526 record_btrace_target::wait (ptid_t ptid
, struct target_waitstatus
*status
,
2529 std::vector
<thread_info
*> moving
;
2530 std::vector
<thread_info
*> no_history
;
2532 DEBUG ("wait %s (0x%x)", target_pid_to_str (ptid
).c_str (), options
);
2534 /* As long as we're not replaying, just forward the request. */
2535 if ((::execution_direction
!= EXEC_REVERSE
)
2536 && !record_is_replaying (minus_one_ptid
))
2538 return this->beneath ()->wait (ptid
, status
, options
);
2541 /* Keep a work list of moving threads. */
2542 for (thread_info
*tp
: all_non_exited_threads (ptid
))
2543 if ((tp
->btrace
.flags
& (BTHR_MOVE
| BTHR_STOP
)) != 0)
2544 moving
.push_back (tp
);
2546 if (moving
.empty ())
2548 *status
= btrace_step_no_resumed ();
2550 DEBUG ("wait ended by %s: %s", target_pid_to_str (null_ptid
).c_str (),
2551 target_waitstatus_to_string (status
).c_str ());
2556 /* Step moving threads one by one, one step each, until either one thread
2557 reports an event or we run out of threads to step.
2559 When stepping more than one thread, chances are that some threads reach
2560 the end of their execution history earlier than others. If we reported
2561 this immediately, all-stop on top of non-stop would stop all threads and
2562 resume the same threads next time. And we would report the same thread
2563 having reached the end of its execution history again.
2565 In the worst case, this would starve the other threads. But even if other
2566 threads would be allowed to make progress, this would result in far too
2567 many intermediate stops.
2569 We therefore delay the reporting of "no execution history" until we have
2570 nothing else to report. By this time, all threads should have moved to
2571 either the beginning or the end of their execution history. There will
2572 be a single user-visible stop. */
2573 struct thread_info
*eventing
= NULL
;
2574 while ((eventing
== NULL
) && !moving
.empty ())
2576 for (unsigned int ix
= 0; eventing
== NULL
&& ix
< moving
.size ();)
2578 thread_info
*tp
= moving
[ix
];
2580 *status
= record_btrace_step_thread (tp
);
2582 switch (status
->kind
)
2584 case TARGET_WAITKIND_IGNORE
:
2588 case TARGET_WAITKIND_NO_HISTORY
:
2589 no_history
.push_back (ordered_remove (moving
, ix
));
2593 eventing
= unordered_remove (moving
, ix
);
2599 if (eventing
== NULL
)
2601 /* We started with at least one moving thread. This thread must have
2602 either stopped or reached the end of its execution history.
2604 In the former case, EVENTING must not be NULL.
2605 In the latter case, NO_HISTORY must not be empty. */
2606 gdb_assert (!no_history
.empty ());
2608 /* We kept threads moving at the end of their execution history. Stop
2609 EVENTING now that we are going to report its stop. */
2610 eventing
= unordered_remove (no_history
, 0);
2611 eventing
->btrace
.flags
&= ~BTHR_MOVE
;
2613 *status
= btrace_step_no_history ();
2616 gdb_assert (eventing
!= NULL
);
2618 /* We kept threads replaying at the end of their execution history. Stop
2619 replaying EVENTING now that we are going to report its stop. */
2620 record_btrace_stop_replaying_at_end (eventing
);
2622 /* Stop all other threads. */
2623 if (!target_is_non_stop_p ())
2625 for (thread_info
*tp
: all_non_exited_threads ())
2626 record_btrace_cancel_resume (tp
);
2629 /* In async mode, we need to announce further events. */
2630 if (target_is_async_p ())
2631 record_btrace_maybe_mark_async_event (moving
, no_history
);
2633 /* Start record histories anew from the current position. */
2634 record_btrace_clear_histories (&eventing
->btrace
);
2636 /* We moved the replay position but did not update registers. */
2637 registers_changed_thread (eventing
);
2639 DEBUG ("wait ended by thread %s (%s): %s",
2640 print_thread_id (eventing
),
2641 target_pid_to_str (eventing
->ptid
).c_str (),
2642 target_waitstatus_to_string (status
).c_str ());
2644 return eventing
->ptid
;
2647 /* The stop method of target record-btrace. */
2650 record_btrace_target::stop (ptid_t ptid
)
2652 DEBUG ("stop %s", target_pid_to_str (ptid
).c_str ());
2654 /* As long as we're not replaying, just forward the request. */
2655 if ((::execution_direction
!= EXEC_REVERSE
)
2656 && !record_is_replaying (minus_one_ptid
))
2658 this->beneath ()->stop (ptid
);
2662 for (thread_info
*tp
: all_non_exited_threads (ptid
))
2664 tp
->btrace
.flags
&= ~BTHR_MOVE
;
2665 tp
->btrace
.flags
|= BTHR_STOP
;
2670 /* The can_execute_reverse method of target record-btrace. */
2673 record_btrace_target::can_execute_reverse ()
2678 /* The stopped_by_sw_breakpoint method of target record-btrace. */
2681 record_btrace_target::stopped_by_sw_breakpoint ()
2683 if (record_is_replaying (minus_one_ptid
))
2685 struct thread_info
*tp
= inferior_thread ();
2687 return tp
->btrace
.stop_reason
== TARGET_STOPPED_BY_SW_BREAKPOINT
;
2690 return this->beneath ()->stopped_by_sw_breakpoint ();
2693 /* The supports_stopped_by_sw_breakpoint method of target
2697 record_btrace_target::supports_stopped_by_sw_breakpoint ()
2699 if (record_is_replaying (minus_one_ptid
))
2702 return this->beneath ()->supports_stopped_by_sw_breakpoint ();
2705 /* The stopped_by_sw_breakpoint method of target record-btrace. */
2708 record_btrace_target::stopped_by_hw_breakpoint ()
2710 if (record_is_replaying (minus_one_ptid
))
2712 struct thread_info
*tp
= inferior_thread ();
2714 return tp
->btrace
.stop_reason
== TARGET_STOPPED_BY_HW_BREAKPOINT
;
2717 return this->beneath ()->stopped_by_hw_breakpoint ();
2720 /* The supports_stopped_by_hw_breakpoint method of target
2724 record_btrace_target::supports_stopped_by_hw_breakpoint ()
2726 if (record_is_replaying (minus_one_ptid
))
2729 return this->beneath ()->supports_stopped_by_hw_breakpoint ();
2732 /* The update_thread_list method of target record-btrace. */
2735 record_btrace_target::update_thread_list ()
2737 /* We don't add or remove threads during replay. */
2738 if (record_is_replaying (minus_one_ptid
))
2741 /* Forward the request. */
2742 this->beneath ()->update_thread_list ();
2745 /* The thread_alive method of target record-btrace. */
2748 record_btrace_target::thread_alive (ptid_t ptid
)
2750 /* We don't add or remove threads during replay. */
2751 if (record_is_replaying (minus_one_ptid
))
2754 /* Forward the request. */
2755 return this->beneath ()->thread_alive (ptid
);
2758 /* Set the replay branch trace instruction iterator. If IT is NULL, replay
2762 record_btrace_set_replay (struct thread_info
*tp
,
2763 const struct btrace_insn_iterator
*it
)
2765 struct btrace_thread_info
*btinfo
;
2767 btinfo
= &tp
->btrace
;
2770 record_btrace_stop_replaying (tp
);
2773 if (btinfo
->replay
== NULL
)
2774 record_btrace_start_replaying (tp
);
2775 else if (btrace_insn_cmp (btinfo
->replay
, it
) == 0)
2778 *btinfo
->replay
= *it
;
2779 registers_changed_thread (tp
);
2782 /* Start anew from the new replay position. */
2783 record_btrace_clear_histories (btinfo
);
2785 inferior_thread ()->suspend
.stop_pc
2786 = regcache_read_pc (get_current_regcache ());
2787 print_stack_frame (get_selected_frame (NULL
), 1, SRC_AND_LOC
, 1);
2790 /* The goto_record_begin method of target record-btrace. */
2793 record_btrace_target::goto_record_begin ()
2795 struct thread_info
*tp
;
2796 struct btrace_insn_iterator begin
;
2798 tp
= require_btrace_thread ();
2800 btrace_insn_begin (&begin
, &tp
->btrace
);
2802 /* Skip gaps at the beginning of the trace. */
2803 while (btrace_insn_get (&begin
) == NULL
)
2807 steps
= btrace_insn_next (&begin
, 1);
2809 error (_("No trace."));
2812 record_btrace_set_replay (tp
, &begin
);
2815 /* The goto_record_end method of target record-btrace. */
2818 record_btrace_target::goto_record_end ()
2820 struct thread_info
*tp
;
2822 tp
= require_btrace_thread ();
2824 record_btrace_set_replay (tp
, NULL
);
2827 /* The goto_record method of target record-btrace. */
2830 record_btrace_target::goto_record (ULONGEST insn
)
2832 struct thread_info
*tp
;
2833 struct btrace_insn_iterator it
;
2834 unsigned int number
;
2839 /* Check for wrap-arounds. */
2841 error (_("Instruction number out of range."));
2843 tp
= require_btrace_thread ();
2845 found
= btrace_find_insn_by_number (&it
, &tp
->btrace
, number
);
2847 /* Check if the instruction could not be found or is a gap. */
2848 if (found
== 0 || btrace_insn_get (&it
) == NULL
)
2849 error (_("No such instruction."));
2851 record_btrace_set_replay (tp
, &it
);
2854 /* The record_stop_replaying method of target record-btrace. */
2857 record_btrace_target::record_stop_replaying ()
2859 for (thread_info
*tp
: all_non_exited_threads ())
2860 record_btrace_stop_replaying (tp
);
2863 /* The execution_direction target method. */
2865 enum exec_direction_kind
2866 record_btrace_target::execution_direction ()
2868 return record_btrace_resume_exec_dir
;
2871 /* The prepare_to_generate_core target method. */
2874 record_btrace_target::prepare_to_generate_core ()
2876 record_btrace_generating_corefile
= 1;
2879 /* The done_generating_core target method. */
2882 record_btrace_target::done_generating_core ()
2884 record_btrace_generating_corefile
= 0;
2887 /* Start recording in BTS format. */
2890 cmd_record_btrace_bts_start (const char *args
, int from_tty
)
2892 if (args
!= NULL
&& *args
!= 0)
2893 error (_("Invalid argument."));
2895 record_btrace_conf
.format
= BTRACE_FORMAT_BTS
;
2899 execute_command ("target record-btrace", from_tty
);
2901 CATCH (exception
, RETURN_MASK_ALL
)
2903 record_btrace_conf
.format
= BTRACE_FORMAT_NONE
;
2904 throw_exception (exception
);
2909 /* Start recording in Intel Processor Trace format. */
2912 cmd_record_btrace_pt_start (const char *args
, int from_tty
)
2914 if (args
!= NULL
&& *args
!= 0)
2915 error (_("Invalid argument."));
2917 record_btrace_conf
.format
= BTRACE_FORMAT_PT
;
2921 execute_command ("target record-btrace", from_tty
);
2923 CATCH (exception
, RETURN_MASK_ALL
)
2925 record_btrace_conf
.format
= BTRACE_FORMAT_NONE
;
2926 throw_exception (exception
);
2931 /* Alias for "target record". */
2934 cmd_record_btrace_start (const char *args
, int from_tty
)
2936 if (args
!= NULL
&& *args
!= 0)
2937 error (_("Invalid argument."));
2939 record_btrace_conf
.format
= BTRACE_FORMAT_PT
;
2943 execute_command ("target record-btrace", from_tty
);
2945 CATCH (exception
, RETURN_MASK_ALL
)
2947 record_btrace_conf
.format
= BTRACE_FORMAT_BTS
;
2951 execute_command ("target record-btrace", from_tty
);
2953 CATCH (ex
, RETURN_MASK_ALL
)
2955 record_btrace_conf
.format
= BTRACE_FORMAT_NONE
;
2956 throw_exception (ex
);
2963 /* The "set record btrace" command. */
2966 cmd_set_record_btrace (const char *args
, int from_tty
)
2968 printf_unfiltered (_("\"set record btrace\" must be followed "
2969 "by an appropriate subcommand.\n"));
2970 help_list (set_record_btrace_cmdlist
, "set record btrace ",
2971 all_commands
, gdb_stdout
);
2974 /* The "show record btrace" command. */
2977 cmd_show_record_btrace (const char *args
, int from_tty
)
2979 cmd_show_list (show_record_btrace_cmdlist
, from_tty
, "");
2982 /* The "show record btrace replay-memory-access" command. */
2985 cmd_show_replay_memory_access (struct ui_file
*file
, int from_tty
,
2986 struct cmd_list_element
*c
, const char *value
)
2988 fprintf_filtered (gdb_stdout
, _("Replay memory access is %s.\n"),
2989 replay_memory_access
);
2992 /* The "set record btrace cpu none" command. */
2995 cmd_set_record_btrace_cpu_none (const char *args
, int from_tty
)
2997 if (args
!= nullptr && *args
!= 0)
2998 error (_("Trailing junk: '%s'."), args
);
3000 record_btrace_cpu_state
= CS_NONE
;
3003 /* The "set record btrace cpu auto" command. */
3006 cmd_set_record_btrace_cpu_auto (const char *args
, int from_tty
)
3008 if (args
!= nullptr && *args
!= 0)
3009 error (_("Trailing junk: '%s'."), args
);
3011 record_btrace_cpu_state
= CS_AUTO
;
3014 /* The "set record btrace cpu" command. */
3017 cmd_set_record_btrace_cpu (const char *args
, int from_tty
)
3019 if (args
== nullptr)
3022 /* We use a hard-coded vendor string for now. */
3023 unsigned int family
, model
, stepping
;
3024 int l1
, l2
, matches
= sscanf (args
, "intel: %u/%u%n/%u%n", &family
,
3025 &model
, &l1
, &stepping
, &l2
);
3028 if (strlen (args
) != l2
)
3029 error (_("Trailing junk: '%s'."), args
+ l2
);
3031 else if (matches
== 2)
3033 if (strlen (args
) != l1
)
3034 error (_("Trailing junk: '%s'."), args
+ l1
);
3039 error (_("Bad format. See \"help set record btrace cpu\"."));
3041 if (USHRT_MAX
< family
)
3042 error (_("Cpu family too big."));
3044 if (UCHAR_MAX
< model
)
3045 error (_("Cpu model too big."));
3047 if (UCHAR_MAX
< stepping
)
3048 error (_("Cpu stepping too big."));
3050 record_btrace_cpu
.vendor
= CV_INTEL
;
3051 record_btrace_cpu
.family
= family
;
3052 record_btrace_cpu
.model
= model
;
3053 record_btrace_cpu
.stepping
= stepping
;
3055 record_btrace_cpu_state
= CS_CPU
;
3058 /* The "show record btrace cpu" command. */
3061 cmd_show_record_btrace_cpu (const char *args
, int from_tty
)
3063 if (args
!= nullptr && *args
!= 0)
3064 error (_("Trailing junk: '%s'."), args
);
3066 switch (record_btrace_cpu_state
)
3069 printf_unfiltered (_("btrace cpu is 'auto'.\n"));
3073 printf_unfiltered (_("btrace cpu is 'none'.\n"));
3077 switch (record_btrace_cpu
.vendor
)
3080 if (record_btrace_cpu
.stepping
== 0)
3081 printf_unfiltered (_("btrace cpu is 'intel: %u/%u'.\n"),
3082 record_btrace_cpu
.family
,
3083 record_btrace_cpu
.model
);
3085 printf_unfiltered (_("btrace cpu is 'intel: %u/%u/%u'.\n"),
3086 record_btrace_cpu
.family
,
3087 record_btrace_cpu
.model
,
3088 record_btrace_cpu
.stepping
);
3093 error (_("Internal error: bad cpu state."));
3096 /* The "s record btrace bts" command. */
3099 cmd_set_record_btrace_bts (const char *args
, int from_tty
)
3101 printf_unfiltered (_("\"set record btrace bts\" must be followed "
3102 "by an appropriate subcommand.\n"));
3103 help_list (set_record_btrace_bts_cmdlist
, "set record btrace bts ",
3104 all_commands
, gdb_stdout
);
3107 /* The "show record btrace bts" command. */
3110 cmd_show_record_btrace_bts (const char *args
, int from_tty
)
3112 cmd_show_list (show_record_btrace_bts_cmdlist
, from_tty
, "");
3115 /* The "set record btrace pt" command. */
3118 cmd_set_record_btrace_pt (const char *args
, int from_tty
)
3120 printf_unfiltered (_("\"set record btrace pt\" must be followed "
3121 "by an appropriate subcommand.\n"));
3122 help_list (set_record_btrace_pt_cmdlist
, "set record btrace pt ",
3123 all_commands
, gdb_stdout
);
3126 /* The "show record btrace pt" command. */
3129 cmd_show_record_btrace_pt (const char *args
, int from_tty
)
3131 cmd_show_list (show_record_btrace_pt_cmdlist
, from_tty
, "");
3134 /* The "record bts buffer-size" show value function. */
3137 show_record_bts_buffer_size_value (struct ui_file
*file
, int from_tty
,
3138 struct cmd_list_element
*c
,
3141 fprintf_filtered (file
, _("The record/replay bts buffer size is %s.\n"),
3145 /* The "record pt buffer-size" show value function. */
3148 show_record_pt_buffer_size_value (struct ui_file
*file
, int from_tty
,
3149 struct cmd_list_element
*c
,
3152 fprintf_filtered (file
, _("The record/replay pt buffer size is %s.\n"),
3156 /* Initialize btrace commands. */
3159 _initialize_record_btrace (void)
3161 add_prefix_cmd ("btrace", class_obscure
, cmd_record_btrace_start
,
3162 _("Start branch trace recording."), &record_btrace_cmdlist
,
3163 "record btrace ", 0, &record_cmdlist
);
3164 add_alias_cmd ("b", "btrace", class_obscure
, 1, &record_cmdlist
);
3166 add_cmd ("bts", class_obscure
, cmd_record_btrace_bts_start
,
3168 Start branch trace recording in Branch Trace Store (BTS) format.\n\n\
3169 The processor stores a from/to record for each branch into a cyclic buffer.\n\
3170 This format may not be available on all processors."),
3171 &record_btrace_cmdlist
);
3172 add_alias_cmd ("bts", "btrace bts", class_obscure
, 1, &record_cmdlist
);
3174 add_cmd ("pt", class_obscure
, cmd_record_btrace_pt_start
,
3176 Start branch trace recording in Intel Processor Trace format.\n\n\
3177 This format may not be available on all processors."),
3178 &record_btrace_cmdlist
);
3179 add_alias_cmd ("pt", "btrace pt", class_obscure
, 1, &record_cmdlist
);
3181 add_prefix_cmd ("btrace", class_support
, cmd_set_record_btrace
,
3182 _("Set record options"), &set_record_btrace_cmdlist
,
3183 "set record btrace ", 0, &set_record_cmdlist
);
3185 add_prefix_cmd ("btrace", class_support
, cmd_show_record_btrace
,
3186 _("Show record options"), &show_record_btrace_cmdlist
,
3187 "show record btrace ", 0, &show_record_cmdlist
);
3189 add_setshow_enum_cmd ("replay-memory-access", no_class
,
3190 replay_memory_access_types
, &replay_memory_access
, _("\
3191 Set what memory accesses are allowed during replay."), _("\
3192 Show what memory accesses are allowed during replay."),
3193 _("Default is READ-ONLY.\n\n\
3194 The btrace record target does not trace data.\n\
3195 The memory therefore corresponds to the live target and not \
3196 to the current replay position.\n\n\
3197 When READ-ONLY, allow accesses to read-only memory during replay.\n\
3198 When READ-WRITE, allow accesses to read-only and read-write memory during \
3200 NULL
, cmd_show_replay_memory_access
,
3201 &set_record_btrace_cmdlist
,
3202 &show_record_btrace_cmdlist
);
3204 add_prefix_cmd ("cpu", class_support
, cmd_set_record_btrace_cpu
,
3206 Set the cpu to be used for trace decode.\n\n\
3207 The format is \"VENDOR:IDENTIFIER\" or \"none\" or \"auto\" (default).\n\
3208 For vendor \"intel\" the format is \"FAMILY/MODEL[/STEPPING]\".\n\n\
3209 When decoding branch trace, enable errata workarounds for the specified cpu.\n\
3210 The default is \"auto\", which uses the cpu on which the trace was recorded.\n\
3211 When GDB does not support that cpu, this option can be used to enable\n\
3212 workarounds for a similar cpu that GDB supports.\n\n\
3213 When set to \"none\", errata workarounds are disabled."),
3214 &set_record_btrace_cpu_cmdlist
,
3215 _("set record btrace cpu "), 1,
3216 &set_record_btrace_cmdlist
);
3218 add_cmd ("auto", class_support
, cmd_set_record_btrace_cpu_auto
, _("\
3219 Automatically determine the cpu to be used for trace decode."),
3220 &set_record_btrace_cpu_cmdlist
);
3222 add_cmd ("none", class_support
, cmd_set_record_btrace_cpu_none
, _("\
3223 Do not enable errata workarounds for trace decode."),
3224 &set_record_btrace_cpu_cmdlist
);
3226 add_cmd ("cpu", class_support
, cmd_show_record_btrace_cpu
, _("\
3227 Show the cpu to be used for trace decode."),
3228 &show_record_btrace_cmdlist
);
3230 add_prefix_cmd ("bts", class_support
, cmd_set_record_btrace_bts
,
3231 _("Set record btrace bts options"),
3232 &set_record_btrace_bts_cmdlist
,
3233 "set record btrace bts ", 0, &set_record_btrace_cmdlist
);
3235 add_prefix_cmd ("bts", class_support
, cmd_show_record_btrace_bts
,
3236 _("Show record btrace bts options"),
3237 &show_record_btrace_bts_cmdlist
,
3238 "show record btrace bts ", 0, &show_record_btrace_cmdlist
);
3240 add_setshow_uinteger_cmd ("buffer-size", no_class
,
3241 &record_btrace_conf
.bts
.size
,
3242 _("Set the record/replay bts buffer size."),
3243 _("Show the record/replay bts buffer size."), _("\
3244 When starting recording request a trace buffer of this size. \
3245 The actual buffer size may differ from the requested size. \
3246 Use \"info record\" to see the actual buffer size.\n\n\
3247 Bigger buffers allow longer recording but also take more time to process \
3248 the recorded execution trace.\n\n\
3249 The trace buffer size may not be changed while recording."), NULL
,
3250 show_record_bts_buffer_size_value
,
3251 &set_record_btrace_bts_cmdlist
,
3252 &show_record_btrace_bts_cmdlist
);
3254 add_prefix_cmd ("pt", class_support
, cmd_set_record_btrace_pt
,
3255 _("Set record btrace pt options"),
3256 &set_record_btrace_pt_cmdlist
,
3257 "set record btrace pt ", 0, &set_record_btrace_cmdlist
);
3259 add_prefix_cmd ("pt", class_support
, cmd_show_record_btrace_pt
,
3260 _("Show record btrace pt options"),
3261 &show_record_btrace_pt_cmdlist
,
3262 "show record btrace pt ", 0, &show_record_btrace_cmdlist
);
3264 add_setshow_uinteger_cmd ("buffer-size", no_class
,
3265 &record_btrace_conf
.pt
.size
,
3266 _("Set the record/replay pt buffer size."),
3267 _("Show the record/replay pt buffer size."), _("\
3268 Bigger buffers allow longer recording but also take more time to process \
3269 the recorded execution.\n\
3270 The actual buffer size may differ from the requested size. Use \"info record\" \
3271 to see the actual buffer size."), NULL
, show_record_pt_buffer_size_value
,
3272 &set_record_btrace_pt_cmdlist
,
3273 &show_record_btrace_pt_cmdlist
);
3275 add_target (record_btrace_target_info
, record_btrace_target_open
);
3277 bfcache
= htab_create_alloc (50, bfcache_hash
, bfcache_eq
, NULL
,
3280 record_btrace_conf
.bts
.size
= 64 * 1024;
3281 record_btrace_conf
.pt
.size
= 16 * 1024;