1 /* Branch trace support for GDB, the GNU debugger.
3 Copyright (C) 2013-2020 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"
44 #include "cli/cli-style.h"
46 static const target_info record_btrace_target_info
= {
48 N_("Branch tracing target"),
49 N_("Collect control-flow trace and provide the execution history.")
52 /* The target_ops of record-btrace. */
54 class record_btrace_target final
: public target_ops
57 const target_info
&info () const override
58 { return record_btrace_target_info
; }
60 strata
stratum () const override
{ return record_stratum
; }
62 void close () override
;
63 void async (int) override
;
65 void detach (inferior
*inf
, int from_tty
) override
66 { record_detach (this, inf
, from_tty
); }
68 void disconnect (const char *, int) override
;
70 void mourn_inferior () override
71 { record_mourn_inferior (this); }
74 { record_kill (this); }
76 enum record_method
record_method (ptid_t ptid
) override
;
78 void stop_recording () override
;
79 void info_record () override
;
81 void insn_history (int size
, gdb_disassembly_flags flags
) override
;
82 void insn_history_from (ULONGEST from
, int size
,
83 gdb_disassembly_flags flags
) override
;
84 void insn_history_range (ULONGEST begin
, ULONGEST end
,
85 gdb_disassembly_flags flags
) override
;
86 void call_history (int size
, record_print_flags flags
) override
;
87 void call_history_from (ULONGEST begin
, int size
, record_print_flags flags
)
89 void call_history_range (ULONGEST begin
, ULONGEST end
, record_print_flags flags
)
92 bool record_is_replaying (ptid_t ptid
) override
;
93 bool record_will_replay (ptid_t ptid
, int dir
) override
;
94 void record_stop_replaying () override
;
96 enum target_xfer_status
xfer_partial (enum target_object object
,
99 const gdb_byte
*writebuf
,
100 ULONGEST offset
, ULONGEST len
,
101 ULONGEST
*xfered_len
) override
;
103 int insert_breakpoint (struct gdbarch
*,
104 struct bp_target_info
*) override
;
105 int remove_breakpoint (struct gdbarch
*, struct bp_target_info
*,
106 enum remove_bp_reason
) override
;
108 void fetch_registers (struct regcache
*, int) override
;
110 void store_registers (struct regcache
*, int) override
;
111 void prepare_to_store (struct regcache
*) override
;
113 const struct frame_unwind
*get_unwinder () override
;
115 const struct frame_unwind
*get_tailcall_unwinder () override
;
117 void commit_resume () override
;
118 void resume (ptid_t
, int, enum gdb_signal
) override
;
119 ptid_t
wait (ptid_t
, struct target_waitstatus
*, int) override
;
121 void stop (ptid_t
) override
;
122 void update_thread_list () override
;
123 bool thread_alive (ptid_t ptid
) override
;
124 void goto_record_begin () override
;
125 void goto_record_end () override
;
126 void goto_record (ULONGEST insn
) override
;
128 bool can_execute_reverse () override
;
130 bool stopped_by_sw_breakpoint () override
;
131 bool supports_stopped_by_sw_breakpoint () override
;
133 bool stopped_by_hw_breakpoint () override
;
134 bool supports_stopped_by_hw_breakpoint () override
;
136 enum exec_direction_kind
execution_direction () override
;
137 void prepare_to_generate_core () override
;
138 void done_generating_core () override
;
141 static record_btrace_target record_btrace_ops
;
143 /* Initialize the record-btrace target ops. */
145 /* Token associated with a new-thread observer enabling branch tracing
146 for the new thread. */
147 static const gdb::observers::token record_btrace_thread_observer_token
{};
149 /* Memory access types used in set/show record btrace replay-memory-access. */
150 static const char replay_memory_access_read_only
[] = "read-only";
151 static const char replay_memory_access_read_write
[] = "read-write";
152 static const char *const replay_memory_access_types
[] =
154 replay_memory_access_read_only
,
155 replay_memory_access_read_write
,
159 /* The currently allowed replay memory access type. */
160 static const char *replay_memory_access
= replay_memory_access_read_only
;
162 /* The cpu state kinds. */
163 enum record_btrace_cpu_state_kind
170 /* The current cpu state. */
171 static enum record_btrace_cpu_state_kind record_btrace_cpu_state
= CS_AUTO
;
173 /* The current cpu for trace decode. */
174 static struct btrace_cpu record_btrace_cpu
;
176 /* Command lists for "set/show record btrace". */
177 static struct cmd_list_element
*set_record_btrace_cmdlist
;
178 static struct cmd_list_element
*show_record_btrace_cmdlist
;
180 /* The execution direction of the last resume we got. See record-full.c. */
181 static enum exec_direction_kind record_btrace_resume_exec_dir
= EXEC_FORWARD
;
183 /* The async event handler for reverse/replay execution. */
184 static struct async_event_handler
*record_btrace_async_inferior_event_handler
;
186 /* A flag indicating that we are currently generating a core file. */
187 static int record_btrace_generating_corefile
;
189 /* The current branch trace configuration. */
190 static struct btrace_config record_btrace_conf
;
192 /* Command list for "record btrace". */
193 static struct cmd_list_element
*record_btrace_cmdlist
;
195 /* Command lists for "set/show record btrace bts". */
196 static struct cmd_list_element
*set_record_btrace_bts_cmdlist
;
197 static struct cmd_list_element
*show_record_btrace_bts_cmdlist
;
199 /* Command lists for "set/show record btrace pt". */
200 static struct cmd_list_element
*set_record_btrace_pt_cmdlist
;
201 static struct cmd_list_element
*show_record_btrace_pt_cmdlist
;
203 /* Command list for "set record btrace cpu". */
204 static struct cmd_list_element
*set_record_btrace_cpu_cmdlist
;
206 /* Print a record-btrace debug message. Use do ... while (0) to avoid
207 ambiguities when used in if statements. */
209 #define DEBUG(msg, args...) \
212 if (record_debug != 0) \
213 fprintf_unfiltered (gdb_stdlog, \
214 "[record-btrace] " msg "\n", ##args); \
219 /* Return the cpu configured by the user. Returns NULL if the cpu was
220 configured as auto. */
221 const struct btrace_cpu
*
222 record_btrace_get_cpu (void)
224 switch (record_btrace_cpu_state
)
230 record_btrace_cpu
.vendor
= CV_UNKNOWN
;
233 return &record_btrace_cpu
;
236 error (_("Internal error: bad record btrace cpu state."));
239 /* Update the branch trace for the current thread and return a pointer to its
242 Throws an error if there is no thread or no trace. This function never
245 static struct thread_info
*
246 require_btrace_thread (void)
250 if (inferior_ptid
== null_ptid
)
251 error (_("No thread."));
253 thread_info
*tp
= inferior_thread ();
255 validate_registers_access ();
257 btrace_fetch (tp
, record_btrace_get_cpu ());
259 if (btrace_is_empty (tp
))
260 error (_("No trace."));
265 /* Update the branch trace for the current thread and return a pointer to its
266 branch trace information struct.
268 Throws an error if there is no thread or no trace. This function never
271 static struct btrace_thread_info
*
272 require_btrace (void)
274 struct thread_info
*tp
;
276 tp
= require_btrace_thread ();
281 /* Enable branch tracing for one thread. Warn on errors. */
284 record_btrace_enable_warn (struct thread_info
*tp
)
288 btrace_enable (tp
, &record_btrace_conf
);
290 catch (const gdb_exception_error
&error
)
292 warning ("%s", error
.what ());
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__
, _("Unknown 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 if (inferior_ptid
== null_ptid
)
560 error (_("No thread."));
562 tp
= inferior_thread ();
564 validate_registers_access ();
566 btinfo
= &tp
->btrace
;
568 conf
= ::btrace_conf (btinfo
);
570 record_btrace_print_conf (conf
);
572 btrace_fetch (tp
, record_btrace_get_cpu ());
578 if (!btrace_is_empty (tp
))
580 struct btrace_call_iterator call
;
581 struct btrace_insn_iterator insn
;
583 btrace_call_end (&call
, btinfo
);
584 btrace_call_prev (&call
, 1);
585 calls
= btrace_call_number (&call
);
587 btrace_insn_end (&insn
, btinfo
);
588 insns
= btrace_insn_number (&insn
);
590 /* If the last instruction is not a gap, it is the current instruction
591 that is not actually part of the record. */
592 if (btrace_insn_get (&insn
) != NULL
)
595 gaps
= btinfo
->ngaps
;
598 printf_unfiltered (_("Recorded %u instructions in %u functions (%u gaps) "
599 "for thread %s (%s).\n"), insns
, calls
, gaps
,
600 print_thread_id (tp
),
601 target_pid_to_str (tp
->ptid
).c_str ());
603 if (btrace_is_replaying (tp
))
604 printf_unfiltered (_("Replay in progress. At instruction %u.\n"),
605 btrace_insn_number (btinfo
->replay
));
608 /* Print a decode error. */
611 btrace_ui_out_decode_error (struct ui_out
*uiout
, int errcode
,
612 enum btrace_format format
)
614 const char *errstr
= btrace_decode_error (format
, errcode
);
616 uiout
->text (_("["));
617 /* ERRCODE > 0 indicates notifications on BTRACE_FORMAT_PT. */
618 if (!(format
== BTRACE_FORMAT_PT
&& errcode
> 0))
620 uiout
->text (_("decode error ("));
621 uiout
->field_signed ("errcode", errcode
);
622 uiout
->text (_("): "));
624 uiout
->text (errstr
);
625 uiout
->text (_("]\n"));
628 /* A range of source lines. */
630 struct btrace_line_range
632 /* The symtab this line is from. */
633 struct symtab
*symtab
;
635 /* The first line (inclusive). */
638 /* The last line (exclusive). */
642 /* Construct a line range. */
644 static struct btrace_line_range
645 btrace_mk_line_range (struct symtab
*symtab
, int begin
, int end
)
647 struct btrace_line_range range
;
649 range
.symtab
= symtab
;
656 /* Add a line to a line range. */
658 static struct btrace_line_range
659 btrace_line_range_add (struct btrace_line_range range
, int line
)
661 if (range
.end
<= range
.begin
)
663 /* This is the first entry. */
665 range
.end
= line
+ 1;
667 else if (line
< range
.begin
)
669 else if (range
.end
< line
)
675 /* Return non-zero if RANGE is empty, zero otherwise. */
678 btrace_line_range_is_empty (struct btrace_line_range range
)
680 return range
.end
<= range
.begin
;
683 /* Return non-zero if LHS contains RHS, zero otherwise. */
686 btrace_line_range_contains_range (struct btrace_line_range lhs
,
687 struct btrace_line_range rhs
)
689 return ((lhs
.symtab
== rhs
.symtab
)
690 && (lhs
.begin
<= rhs
.begin
)
691 && (rhs
.end
<= lhs
.end
));
694 /* Find the line range associated with PC. */
696 static struct btrace_line_range
697 btrace_find_line_range (CORE_ADDR pc
)
699 struct btrace_line_range range
;
700 struct linetable_entry
*lines
;
701 struct linetable
*ltable
;
702 struct symtab
*symtab
;
705 symtab
= find_pc_line_symtab (pc
);
707 return btrace_mk_line_range (NULL
, 0, 0);
709 ltable
= SYMTAB_LINETABLE (symtab
);
711 return btrace_mk_line_range (symtab
, 0, 0);
713 nlines
= ltable
->nitems
;
714 lines
= ltable
->item
;
716 return btrace_mk_line_range (symtab
, 0, 0);
718 range
= btrace_mk_line_range (symtab
, 0, 0);
719 for (i
= 0; i
< nlines
- 1; i
++)
721 /* The test of is_stmt here was added when the is_stmt field was
722 introduced to the 'struct linetable_entry' structure. This
723 ensured that this loop maintained the same behaviour as before we
724 introduced is_stmt. That said, it might be that we would be
725 better off not checking is_stmt here, this would lead to us
726 possibly adding more line numbers to the range. At the time this
727 change was made I was unsure how to test this so chose to go with
728 maintaining the existing experience. */
729 if ((lines
[i
].pc
== pc
) && (lines
[i
].line
!= 0)
730 && (lines
[i
].is_stmt
== 1))
731 range
= btrace_line_range_add (range
, lines
[i
].line
);
737 /* Print source lines in LINES to UIOUT.
739 UI_ITEM_CHAIN is a cleanup chain for the last source line and the
740 instructions corresponding to that source line. When printing a new source
741 line, we do the cleanups for the open chain and open a new cleanup chain for
742 the new source line. If the source line range in LINES is not empty, this
743 function will leave the cleanup chain for the last printed source line open
744 so instructions can be added to it. */
747 btrace_print_lines (struct btrace_line_range lines
, struct ui_out
*uiout
,
748 gdb::optional
<ui_out_emit_tuple
> *src_and_asm_tuple
,
749 gdb::optional
<ui_out_emit_list
> *asm_list
,
750 gdb_disassembly_flags flags
)
752 print_source_lines_flags psl_flags
;
754 if (flags
& DISASSEMBLY_FILENAME
)
755 psl_flags
|= PRINT_SOURCE_LINES_FILENAME
;
757 for (int line
= lines
.begin
; line
< lines
.end
; ++line
)
761 src_and_asm_tuple
->emplace (uiout
, "src_and_asm_line");
763 print_source_lines (lines
.symtab
, line
, line
+ 1, psl_flags
);
765 asm_list
->emplace (uiout
, "line_asm_insn");
769 /* Disassemble a section of the recorded instruction trace. */
772 btrace_insn_history (struct ui_out
*uiout
,
773 const struct btrace_thread_info
*btinfo
,
774 const struct btrace_insn_iterator
*begin
,
775 const struct btrace_insn_iterator
*end
,
776 gdb_disassembly_flags flags
)
778 DEBUG ("itrace (0x%x): [%u; %u)", (unsigned) flags
,
779 btrace_insn_number (begin
), btrace_insn_number (end
));
781 flags
|= DISASSEMBLY_SPECULATIVE
;
783 struct gdbarch
*gdbarch
= target_gdbarch ();
784 btrace_line_range last_lines
= btrace_mk_line_range (NULL
, 0, 0);
786 ui_out_emit_list
list_emitter (uiout
, "asm_insns");
788 gdb::optional
<ui_out_emit_tuple
> src_and_asm_tuple
;
789 gdb::optional
<ui_out_emit_list
> asm_list
;
791 gdb_pretty_print_disassembler
disasm (gdbarch
, uiout
);
793 for (btrace_insn_iterator it
= *begin
; btrace_insn_cmp (&it
, end
) != 0;
794 btrace_insn_next (&it
, 1))
796 const struct btrace_insn
*insn
;
798 insn
= btrace_insn_get (&it
);
800 /* A NULL instruction indicates a gap in the trace. */
803 const struct btrace_config
*conf
;
805 conf
= btrace_conf (btinfo
);
807 /* We have trace so we must have a configuration. */
808 gdb_assert (conf
!= NULL
);
810 uiout
->field_fmt ("insn-number", "%u",
811 btrace_insn_number (&it
));
814 btrace_ui_out_decode_error (uiout
, btrace_insn_get_error (&it
),
819 struct disasm_insn dinsn
;
821 if ((flags
& DISASSEMBLY_SOURCE
) != 0)
823 struct btrace_line_range lines
;
825 lines
= btrace_find_line_range (insn
->pc
);
826 if (!btrace_line_range_is_empty (lines
)
827 && !btrace_line_range_contains_range (last_lines
, lines
))
829 btrace_print_lines (lines
, uiout
, &src_and_asm_tuple
, &asm_list
,
833 else if (!src_and_asm_tuple
.has_value ())
835 gdb_assert (!asm_list
.has_value ());
837 src_and_asm_tuple
.emplace (uiout
, "src_and_asm_line");
839 /* No source information. */
840 asm_list
.emplace (uiout
, "line_asm_insn");
843 gdb_assert (src_and_asm_tuple
.has_value ());
844 gdb_assert (asm_list
.has_value ());
847 memset (&dinsn
, 0, sizeof (dinsn
));
848 dinsn
.number
= btrace_insn_number (&it
);
849 dinsn
.addr
= insn
->pc
;
851 if ((insn
->flags
& BTRACE_INSN_FLAG_SPECULATIVE
) != 0)
852 dinsn
.is_speculative
= 1;
854 disasm
.pretty_print_insn (&dinsn
, flags
);
859 /* The insn_history method of target record-btrace. */
862 record_btrace_target::insn_history (int size
, gdb_disassembly_flags flags
)
864 struct btrace_thread_info
*btinfo
;
865 struct btrace_insn_history
*history
;
866 struct btrace_insn_iterator begin
, end
;
867 struct ui_out
*uiout
;
868 unsigned int context
, covered
;
870 uiout
= current_uiout
;
871 ui_out_emit_tuple
tuple_emitter (uiout
, "insn history");
872 context
= abs (size
);
874 error (_("Bad record instruction-history-size."));
876 btinfo
= require_btrace ();
877 history
= btinfo
->insn_history
;
880 struct btrace_insn_iterator
*replay
;
882 DEBUG ("insn-history (0x%x): %d", (unsigned) flags
, size
);
884 /* If we're replaying, we start at the replay position. Otherwise, we
885 start at the tail of the trace. */
886 replay
= btinfo
->replay
;
890 btrace_insn_end (&begin
, btinfo
);
892 /* We start from here and expand in the requested direction. Then we
893 expand in the other direction, as well, to fill up any remaining
898 /* We want the current position covered, as well. */
899 covered
= btrace_insn_next (&end
, 1);
900 covered
+= btrace_insn_prev (&begin
, context
- covered
);
901 covered
+= btrace_insn_next (&end
, context
- covered
);
905 covered
= btrace_insn_next (&end
, context
);
906 covered
+= btrace_insn_prev (&begin
, context
- covered
);
911 begin
= history
->begin
;
914 DEBUG ("insn-history (0x%x): %d, prev: [%u; %u)", (unsigned) flags
, size
,
915 btrace_insn_number (&begin
), btrace_insn_number (&end
));
920 covered
= btrace_insn_prev (&begin
, context
);
925 covered
= btrace_insn_next (&end
, context
);
930 btrace_insn_history (uiout
, btinfo
, &begin
, &end
, flags
);
934 printf_unfiltered (_("At the start of the branch trace record.\n"));
936 printf_unfiltered (_("At the end of the branch trace record.\n"));
939 btrace_set_insn_history (btinfo
, &begin
, &end
);
942 /* The insn_history_range method of target record-btrace. */
945 record_btrace_target::insn_history_range (ULONGEST from
, ULONGEST to
,
946 gdb_disassembly_flags flags
)
948 struct btrace_thread_info
*btinfo
;
949 struct btrace_insn_iterator begin
, end
;
950 struct ui_out
*uiout
;
951 unsigned int low
, high
;
954 uiout
= current_uiout
;
955 ui_out_emit_tuple
tuple_emitter (uiout
, "insn history");
959 DEBUG ("insn-history (0x%x): [%u; %u)", (unsigned) flags
, low
, high
);
961 /* Check for wrap-arounds. */
962 if (low
!= from
|| high
!= to
)
963 error (_("Bad range."));
966 error (_("Bad range."));
968 btinfo
= require_btrace ();
970 found
= btrace_find_insn_by_number (&begin
, btinfo
, low
);
972 error (_("Range out of bounds."));
974 found
= btrace_find_insn_by_number (&end
, btinfo
, high
);
977 /* Silently truncate the range. */
978 btrace_insn_end (&end
, btinfo
);
982 /* We want both begin and end to be inclusive. */
983 btrace_insn_next (&end
, 1);
986 btrace_insn_history (uiout
, btinfo
, &begin
, &end
, flags
);
987 btrace_set_insn_history (btinfo
, &begin
, &end
);
990 /* The insn_history_from method of target record-btrace. */
993 record_btrace_target::insn_history_from (ULONGEST from
, int size
,
994 gdb_disassembly_flags flags
)
996 ULONGEST begin
, end
, context
;
998 context
= abs (size
);
1000 error (_("Bad record instruction-history-size."));
1009 begin
= from
- context
+ 1;
1014 end
= from
+ context
- 1;
1016 /* Check for wrap-around. */
1021 insn_history_range (begin
, end
, flags
);
1024 /* Print the instruction number range for a function call history line. */
1027 btrace_call_history_insn_range (struct ui_out
*uiout
,
1028 const struct btrace_function
*bfun
)
1030 unsigned int begin
, end
, size
;
1032 size
= bfun
->insn
.size ();
1033 gdb_assert (size
> 0);
1035 begin
= bfun
->insn_offset
;
1036 end
= begin
+ size
- 1;
1038 uiout
->field_unsigned ("insn begin", begin
);
1040 uiout
->field_unsigned ("insn end", end
);
1043 /* Compute the lowest and highest source line for the instructions in BFUN
1044 and return them in PBEGIN and PEND.
1045 Ignore instructions that can't be mapped to BFUN, e.g. instructions that
1046 result from inlining or macro expansion. */
1049 btrace_compute_src_line_range (const struct btrace_function
*bfun
,
1050 int *pbegin
, int *pend
)
1052 struct symtab
*symtab
;
1063 symtab
= symbol_symtab (sym
);
1065 for (const btrace_insn
&insn
: bfun
->insn
)
1067 struct symtab_and_line sal
;
1069 sal
= find_pc_line (insn
.pc
, 0);
1070 if (sal
.symtab
!= symtab
|| sal
.line
== 0)
1073 begin
= std::min (begin
, sal
.line
);
1074 end
= std::max (end
, sal
.line
);
1082 /* Print the source line information for a function call history line. */
1085 btrace_call_history_src_line (struct ui_out
*uiout
,
1086 const struct btrace_function
*bfun
)
1095 uiout
->field_string ("file",
1096 symtab_to_filename_for_display (symbol_symtab (sym
)),
1097 file_name_style
.style ());
1099 btrace_compute_src_line_range (bfun
, &begin
, &end
);
1104 uiout
->field_signed ("min line", begin
);
1110 uiout
->field_signed ("max line", end
);
1113 /* Get the name of a branch trace function. */
1116 btrace_get_bfun_name (const struct btrace_function
*bfun
)
1118 struct minimal_symbol
*msym
;
1128 return sym
->print_name ();
1129 else if (msym
!= NULL
)
1130 return msym
->print_name ();
1135 /* Disassemble a section of the recorded function trace. */
1138 btrace_call_history (struct ui_out
*uiout
,
1139 const struct btrace_thread_info
*btinfo
,
1140 const struct btrace_call_iterator
*begin
,
1141 const struct btrace_call_iterator
*end
,
1144 struct btrace_call_iterator it
;
1145 record_print_flags flags
= (enum record_print_flag
) int_flags
;
1147 DEBUG ("ftrace (0x%x): [%u; %u)", int_flags
, btrace_call_number (begin
),
1148 btrace_call_number (end
));
1150 for (it
= *begin
; btrace_call_cmp (&it
, end
) < 0; btrace_call_next (&it
, 1))
1152 const struct btrace_function
*bfun
;
1153 struct minimal_symbol
*msym
;
1156 bfun
= btrace_call_get (&it
);
1160 /* Print the function index. */
1161 uiout
->field_unsigned ("index", bfun
->number
);
1164 /* Indicate gaps in the trace. */
1165 if (bfun
->errcode
!= 0)
1167 const struct btrace_config
*conf
;
1169 conf
= btrace_conf (btinfo
);
1171 /* We have trace so we must have a configuration. */
1172 gdb_assert (conf
!= NULL
);
1174 btrace_ui_out_decode_error (uiout
, bfun
->errcode
, conf
->format
);
1179 if ((flags
& RECORD_PRINT_INDENT_CALLS
) != 0)
1181 int level
= bfun
->level
+ btinfo
->level
, i
;
1183 for (i
= 0; i
< level
; ++i
)
1188 uiout
->field_string ("function", sym
->print_name (),
1189 function_name_style
.style ());
1190 else if (msym
!= NULL
)
1191 uiout
->field_string ("function", msym
->print_name (),
1192 function_name_style
.style ());
1193 else if (!uiout
->is_mi_like_p ())
1194 uiout
->field_string ("function", "??",
1195 function_name_style
.style ());
1197 if ((flags
& RECORD_PRINT_INSN_RANGE
) != 0)
1199 uiout
->text (_("\tinst "));
1200 btrace_call_history_insn_range (uiout
, bfun
);
1203 if ((flags
& RECORD_PRINT_SRC_LINE
) != 0)
1205 uiout
->text (_("\tat "));
1206 btrace_call_history_src_line (uiout
, bfun
);
1213 /* The call_history method of target record-btrace. */
1216 record_btrace_target::call_history (int size
, record_print_flags flags
)
1218 struct btrace_thread_info
*btinfo
;
1219 struct btrace_call_history
*history
;
1220 struct btrace_call_iterator begin
, end
;
1221 struct ui_out
*uiout
;
1222 unsigned int context
, covered
;
1224 uiout
= current_uiout
;
1225 ui_out_emit_tuple
tuple_emitter (uiout
, "insn history");
1226 context
= abs (size
);
1228 error (_("Bad record function-call-history-size."));
1230 btinfo
= require_btrace ();
1231 history
= btinfo
->call_history
;
1232 if (history
== NULL
)
1234 struct btrace_insn_iterator
*replay
;
1236 DEBUG ("call-history (0x%x): %d", (int) flags
, size
);
1238 /* If we're replaying, we start at the replay position. Otherwise, we
1239 start at the tail of the trace. */
1240 replay
= btinfo
->replay
;
1243 begin
.btinfo
= btinfo
;
1244 begin
.index
= replay
->call_index
;
1247 btrace_call_end (&begin
, btinfo
);
1249 /* We start from here and expand in the requested direction. Then we
1250 expand in the other direction, as well, to fill up any remaining
1255 /* We want the current position covered, as well. */
1256 covered
= btrace_call_next (&end
, 1);
1257 covered
+= btrace_call_prev (&begin
, context
- covered
);
1258 covered
+= btrace_call_next (&end
, context
- covered
);
1262 covered
= btrace_call_next (&end
, context
);
1263 covered
+= btrace_call_prev (&begin
, context
- covered
);
1268 begin
= history
->begin
;
1271 DEBUG ("call-history (0x%x): %d, prev: [%u; %u)", (int) flags
, size
,
1272 btrace_call_number (&begin
), btrace_call_number (&end
));
1277 covered
= btrace_call_prev (&begin
, context
);
1282 covered
= btrace_call_next (&end
, context
);
1287 btrace_call_history (uiout
, btinfo
, &begin
, &end
, flags
);
1291 printf_unfiltered (_("At the start of the branch trace record.\n"));
1293 printf_unfiltered (_("At the end of the branch trace record.\n"));
1296 btrace_set_call_history (btinfo
, &begin
, &end
);
1299 /* The call_history_range method of target record-btrace. */
1302 record_btrace_target::call_history_range (ULONGEST from
, ULONGEST to
,
1303 record_print_flags flags
)
1305 struct btrace_thread_info
*btinfo
;
1306 struct btrace_call_iterator begin
, end
;
1307 struct ui_out
*uiout
;
1308 unsigned int low
, high
;
1311 uiout
= current_uiout
;
1312 ui_out_emit_tuple
tuple_emitter (uiout
, "func history");
1316 DEBUG ("call-history (0x%x): [%u; %u)", (int) flags
, low
, high
);
1318 /* Check for wrap-arounds. */
1319 if (low
!= from
|| high
!= to
)
1320 error (_("Bad range."));
1323 error (_("Bad range."));
1325 btinfo
= require_btrace ();
1327 found
= btrace_find_call_by_number (&begin
, btinfo
, low
);
1329 error (_("Range out of bounds."));
1331 found
= btrace_find_call_by_number (&end
, btinfo
, high
);
1334 /* Silently truncate the range. */
1335 btrace_call_end (&end
, btinfo
);
1339 /* We want both begin and end to be inclusive. */
1340 btrace_call_next (&end
, 1);
1343 btrace_call_history (uiout
, btinfo
, &begin
, &end
, flags
);
1344 btrace_set_call_history (btinfo
, &begin
, &end
);
1347 /* The call_history_from method of target record-btrace. */
1350 record_btrace_target::call_history_from (ULONGEST from
, int size
,
1351 record_print_flags flags
)
1353 ULONGEST begin
, end
, context
;
1355 context
= abs (size
);
1357 error (_("Bad record function-call-history-size."));
1366 begin
= from
- context
+ 1;
1371 end
= from
+ context
- 1;
1373 /* Check for wrap-around. */
1378 call_history_range ( begin
, end
, flags
);
1381 /* The record_method method of target record-btrace. */
1384 record_btrace_target::record_method (ptid_t ptid
)
1386 process_stratum_target
*proc_target
= current_inferior ()->process_target ();
1387 thread_info
*const tp
= find_thread_ptid (proc_target
, ptid
);
1390 error (_("No thread."));
1392 if (tp
->btrace
.target
== NULL
)
1393 return RECORD_METHOD_NONE
;
1395 return RECORD_METHOD_BTRACE
;
1398 /* The record_is_replaying method of target record-btrace. */
1401 record_btrace_target::record_is_replaying (ptid_t ptid
)
1403 process_stratum_target
*proc_target
= current_inferior ()->process_target ();
1404 for (thread_info
*tp
: all_non_exited_threads (proc_target
, ptid
))
1405 if (btrace_is_replaying (tp
))
1411 /* The record_will_replay method of target record-btrace. */
1414 record_btrace_target::record_will_replay (ptid_t ptid
, int dir
)
1416 return dir
== EXEC_REVERSE
|| record_is_replaying (ptid
);
1419 /* The xfer_partial method of target record-btrace. */
1421 enum target_xfer_status
1422 record_btrace_target::xfer_partial (enum target_object object
,
1423 const char *annex
, gdb_byte
*readbuf
,
1424 const gdb_byte
*writebuf
, ULONGEST offset
,
1425 ULONGEST len
, ULONGEST
*xfered_len
)
1427 /* Filter out requests that don't make sense during replay. */
1428 if (replay_memory_access
== replay_memory_access_read_only
1429 && !record_btrace_generating_corefile
1430 && record_is_replaying (inferior_ptid
))
1434 case TARGET_OBJECT_MEMORY
:
1436 struct target_section
*section
;
1438 /* We do not allow writing memory in general. */
1439 if (writebuf
!= NULL
)
1442 return TARGET_XFER_UNAVAILABLE
;
1445 /* We allow reading readonly memory. */
1446 section
= target_section_by_addr (this, offset
);
1447 if (section
!= NULL
)
1449 /* Check if the section we found is readonly. */
1450 if ((bfd_section_flags (section
->the_bfd_section
)
1451 & SEC_READONLY
) != 0)
1453 /* Truncate the request to fit into this section. */
1454 len
= std::min (len
, section
->endaddr
- offset
);
1460 return TARGET_XFER_UNAVAILABLE
;
1465 /* Forward the request. */
1466 return this->beneath ()->xfer_partial (object
, annex
, readbuf
, writebuf
,
1467 offset
, len
, xfered_len
);
1470 /* The insert_breakpoint method of target record-btrace. */
1473 record_btrace_target::insert_breakpoint (struct gdbarch
*gdbarch
,
1474 struct bp_target_info
*bp_tgt
)
1479 /* Inserting breakpoints requires accessing memory. Allow it for the
1480 duration of this function. */
1481 old
= replay_memory_access
;
1482 replay_memory_access
= replay_memory_access_read_write
;
1487 ret
= this->beneath ()->insert_breakpoint (gdbarch
, bp_tgt
);
1489 catch (const gdb_exception
&except
)
1491 replay_memory_access
= old
;
1494 replay_memory_access
= old
;
1499 /* The remove_breakpoint method of target record-btrace. */
1502 record_btrace_target::remove_breakpoint (struct gdbarch
*gdbarch
,
1503 struct bp_target_info
*bp_tgt
,
1504 enum remove_bp_reason reason
)
1509 /* Removing breakpoints requires accessing memory. Allow it for the
1510 duration of this function. */
1511 old
= replay_memory_access
;
1512 replay_memory_access
= replay_memory_access_read_write
;
1517 ret
= this->beneath ()->remove_breakpoint (gdbarch
, bp_tgt
, reason
);
1519 catch (const gdb_exception
&except
)
1521 replay_memory_access
= old
;
1524 replay_memory_access
= old
;
1529 /* The fetch_registers method of target record-btrace. */
1532 record_btrace_target::fetch_registers (struct regcache
*regcache
, int regno
)
1534 thread_info
*tp
= find_thread_ptid (regcache
->target (), regcache
->ptid ());
1535 gdb_assert (tp
!= NULL
);
1537 btrace_insn_iterator
*replay
= tp
->btrace
.replay
;
1538 if (replay
!= NULL
&& !record_btrace_generating_corefile
)
1540 const struct btrace_insn
*insn
;
1541 struct gdbarch
*gdbarch
;
1544 gdbarch
= regcache
->arch ();
1545 pcreg
= gdbarch_pc_regnum (gdbarch
);
1549 /* We can only provide the PC register. */
1550 if (regno
>= 0 && regno
!= pcreg
)
1553 insn
= btrace_insn_get (replay
);
1554 gdb_assert (insn
!= NULL
);
1556 regcache
->raw_supply (regno
, &insn
->pc
);
1559 this->beneath ()->fetch_registers (regcache
, regno
);
1562 /* The store_registers method of target record-btrace. */
1565 record_btrace_target::store_registers (struct regcache
*regcache
, int regno
)
1567 if (!record_btrace_generating_corefile
1568 && record_is_replaying (regcache
->ptid ()))
1569 error (_("Cannot write registers while replaying."));
1571 gdb_assert (may_write_registers
);
1573 this->beneath ()->store_registers (regcache
, regno
);
1576 /* The prepare_to_store method of target record-btrace. */
1579 record_btrace_target::prepare_to_store (struct regcache
*regcache
)
1581 if (!record_btrace_generating_corefile
1582 && record_is_replaying (regcache
->ptid ()))
1585 this->beneath ()->prepare_to_store (regcache
);
1588 /* The branch trace frame cache. */
1590 struct btrace_frame_cache
1593 struct thread_info
*tp
;
1595 /* The frame info. */
1596 struct frame_info
*frame
;
1598 /* The branch trace function segment. */
1599 const struct btrace_function
*bfun
;
1602 /* A struct btrace_frame_cache hash table indexed by NEXT. */
1604 static htab_t bfcache
;
1606 /* hash_f for htab_create_alloc of bfcache. */
1609 bfcache_hash (const void *arg
)
1611 const struct btrace_frame_cache
*cache
1612 = (const struct btrace_frame_cache
*) arg
;
1614 return htab_hash_pointer (cache
->frame
);
1617 /* eq_f for htab_create_alloc of bfcache. */
1620 bfcache_eq (const void *arg1
, const void *arg2
)
1622 const struct btrace_frame_cache
*cache1
1623 = (const struct btrace_frame_cache
*) arg1
;
1624 const struct btrace_frame_cache
*cache2
1625 = (const struct btrace_frame_cache
*) arg2
;
1627 return cache1
->frame
== cache2
->frame
;
1630 /* Create a new btrace frame cache. */
1632 static struct btrace_frame_cache
*
1633 bfcache_new (struct frame_info
*frame
)
1635 struct btrace_frame_cache
*cache
;
1638 cache
= FRAME_OBSTACK_ZALLOC (struct btrace_frame_cache
);
1639 cache
->frame
= frame
;
1641 slot
= htab_find_slot (bfcache
, cache
, INSERT
);
1642 gdb_assert (*slot
== NULL
);
1648 /* Extract the branch trace function from a branch trace frame. */
1650 static const struct btrace_function
*
1651 btrace_get_frame_function (struct frame_info
*frame
)
1653 const struct btrace_frame_cache
*cache
;
1654 struct btrace_frame_cache pattern
;
1657 pattern
.frame
= frame
;
1659 slot
= htab_find_slot (bfcache
, &pattern
, NO_INSERT
);
1663 cache
= (const struct btrace_frame_cache
*) *slot
;
1667 /* Implement stop_reason method for record_btrace_frame_unwind. */
1669 static enum unwind_stop_reason
1670 record_btrace_frame_unwind_stop_reason (struct frame_info
*this_frame
,
1673 const struct btrace_frame_cache
*cache
;
1674 const struct btrace_function
*bfun
;
1676 cache
= (const struct btrace_frame_cache
*) *this_cache
;
1678 gdb_assert (bfun
!= NULL
);
1681 return UNWIND_UNAVAILABLE
;
1683 return UNWIND_NO_REASON
;
1686 /* Implement this_id method for record_btrace_frame_unwind. */
1689 record_btrace_frame_this_id (struct frame_info
*this_frame
, void **this_cache
,
1690 struct frame_id
*this_id
)
1692 const struct btrace_frame_cache
*cache
;
1693 const struct btrace_function
*bfun
;
1694 struct btrace_call_iterator it
;
1695 CORE_ADDR code
, special
;
1697 cache
= (const struct btrace_frame_cache
*) *this_cache
;
1700 gdb_assert (bfun
!= NULL
);
1702 while (btrace_find_call_by_number (&it
, &cache
->tp
->btrace
, bfun
->prev
) != 0)
1703 bfun
= btrace_call_get (&it
);
1705 code
= get_frame_func (this_frame
);
1706 special
= bfun
->number
;
1708 *this_id
= frame_id_build_unavailable_stack_special (code
, special
);
1710 DEBUG ("[frame] %s id: (!stack, pc=%s, special=%s)",
1711 btrace_get_bfun_name (cache
->bfun
),
1712 core_addr_to_string_nz (this_id
->code_addr
),
1713 core_addr_to_string_nz (this_id
->special_addr
));
1716 /* Implement prev_register method for record_btrace_frame_unwind. */
1718 static struct value
*
1719 record_btrace_frame_prev_register (struct frame_info
*this_frame
,
1723 const struct btrace_frame_cache
*cache
;
1724 const struct btrace_function
*bfun
, *caller
;
1725 struct btrace_call_iterator it
;
1726 struct gdbarch
*gdbarch
;
1730 gdbarch
= get_frame_arch (this_frame
);
1731 pcreg
= gdbarch_pc_regnum (gdbarch
);
1732 if (pcreg
< 0 || regnum
!= pcreg
)
1733 throw_error (NOT_AVAILABLE_ERROR
,
1734 _("Registers are not available in btrace record history"));
1736 cache
= (const struct btrace_frame_cache
*) *this_cache
;
1738 gdb_assert (bfun
!= NULL
);
1740 if (btrace_find_call_by_number (&it
, &cache
->tp
->btrace
, bfun
->up
) == 0)
1741 throw_error (NOT_AVAILABLE_ERROR
,
1742 _("No caller in btrace record history"));
1744 caller
= btrace_call_get (&it
);
1746 if ((bfun
->flags
& BFUN_UP_LINKS_TO_RET
) != 0)
1747 pc
= caller
->insn
.front ().pc
;
1750 pc
= caller
->insn
.back ().pc
;
1751 pc
+= gdb_insn_length (gdbarch
, pc
);
1754 DEBUG ("[frame] unwound PC in %s on level %d: %s",
1755 btrace_get_bfun_name (bfun
), bfun
->level
,
1756 core_addr_to_string_nz (pc
));
1758 return frame_unwind_got_address (this_frame
, regnum
, pc
);
1761 /* Implement sniffer method for record_btrace_frame_unwind. */
1764 record_btrace_frame_sniffer (const struct frame_unwind
*self
,
1765 struct frame_info
*this_frame
,
1768 const struct btrace_function
*bfun
;
1769 struct btrace_frame_cache
*cache
;
1770 struct thread_info
*tp
;
1771 struct frame_info
*next
;
1773 /* THIS_FRAME does not contain a reference to its thread. */
1774 tp
= inferior_thread ();
1777 next
= get_next_frame (this_frame
);
1780 const struct btrace_insn_iterator
*replay
;
1782 replay
= tp
->btrace
.replay
;
1784 bfun
= &replay
->btinfo
->functions
[replay
->call_index
];
1788 const struct btrace_function
*callee
;
1789 struct btrace_call_iterator it
;
1791 callee
= btrace_get_frame_function (next
);
1792 if (callee
== NULL
|| (callee
->flags
& BFUN_UP_LINKS_TO_TAILCALL
) != 0)
1795 if (btrace_find_call_by_number (&it
, &tp
->btrace
, callee
->up
) == 0)
1798 bfun
= btrace_call_get (&it
);
1804 DEBUG ("[frame] sniffed frame for %s on level %d",
1805 btrace_get_bfun_name (bfun
), bfun
->level
);
1807 /* This is our frame. Initialize the frame cache. */
1808 cache
= bfcache_new (this_frame
);
1812 *this_cache
= cache
;
1816 /* Implement sniffer method for record_btrace_tailcall_frame_unwind. */
1819 record_btrace_tailcall_frame_sniffer (const struct frame_unwind
*self
,
1820 struct frame_info
*this_frame
,
1823 const struct btrace_function
*bfun
, *callee
;
1824 struct btrace_frame_cache
*cache
;
1825 struct btrace_call_iterator it
;
1826 struct frame_info
*next
;
1827 struct thread_info
*tinfo
;
1829 next
= get_next_frame (this_frame
);
1833 callee
= btrace_get_frame_function (next
);
1837 if ((callee
->flags
& BFUN_UP_LINKS_TO_TAILCALL
) == 0)
1840 tinfo
= inferior_thread ();
1841 if (btrace_find_call_by_number (&it
, &tinfo
->btrace
, callee
->up
) == 0)
1844 bfun
= btrace_call_get (&it
);
1846 DEBUG ("[frame] sniffed tailcall frame for %s on level %d",
1847 btrace_get_bfun_name (bfun
), bfun
->level
);
1849 /* This is our frame. Initialize the frame cache. */
1850 cache
= bfcache_new (this_frame
);
1854 *this_cache
= cache
;
1859 record_btrace_frame_dealloc_cache (struct frame_info
*self
, void *this_cache
)
1861 struct btrace_frame_cache
*cache
;
1864 cache
= (struct btrace_frame_cache
*) this_cache
;
1866 slot
= htab_find_slot (bfcache
, cache
, NO_INSERT
);
1867 gdb_assert (slot
!= NULL
);
1869 htab_remove_elt (bfcache
, cache
);
1872 /* btrace recording does not store previous memory content, neither the stack
1873 frames content. Any unwinding would return erroneous results as the stack
1874 contents no longer matches the changed PC value restored from history.
1875 Therefore this unwinder reports any possibly unwound registers as
1878 const struct frame_unwind record_btrace_frame_unwind
=
1881 record_btrace_frame_unwind_stop_reason
,
1882 record_btrace_frame_this_id
,
1883 record_btrace_frame_prev_register
,
1885 record_btrace_frame_sniffer
,
1886 record_btrace_frame_dealloc_cache
1889 const struct frame_unwind record_btrace_tailcall_frame_unwind
=
1892 record_btrace_frame_unwind_stop_reason
,
1893 record_btrace_frame_this_id
,
1894 record_btrace_frame_prev_register
,
1896 record_btrace_tailcall_frame_sniffer
,
1897 record_btrace_frame_dealloc_cache
1900 /* Implement the get_unwinder method. */
1902 const struct frame_unwind
*
1903 record_btrace_target::get_unwinder ()
1905 return &record_btrace_frame_unwind
;
1908 /* Implement the get_tailcall_unwinder method. */
1910 const struct frame_unwind
*
1911 record_btrace_target::get_tailcall_unwinder ()
1913 return &record_btrace_tailcall_frame_unwind
;
1916 /* Return a human-readable string for FLAG. */
1919 btrace_thread_flag_to_str (enum btrace_thread_flag flag
)
1927 return "reverse-step";
1933 return "reverse-cont";
1942 /* Indicate that TP should be resumed according to FLAG. */
1945 record_btrace_resume_thread (struct thread_info
*tp
,
1946 enum btrace_thread_flag flag
)
1948 struct btrace_thread_info
*btinfo
;
1950 DEBUG ("resuming thread %s (%s): %x (%s)", print_thread_id (tp
),
1951 target_pid_to_str (tp
->ptid
).c_str (), flag
,
1952 btrace_thread_flag_to_str (flag
));
1954 btinfo
= &tp
->btrace
;
1956 /* Fetch the latest branch trace. */
1957 btrace_fetch (tp
, record_btrace_get_cpu ());
1959 /* A resume request overwrites a preceding resume or stop request. */
1960 btinfo
->flags
&= ~(BTHR_MOVE
| BTHR_STOP
);
1961 btinfo
->flags
|= flag
;
1964 /* Get the current frame for TP. */
1966 static struct frame_id
1967 get_thread_current_frame_id (struct thread_info
*tp
)
1972 /* Set current thread, which is implicitly used by
1973 get_current_frame. */
1974 scoped_restore_current_thread restore_thread
;
1976 switch_to_thread (tp
);
1978 process_stratum_target
*proc_target
= tp
->inf
->process_target ();
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 false. */
1987 executing
= tp
->executing
;
1988 set_executing (proc_target
, inferior_ptid
, false);
1993 id
= get_frame_id (get_current_frame ());
1995 catch (const gdb_exception
&except
)
1997 /* Restore the previous execution state. */
1998 set_executing (proc_target
, inferior_ptid
, executing
);
2003 /* Restore the previous execution state. */
2004 set_executing (proc_target
, inferior_ptid
, executing
);
2009 /* Start replaying a thread. */
2011 static struct btrace_insn_iterator
*
2012 record_btrace_start_replaying (struct thread_info
*tp
)
2014 struct btrace_insn_iterator
*replay
;
2015 struct btrace_thread_info
*btinfo
;
2017 btinfo
= &tp
->btrace
;
2020 /* We can't start replaying without trace. */
2021 if (btinfo
->functions
.empty ())
2024 /* GDB stores the current frame_id when stepping in order to detects steps
2026 Since frames are computed differently when we're replaying, we need to
2027 recompute those stored frames and fix them up so we can still detect
2028 subroutines after we started replaying. */
2031 struct frame_id frame_id
;
2032 int upd_step_frame_id
, upd_step_stack_frame_id
;
2034 /* The current frame without replaying - computed via normal unwind. */
2035 frame_id
= get_thread_current_frame_id (tp
);
2037 /* Check if we need to update any stepping-related frame id's. */
2038 upd_step_frame_id
= frame_id_eq (frame_id
,
2039 tp
->control
.step_frame_id
);
2040 upd_step_stack_frame_id
= frame_id_eq (frame_id
,
2041 tp
->control
.step_stack_frame_id
);
2043 /* We start replaying at the end of the branch trace. This corresponds
2044 to the current instruction. */
2045 replay
= XNEW (struct btrace_insn_iterator
);
2046 btrace_insn_end (replay
, btinfo
);
2048 /* Skip gaps at the end of the trace. */
2049 while (btrace_insn_get (replay
) == NULL
)
2053 steps
= btrace_insn_prev (replay
, 1);
2055 error (_("No trace."));
2058 /* We're not replaying, yet. */
2059 gdb_assert (btinfo
->replay
== NULL
);
2060 btinfo
->replay
= replay
;
2062 /* Make sure we're not using any stale registers. */
2063 registers_changed_thread (tp
);
2065 /* The current frame with replaying - computed via btrace unwind. */
2066 frame_id
= get_thread_current_frame_id (tp
);
2068 /* Replace stepping related frames where necessary. */
2069 if (upd_step_frame_id
)
2070 tp
->control
.step_frame_id
= frame_id
;
2071 if (upd_step_stack_frame_id
)
2072 tp
->control
.step_stack_frame_id
= frame_id
;
2074 catch (const gdb_exception
&except
)
2076 xfree (btinfo
->replay
);
2077 btinfo
->replay
= NULL
;
2079 registers_changed_thread (tp
);
2087 /* Stop replaying a thread. */
2090 record_btrace_stop_replaying (struct thread_info
*tp
)
2092 struct btrace_thread_info
*btinfo
;
2094 btinfo
= &tp
->btrace
;
2096 xfree (btinfo
->replay
);
2097 btinfo
->replay
= NULL
;
2099 /* Make sure we're not leaving any stale registers. */
2100 registers_changed_thread (tp
);
2103 /* Stop replaying TP if it is at the end of its execution history. */
2106 record_btrace_stop_replaying_at_end (struct thread_info
*tp
)
2108 struct btrace_insn_iterator
*replay
, end
;
2109 struct btrace_thread_info
*btinfo
;
2111 btinfo
= &tp
->btrace
;
2112 replay
= btinfo
->replay
;
2117 btrace_insn_end (&end
, btinfo
);
2119 if (btrace_insn_cmp (replay
, &end
) == 0)
2120 record_btrace_stop_replaying (tp
);
2123 /* The resume method of target record-btrace. */
2126 record_btrace_target::resume (ptid_t ptid
, int step
, enum gdb_signal signal
)
2128 enum btrace_thread_flag flag
, cflag
;
2130 DEBUG ("resume %s: %s%s", target_pid_to_str (ptid
).c_str (),
2131 ::execution_direction
== EXEC_REVERSE
? "reverse-" : "",
2132 step
? "step" : "cont");
2134 /* Store the execution direction of the last resume.
2136 If there is more than one resume call, we have to rely on infrun
2137 to not change the execution direction in-between. */
2138 record_btrace_resume_exec_dir
= ::execution_direction
;
2140 /* As long as we're not replaying, just forward the request.
2142 For non-stop targets this means that no thread is replaying. In order to
2143 make progress, we may need to explicitly move replaying threads to the end
2144 of their execution history. */
2145 if ((::execution_direction
!= EXEC_REVERSE
)
2146 && !record_is_replaying (minus_one_ptid
))
2148 this->beneath ()->resume (ptid
, step
, signal
);
2152 /* Compute the btrace thread flag for the requested move. */
2153 if (::execution_direction
== EXEC_REVERSE
)
2155 flag
= step
== 0 ? BTHR_RCONT
: BTHR_RSTEP
;
2160 flag
= step
== 0 ? BTHR_CONT
: BTHR_STEP
;
2164 /* We just indicate the resume intent here. The actual stepping happens in
2165 record_btrace_wait below.
2167 For all-stop targets, we only step INFERIOR_PTID and continue others. */
2169 process_stratum_target
*proc_target
= current_inferior ()->process_target ();
2171 if (!target_is_non_stop_p ())
2173 gdb_assert (inferior_ptid
.matches (ptid
));
2175 for (thread_info
*tp
: all_non_exited_threads (proc_target
, ptid
))
2177 if (tp
->ptid
.matches (inferior_ptid
))
2178 record_btrace_resume_thread (tp
, flag
);
2180 record_btrace_resume_thread (tp
, cflag
);
2185 for (thread_info
*tp
: all_non_exited_threads (proc_target
, ptid
))
2186 record_btrace_resume_thread (tp
, flag
);
2189 /* Async support. */
2190 if (target_can_async_p ())
2193 mark_async_event_handler (record_btrace_async_inferior_event_handler
);
2197 /* The commit_resume method of target record-btrace. */
2200 record_btrace_target::commit_resume ()
2202 if ((::execution_direction
!= EXEC_REVERSE
)
2203 && !record_is_replaying (minus_one_ptid
))
2204 beneath ()->commit_resume ();
2207 /* Cancel resuming TP. */
2210 record_btrace_cancel_resume (struct thread_info
*tp
)
2212 enum btrace_thread_flag flags
;
2214 flags
= tp
->btrace
.flags
& (BTHR_MOVE
| BTHR_STOP
);
2218 DEBUG ("cancel resume thread %s (%s): %x (%s)",
2219 print_thread_id (tp
),
2220 target_pid_to_str (tp
->ptid
).c_str (), flags
,
2221 btrace_thread_flag_to_str (flags
));
2223 tp
->btrace
.flags
&= ~(BTHR_MOVE
| BTHR_STOP
);
2224 record_btrace_stop_replaying_at_end (tp
);
2227 /* Return a target_waitstatus indicating that we ran out of history. */
2229 static struct target_waitstatus
2230 btrace_step_no_history (void)
2232 struct target_waitstatus status
;
2234 status
.kind
= TARGET_WAITKIND_NO_HISTORY
;
2239 /* Return a target_waitstatus indicating that a step finished. */
2241 static struct target_waitstatus
2242 btrace_step_stopped (void)
2244 struct target_waitstatus status
;
2246 status
.kind
= TARGET_WAITKIND_STOPPED
;
2247 status
.value
.sig
= GDB_SIGNAL_TRAP
;
2252 /* Return a target_waitstatus indicating that a thread was stopped as
2255 static struct target_waitstatus
2256 btrace_step_stopped_on_request (void)
2258 struct target_waitstatus status
;
2260 status
.kind
= TARGET_WAITKIND_STOPPED
;
2261 status
.value
.sig
= GDB_SIGNAL_0
;
2266 /* Return a target_waitstatus indicating a spurious stop. */
2268 static struct target_waitstatus
2269 btrace_step_spurious (void)
2271 struct target_waitstatus status
;
2273 status
.kind
= TARGET_WAITKIND_SPURIOUS
;
2278 /* Return a target_waitstatus indicating that the thread was not resumed. */
2280 static struct target_waitstatus
2281 btrace_step_no_resumed (void)
2283 struct target_waitstatus status
;
2285 status
.kind
= TARGET_WAITKIND_NO_RESUMED
;
2290 /* Return a target_waitstatus indicating that we should wait again. */
2292 static struct target_waitstatus
2293 btrace_step_again (void)
2295 struct target_waitstatus status
;
2297 status
.kind
= TARGET_WAITKIND_IGNORE
;
2302 /* Clear the record histories. */
2305 record_btrace_clear_histories (struct btrace_thread_info
*btinfo
)
2307 xfree (btinfo
->insn_history
);
2308 xfree (btinfo
->call_history
);
2310 btinfo
->insn_history
= NULL
;
2311 btinfo
->call_history
= NULL
;
2314 /* Check whether TP's current replay position is at a breakpoint. */
2317 record_btrace_replay_at_breakpoint (struct thread_info
*tp
)
2319 struct btrace_insn_iterator
*replay
;
2320 struct btrace_thread_info
*btinfo
;
2321 const struct btrace_insn
*insn
;
2323 btinfo
= &tp
->btrace
;
2324 replay
= btinfo
->replay
;
2329 insn
= btrace_insn_get (replay
);
2333 return record_check_stopped_by_breakpoint (tp
->inf
->aspace
, insn
->pc
,
2334 &btinfo
->stop_reason
);
2337 /* Step one instruction in forward direction. */
2339 static struct target_waitstatus
2340 record_btrace_single_step_forward (struct thread_info
*tp
)
2342 struct btrace_insn_iterator
*replay
, end
, start
;
2343 struct btrace_thread_info
*btinfo
;
2345 btinfo
= &tp
->btrace
;
2346 replay
= btinfo
->replay
;
2348 /* We're done if we're not replaying. */
2350 return btrace_step_no_history ();
2352 /* Check if we're stepping a breakpoint. */
2353 if (record_btrace_replay_at_breakpoint (tp
))
2354 return btrace_step_stopped ();
2356 /* Skip gaps during replay. If we end up at a gap (at the end of the trace),
2357 jump back to the instruction at which we started. */
2363 /* We will bail out here if we continue stepping after reaching the end
2364 of the execution history. */
2365 steps
= btrace_insn_next (replay
, 1);
2369 return btrace_step_no_history ();
2372 while (btrace_insn_get (replay
) == NULL
);
2374 /* Determine the end of the instruction trace. */
2375 btrace_insn_end (&end
, btinfo
);
2377 /* The execution trace contains (and ends with) the current instruction.
2378 This instruction has not been executed, yet, so the trace really ends
2379 one instruction earlier. */
2380 if (btrace_insn_cmp (replay
, &end
) == 0)
2381 return btrace_step_no_history ();
2383 return btrace_step_spurious ();
2386 /* Step one instruction in backward direction. */
2388 static struct target_waitstatus
2389 record_btrace_single_step_backward (struct thread_info
*tp
)
2391 struct btrace_insn_iterator
*replay
, start
;
2392 struct btrace_thread_info
*btinfo
;
2394 btinfo
= &tp
->btrace
;
2395 replay
= btinfo
->replay
;
2397 /* Start replaying if we're not already doing so. */
2399 replay
= record_btrace_start_replaying (tp
);
2401 /* If we can't step any further, we reached the end of the history.
2402 Skip gaps during replay. If we end up at a gap (at the beginning of
2403 the trace), jump back to the instruction at which we started. */
2409 steps
= btrace_insn_prev (replay
, 1);
2413 return btrace_step_no_history ();
2416 while (btrace_insn_get (replay
) == NULL
);
2418 /* Check if we're stepping a breakpoint.
2420 For reverse-stepping, this check is after the step. There is logic in
2421 infrun.c that handles reverse-stepping separately. See, for example,
2422 proceed and adjust_pc_after_break.
2424 This code assumes that for reverse-stepping, PC points to the last
2425 de-executed instruction, whereas for forward-stepping PC points to the
2426 next to-be-executed instruction. */
2427 if (record_btrace_replay_at_breakpoint (tp
))
2428 return btrace_step_stopped ();
2430 return btrace_step_spurious ();
2433 /* Step a single thread. */
2435 static struct target_waitstatus
2436 record_btrace_step_thread (struct thread_info
*tp
)
2438 struct btrace_thread_info
*btinfo
;
2439 struct target_waitstatus status
;
2440 enum btrace_thread_flag flags
;
2442 btinfo
= &tp
->btrace
;
2444 flags
= btinfo
->flags
& (BTHR_MOVE
| BTHR_STOP
);
2445 btinfo
->flags
&= ~(BTHR_MOVE
| BTHR_STOP
);
2447 DEBUG ("stepping thread %s (%s): %x (%s)", print_thread_id (tp
),
2448 target_pid_to_str (tp
->ptid
).c_str (), flags
,
2449 btrace_thread_flag_to_str (flags
));
2451 /* We can't step without an execution history. */
2452 if ((flags
& BTHR_MOVE
) != 0 && btrace_is_empty (tp
))
2453 return btrace_step_no_history ();
2458 internal_error (__FILE__
, __LINE__
, _("invalid stepping type."));
2461 return btrace_step_stopped_on_request ();
2464 status
= record_btrace_single_step_forward (tp
);
2465 if (status
.kind
!= TARGET_WAITKIND_SPURIOUS
)
2468 return btrace_step_stopped ();
2471 status
= record_btrace_single_step_backward (tp
);
2472 if (status
.kind
!= TARGET_WAITKIND_SPURIOUS
)
2475 return btrace_step_stopped ();
2478 status
= record_btrace_single_step_forward (tp
);
2479 if (status
.kind
!= TARGET_WAITKIND_SPURIOUS
)
2482 btinfo
->flags
|= flags
;
2483 return btrace_step_again ();
2486 status
= record_btrace_single_step_backward (tp
);
2487 if (status
.kind
!= TARGET_WAITKIND_SPURIOUS
)
2490 btinfo
->flags
|= flags
;
2491 return btrace_step_again ();
2494 /* We keep threads moving at the end of their execution history. The wait
2495 method will stop the thread for whom the event is reported. */
2496 if (status
.kind
== TARGET_WAITKIND_NO_HISTORY
)
2497 btinfo
->flags
|= flags
;
2502 /* Announce further events if necessary. */
2505 record_btrace_maybe_mark_async_event
2506 (const std::vector
<thread_info
*> &moving
,
2507 const std::vector
<thread_info
*> &no_history
)
2509 bool more_moving
= !moving
.empty ();
2510 bool more_no_history
= !no_history
.empty ();;
2512 if (!more_moving
&& !more_no_history
)
2516 DEBUG ("movers pending");
2518 if (more_no_history
)
2519 DEBUG ("no-history pending");
2521 mark_async_event_handler (record_btrace_async_inferior_event_handler
);
2524 /* The wait method of target record-btrace. */
2527 record_btrace_target::wait (ptid_t ptid
, struct target_waitstatus
*status
,
2530 std::vector
<thread_info
*> moving
;
2531 std::vector
<thread_info
*> no_history
;
2533 DEBUG ("wait %s (0x%x)", target_pid_to_str (ptid
).c_str (), options
);
2535 /* As long as we're not replaying, just forward the request. */
2536 if ((::execution_direction
!= EXEC_REVERSE
)
2537 && !record_is_replaying (minus_one_ptid
))
2539 return this->beneath ()->wait (ptid
, status
, options
);
2542 /* Keep a work list of moving threads. */
2543 process_stratum_target
*proc_target
= current_inferior ()->process_target ();
2544 for (thread_info
*tp
: all_non_exited_threads (proc_target
, ptid
))
2545 if ((tp
->btrace
.flags
& (BTHR_MOVE
| BTHR_STOP
)) != 0)
2546 moving
.push_back (tp
);
2548 if (moving
.empty ())
2550 *status
= btrace_step_no_resumed ();
2552 DEBUG ("wait ended by %s: %s", target_pid_to_str (null_ptid
).c_str (),
2553 target_waitstatus_to_string (status
).c_str ());
2558 /* Step moving threads one by one, one step each, until either one thread
2559 reports an event or we run out of threads to step.
2561 When stepping more than one thread, chances are that some threads reach
2562 the end of their execution history earlier than others. If we reported
2563 this immediately, all-stop on top of non-stop would stop all threads and
2564 resume the same threads next time. And we would report the same thread
2565 having reached the end of its execution history again.
2567 In the worst case, this would starve the other threads. But even if other
2568 threads would be allowed to make progress, this would result in far too
2569 many intermediate stops.
2571 We therefore delay the reporting of "no execution history" until we have
2572 nothing else to report. By this time, all threads should have moved to
2573 either the beginning or the end of their execution history. There will
2574 be a single user-visible stop. */
2575 struct thread_info
*eventing
= NULL
;
2576 while ((eventing
== NULL
) && !moving
.empty ())
2578 for (unsigned int ix
= 0; eventing
== NULL
&& ix
< moving
.size ();)
2580 thread_info
*tp
= moving
[ix
];
2582 *status
= record_btrace_step_thread (tp
);
2584 switch (status
->kind
)
2586 case TARGET_WAITKIND_IGNORE
:
2590 case TARGET_WAITKIND_NO_HISTORY
:
2591 no_history
.push_back (ordered_remove (moving
, ix
));
2595 eventing
= unordered_remove (moving
, ix
);
2601 if (eventing
== NULL
)
2603 /* We started with at least one moving thread. This thread must have
2604 either stopped or reached the end of its execution history.
2606 In the former case, EVENTING must not be NULL.
2607 In the latter case, NO_HISTORY must not be empty. */
2608 gdb_assert (!no_history
.empty ());
2610 /* We kept threads moving at the end of their execution history. Stop
2611 EVENTING now that we are going to report its stop. */
2612 eventing
= unordered_remove (no_history
, 0);
2613 eventing
->btrace
.flags
&= ~BTHR_MOVE
;
2615 *status
= btrace_step_no_history ();
2618 gdb_assert (eventing
!= NULL
);
2620 /* We kept threads replaying at the end of their execution history. Stop
2621 replaying EVENTING now that we are going to report its stop. */
2622 record_btrace_stop_replaying_at_end (eventing
);
2624 /* Stop all other threads. */
2625 if (!target_is_non_stop_p ())
2627 for (thread_info
*tp
: all_non_exited_threads ())
2628 record_btrace_cancel_resume (tp
);
2631 /* In async mode, we need to announce further events. */
2632 if (target_is_async_p ())
2633 record_btrace_maybe_mark_async_event (moving
, no_history
);
2635 /* Start record histories anew from the current position. */
2636 record_btrace_clear_histories (&eventing
->btrace
);
2638 /* We moved the replay position but did not update registers. */
2639 registers_changed_thread (eventing
);
2641 DEBUG ("wait ended by thread %s (%s): %s",
2642 print_thread_id (eventing
),
2643 target_pid_to_str (eventing
->ptid
).c_str (),
2644 target_waitstatus_to_string (status
).c_str ());
2646 return eventing
->ptid
;
2649 /* The stop method of target record-btrace. */
2652 record_btrace_target::stop (ptid_t ptid
)
2654 DEBUG ("stop %s", target_pid_to_str (ptid
).c_str ());
2656 /* As long as we're not replaying, just forward the request. */
2657 if ((::execution_direction
!= EXEC_REVERSE
)
2658 && !record_is_replaying (minus_one_ptid
))
2660 this->beneath ()->stop (ptid
);
2664 process_stratum_target
*proc_target
2665 = current_inferior ()->process_target ();
2667 for (thread_info
*tp
: all_non_exited_threads (proc_target
, ptid
))
2669 tp
->btrace
.flags
&= ~BTHR_MOVE
;
2670 tp
->btrace
.flags
|= BTHR_STOP
;
2675 /* The can_execute_reverse method of target record-btrace. */
2678 record_btrace_target::can_execute_reverse ()
2683 /* The stopped_by_sw_breakpoint method of target record-btrace. */
2686 record_btrace_target::stopped_by_sw_breakpoint ()
2688 if (record_is_replaying (minus_one_ptid
))
2690 struct thread_info
*tp
= inferior_thread ();
2692 return tp
->btrace
.stop_reason
== TARGET_STOPPED_BY_SW_BREAKPOINT
;
2695 return this->beneath ()->stopped_by_sw_breakpoint ();
2698 /* The supports_stopped_by_sw_breakpoint method of target
2702 record_btrace_target::supports_stopped_by_sw_breakpoint ()
2704 if (record_is_replaying (minus_one_ptid
))
2707 return this->beneath ()->supports_stopped_by_sw_breakpoint ();
2710 /* The stopped_by_sw_breakpoint method of target record-btrace. */
2713 record_btrace_target::stopped_by_hw_breakpoint ()
2715 if (record_is_replaying (minus_one_ptid
))
2717 struct thread_info
*tp
= inferior_thread ();
2719 return tp
->btrace
.stop_reason
== TARGET_STOPPED_BY_HW_BREAKPOINT
;
2722 return this->beneath ()->stopped_by_hw_breakpoint ();
2725 /* The supports_stopped_by_hw_breakpoint method of target
2729 record_btrace_target::supports_stopped_by_hw_breakpoint ()
2731 if (record_is_replaying (minus_one_ptid
))
2734 return this->beneath ()->supports_stopped_by_hw_breakpoint ();
2737 /* The update_thread_list method of target record-btrace. */
2740 record_btrace_target::update_thread_list ()
2742 /* We don't add or remove threads during replay. */
2743 if (record_is_replaying (minus_one_ptid
))
2746 /* Forward the request. */
2747 this->beneath ()->update_thread_list ();
2750 /* The thread_alive method of target record-btrace. */
2753 record_btrace_target::thread_alive (ptid_t ptid
)
2755 /* We don't add or remove threads during replay. */
2756 if (record_is_replaying (minus_one_ptid
))
2759 /* Forward the request. */
2760 return this->beneath ()->thread_alive (ptid
);
2763 /* Set the replay branch trace instruction iterator. If IT is NULL, replay
2767 record_btrace_set_replay (struct thread_info
*tp
,
2768 const struct btrace_insn_iterator
*it
)
2770 struct btrace_thread_info
*btinfo
;
2772 btinfo
= &tp
->btrace
;
2775 record_btrace_stop_replaying (tp
);
2778 if (btinfo
->replay
== NULL
)
2779 record_btrace_start_replaying (tp
);
2780 else if (btrace_insn_cmp (btinfo
->replay
, it
) == 0)
2783 *btinfo
->replay
= *it
;
2784 registers_changed_thread (tp
);
2787 /* Start anew from the new replay position. */
2788 record_btrace_clear_histories (btinfo
);
2790 inferior_thread ()->suspend
.stop_pc
2791 = regcache_read_pc (get_current_regcache ());
2792 print_stack_frame (get_selected_frame (NULL
), 1, SRC_AND_LOC
, 1);
2795 /* The goto_record_begin method of target record-btrace. */
2798 record_btrace_target::goto_record_begin ()
2800 struct thread_info
*tp
;
2801 struct btrace_insn_iterator begin
;
2803 tp
= require_btrace_thread ();
2805 btrace_insn_begin (&begin
, &tp
->btrace
);
2807 /* Skip gaps at the beginning of the trace. */
2808 while (btrace_insn_get (&begin
) == NULL
)
2812 steps
= btrace_insn_next (&begin
, 1);
2814 error (_("No trace."));
2817 record_btrace_set_replay (tp
, &begin
);
2820 /* The goto_record_end method of target record-btrace. */
2823 record_btrace_target::goto_record_end ()
2825 struct thread_info
*tp
;
2827 tp
= require_btrace_thread ();
2829 record_btrace_set_replay (tp
, NULL
);
2832 /* The goto_record method of target record-btrace. */
2835 record_btrace_target::goto_record (ULONGEST insn
)
2837 struct thread_info
*tp
;
2838 struct btrace_insn_iterator it
;
2839 unsigned int number
;
2844 /* Check for wrap-arounds. */
2846 error (_("Instruction number out of range."));
2848 tp
= require_btrace_thread ();
2850 found
= btrace_find_insn_by_number (&it
, &tp
->btrace
, number
);
2852 /* Check if the instruction could not be found or is a gap. */
2853 if (found
== 0 || btrace_insn_get (&it
) == NULL
)
2854 error (_("No such instruction."));
2856 record_btrace_set_replay (tp
, &it
);
2859 /* The record_stop_replaying method of target record-btrace. */
2862 record_btrace_target::record_stop_replaying ()
2864 for (thread_info
*tp
: all_non_exited_threads ())
2865 record_btrace_stop_replaying (tp
);
2868 /* The execution_direction target method. */
2870 enum exec_direction_kind
2871 record_btrace_target::execution_direction ()
2873 return record_btrace_resume_exec_dir
;
2876 /* The prepare_to_generate_core target method. */
2879 record_btrace_target::prepare_to_generate_core ()
2881 record_btrace_generating_corefile
= 1;
2884 /* The done_generating_core target method. */
2887 record_btrace_target::done_generating_core ()
2889 record_btrace_generating_corefile
= 0;
2892 /* Start recording in BTS format. */
2895 cmd_record_btrace_bts_start (const char *args
, int from_tty
)
2897 if (args
!= NULL
&& *args
!= 0)
2898 error (_("Invalid argument."));
2900 record_btrace_conf
.format
= BTRACE_FORMAT_BTS
;
2904 execute_command ("target record-btrace", from_tty
);
2906 catch (const gdb_exception
&exception
)
2908 record_btrace_conf
.format
= BTRACE_FORMAT_NONE
;
2913 /* Start recording in Intel Processor Trace format. */
2916 cmd_record_btrace_pt_start (const char *args
, int from_tty
)
2918 if (args
!= NULL
&& *args
!= 0)
2919 error (_("Invalid argument."));
2921 record_btrace_conf
.format
= BTRACE_FORMAT_PT
;
2925 execute_command ("target record-btrace", from_tty
);
2927 catch (const gdb_exception
&exception
)
2929 record_btrace_conf
.format
= BTRACE_FORMAT_NONE
;
2934 /* Alias for "target record". */
2937 cmd_record_btrace_start (const char *args
, int from_tty
)
2939 if (args
!= NULL
&& *args
!= 0)
2940 error (_("Invalid argument."));
2942 record_btrace_conf
.format
= BTRACE_FORMAT_PT
;
2946 execute_command ("target record-btrace", from_tty
);
2948 catch (const gdb_exception
&exception
)
2950 record_btrace_conf
.format
= BTRACE_FORMAT_BTS
;
2954 execute_command ("target record-btrace", from_tty
);
2956 catch (const gdb_exception
&ex
)
2958 record_btrace_conf
.format
= BTRACE_FORMAT_NONE
;
2964 /* The "set record btrace" command. */
2967 cmd_set_record_btrace (const char *args
, int from_tty
)
2969 printf_unfiltered (_("\"set record btrace\" must be followed "
2970 "by an appropriate subcommand.\n"));
2971 help_list (set_record_btrace_cmdlist
, "set record btrace ",
2972 all_commands
, gdb_stdout
);
2975 /* The "show record btrace" command. */
2978 cmd_show_record_btrace (const char *args
, int from_tty
)
2980 cmd_show_list (show_record_btrace_cmdlist
, from_tty
, "");
2983 /* The "show record btrace replay-memory-access" command. */
2986 cmd_show_replay_memory_access (struct ui_file
*file
, int from_tty
,
2987 struct cmd_list_element
*c
, const char *value
)
2989 fprintf_filtered (gdb_stdout
, _("Replay memory access is %s.\n"),
2990 replay_memory_access
);
2993 /* The "set record btrace cpu none" command. */
2996 cmd_set_record_btrace_cpu_none (const char *args
, int from_tty
)
2998 if (args
!= nullptr && *args
!= 0)
2999 error (_("Trailing junk: '%s'."), args
);
3001 record_btrace_cpu_state
= CS_NONE
;
3004 /* The "set record btrace cpu auto" command. */
3007 cmd_set_record_btrace_cpu_auto (const char *args
, int from_tty
)
3009 if (args
!= nullptr && *args
!= 0)
3010 error (_("Trailing junk: '%s'."), args
);
3012 record_btrace_cpu_state
= CS_AUTO
;
3015 /* The "set record btrace cpu" command. */
3018 cmd_set_record_btrace_cpu (const char *args
, int from_tty
)
3020 if (args
== nullptr)
3023 /* We use a hard-coded vendor string for now. */
3024 unsigned int family
, model
, stepping
;
3025 int l1
, l2
, matches
= sscanf (args
, "intel: %u/%u%n/%u%n", &family
,
3026 &model
, &l1
, &stepping
, &l2
);
3029 if (strlen (args
) != l2
)
3030 error (_("Trailing junk: '%s'."), args
+ l2
);
3032 else if (matches
== 2)
3034 if (strlen (args
) != l1
)
3035 error (_("Trailing junk: '%s'."), args
+ l1
);
3040 error (_("Bad format. See \"help set record btrace cpu\"."));
3042 if (USHRT_MAX
< family
)
3043 error (_("Cpu family too big."));
3045 if (UCHAR_MAX
< model
)
3046 error (_("Cpu model too big."));
3048 if (UCHAR_MAX
< stepping
)
3049 error (_("Cpu stepping too big."));
3051 record_btrace_cpu
.vendor
= CV_INTEL
;
3052 record_btrace_cpu
.family
= family
;
3053 record_btrace_cpu
.model
= model
;
3054 record_btrace_cpu
.stepping
= stepping
;
3056 record_btrace_cpu_state
= CS_CPU
;
3059 /* The "show record btrace cpu" command. */
3062 cmd_show_record_btrace_cpu (const char *args
, int from_tty
)
3064 if (args
!= nullptr && *args
!= 0)
3065 error (_("Trailing junk: '%s'."), args
);
3067 switch (record_btrace_cpu_state
)
3070 printf_unfiltered (_("btrace cpu is 'auto'.\n"));
3074 printf_unfiltered (_("btrace cpu is 'none'.\n"));
3078 switch (record_btrace_cpu
.vendor
)
3081 if (record_btrace_cpu
.stepping
== 0)
3082 printf_unfiltered (_("btrace cpu is 'intel: %u/%u'.\n"),
3083 record_btrace_cpu
.family
,
3084 record_btrace_cpu
.model
);
3086 printf_unfiltered (_("btrace cpu is 'intel: %u/%u/%u'.\n"),
3087 record_btrace_cpu
.family
,
3088 record_btrace_cpu
.model
,
3089 record_btrace_cpu
.stepping
);
3094 error (_("Internal error: bad cpu state."));
3097 /* The "s record btrace bts" command. */
3100 cmd_set_record_btrace_bts (const char *args
, int from_tty
)
3102 printf_unfiltered (_("\"set record btrace bts\" must be followed "
3103 "by an appropriate subcommand.\n"));
3104 help_list (set_record_btrace_bts_cmdlist
, "set record btrace bts ",
3105 all_commands
, gdb_stdout
);
3108 /* The "show record btrace bts" command. */
3111 cmd_show_record_btrace_bts (const char *args
, int from_tty
)
3113 cmd_show_list (show_record_btrace_bts_cmdlist
, from_tty
, "");
3116 /* The "set record btrace pt" command. */
3119 cmd_set_record_btrace_pt (const char *args
, int from_tty
)
3121 printf_unfiltered (_("\"set record btrace pt\" must be followed "
3122 "by an appropriate subcommand.\n"));
3123 help_list (set_record_btrace_pt_cmdlist
, "set record btrace pt ",
3124 all_commands
, gdb_stdout
);
3127 /* The "show record btrace pt" command. */
3130 cmd_show_record_btrace_pt (const char *args
, int from_tty
)
3132 cmd_show_list (show_record_btrace_pt_cmdlist
, from_tty
, "");
3135 /* The "record bts buffer-size" show value function. */
3138 show_record_bts_buffer_size_value (struct ui_file
*file
, int from_tty
,
3139 struct cmd_list_element
*c
,
3142 fprintf_filtered (file
, _("The record/replay bts buffer size is %s.\n"),
3146 /* The "record pt buffer-size" show value function. */
3149 show_record_pt_buffer_size_value (struct ui_file
*file
, int from_tty
,
3150 struct cmd_list_element
*c
,
3153 fprintf_filtered (file
, _("The record/replay pt buffer size is %s.\n"),
3157 /* Initialize btrace commands. */
3159 void _initialize_record_btrace ();
3161 _initialize_record_btrace ()
3163 add_prefix_cmd ("btrace", class_obscure
, cmd_record_btrace_start
,
3164 _("Start branch trace recording."), &record_btrace_cmdlist
,
3165 "record btrace ", 0, &record_cmdlist
);
3166 add_alias_cmd ("b", "btrace", class_obscure
, 1, &record_cmdlist
);
3168 add_cmd ("bts", class_obscure
, cmd_record_btrace_bts_start
,
3170 Start branch trace recording in Branch Trace Store (BTS) format.\n\n\
3171 The processor stores a from/to record for each branch into a cyclic buffer.\n\
3172 This format may not be available on all processors."),
3173 &record_btrace_cmdlist
);
3174 add_alias_cmd ("bts", "btrace bts", class_obscure
, 1, &record_cmdlist
);
3176 add_cmd ("pt", class_obscure
, cmd_record_btrace_pt_start
,
3178 Start branch trace recording in Intel Processor Trace format.\n\n\
3179 This format may not be available on all processors."),
3180 &record_btrace_cmdlist
);
3181 add_alias_cmd ("pt", "btrace pt", class_obscure
, 1, &record_cmdlist
);
3183 add_prefix_cmd ("btrace", class_support
, cmd_set_record_btrace
,
3184 _("Set record options."), &set_record_btrace_cmdlist
,
3185 "set record btrace ", 0, &set_record_cmdlist
);
3187 add_prefix_cmd ("btrace", class_support
, cmd_show_record_btrace
,
3188 _("Show record options."), &show_record_btrace_cmdlist
,
3189 "show record btrace ", 0, &show_record_cmdlist
);
3191 add_setshow_enum_cmd ("replay-memory-access", no_class
,
3192 replay_memory_access_types
, &replay_memory_access
, _("\
3193 Set what memory accesses are allowed during replay."), _("\
3194 Show what memory accesses are allowed during replay."),
3195 _("Default is READ-ONLY.\n\n\
3196 The btrace record target does not trace data.\n\
3197 The memory therefore corresponds to the live target and not \
3198 to the current replay position.\n\n\
3199 When READ-ONLY, allow accesses to read-only memory during replay.\n\
3200 When READ-WRITE, allow accesses to read-only and read-write memory during \
3202 NULL
, cmd_show_replay_memory_access
,
3203 &set_record_btrace_cmdlist
,
3204 &show_record_btrace_cmdlist
);
3206 add_prefix_cmd ("cpu", class_support
, cmd_set_record_btrace_cpu
,
3208 Set the cpu to be used for trace decode.\n\n\
3209 The format is \"VENDOR:IDENTIFIER\" or \"none\" or \"auto\" (default).\n\
3210 For vendor \"intel\" the format is \"FAMILY/MODEL[/STEPPING]\".\n\n\
3211 When decoding branch trace, enable errata workarounds for the specified cpu.\n\
3212 The default is \"auto\", which uses the cpu on which the trace was recorded.\n\
3213 When GDB does not support that cpu, this option can be used to enable\n\
3214 workarounds for a similar cpu that GDB supports.\n\n\
3215 When set to \"none\", errata workarounds are disabled."),
3216 &set_record_btrace_cpu_cmdlist
,
3217 "set record btrace cpu ", 1,
3218 &set_record_btrace_cmdlist
);
3220 add_cmd ("auto", class_support
, cmd_set_record_btrace_cpu_auto
, _("\
3221 Automatically determine the cpu to be used for trace decode."),
3222 &set_record_btrace_cpu_cmdlist
);
3224 add_cmd ("none", class_support
, cmd_set_record_btrace_cpu_none
, _("\
3225 Do not enable errata workarounds for trace decode."),
3226 &set_record_btrace_cpu_cmdlist
);
3228 add_cmd ("cpu", class_support
, cmd_show_record_btrace_cpu
, _("\
3229 Show the cpu to be used for trace decode."),
3230 &show_record_btrace_cmdlist
);
3232 add_prefix_cmd ("bts", class_support
, cmd_set_record_btrace_bts
,
3233 _("Set record btrace bts options."),
3234 &set_record_btrace_bts_cmdlist
,
3235 "set record btrace bts ", 0, &set_record_btrace_cmdlist
);
3237 add_prefix_cmd ("bts", class_support
, cmd_show_record_btrace_bts
,
3238 _("Show record btrace bts options."),
3239 &show_record_btrace_bts_cmdlist
,
3240 "show record btrace bts ", 0, &show_record_btrace_cmdlist
);
3242 add_setshow_uinteger_cmd ("buffer-size", no_class
,
3243 &record_btrace_conf
.bts
.size
,
3244 _("Set the record/replay bts buffer size."),
3245 _("Show the record/replay bts buffer size."), _("\
3246 When starting recording request a trace buffer of this size. \
3247 The actual buffer size may differ from the requested size. \
3248 Use \"info record\" to see the actual buffer size.\n\n\
3249 Bigger buffers allow longer recording but also take more time to process \
3250 the recorded execution trace.\n\n\
3251 The trace buffer size may not be changed while recording."), NULL
,
3252 show_record_bts_buffer_size_value
,
3253 &set_record_btrace_bts_cmdlist
,
3254 &show_record_btrace_bts_cmdlist
);
3256 add_prefix_cmd ("pt", class_support
, cmd_set_record_btrace_pt
,
3257 _("Set record btrace pt options."),
3258 &set_record_btrace_pt_cmdlist
,
3259 "set record btrace pt ", 0, &set_record_btrace_cmdlist
);
3261 add_prefix_cmd ("pt", class_support
, cmd_show_record_btrace_pt
,
3262 _("Show record btrace pt options."),
3263 &show_record_btrace_pt_cmdlist
,
3264 "show record btrace pt ", 0, &show_record_btrace_cmdlist
);
3266 add_setshow_uinteger_cmd ("buffer-size", no_class
,
3267 &record_btrace_conf
.pt
.size
,
3268 _("Set the record/replay pt buffer size."),
3269 _("Show the record/replay pt buffer size."), _("\
3270 Bigger buffers allow longer recording but also take more time to process \
3271 the recorded execution.\n\
3272 The actual buffer size may differ from the requested size. Use \"info record\" \
3273 to see the actual buffer size."), NULL
, show_record_pt_buffer_size_value
,
3274 &set_record_btrace_pt_cmdlist
,
3275 &show_record_btrace_pt_cmdlist
);
3277 add_target (record_btrace_target_info
, record_btrace_target_open
);
3279 bfcache
= htab_create_alloc (50, bfcache_hash
, bfcache_eq
, NULL
,
3282 record_btrace_conf
.bts
.size
= 64 * 1024;
3283 record_btrace_conf
.pt
.size
= 16 * 1024;