aboutsummaryrefslogtreecommitdiff
path: root/gdb/btrace.h
diff options
context:
space:
mode:
authorMarkus Metzger <markus.t.metzger@intel.com>2014-01-30 09:51:10 +0100
committerMarkus Metzger <markus.t.metzger@intel.com>2015-02-09 09:52:10 +0100
commit31fd9caad9fa8e13bbc132dce264f0c3bc53412f (patch)
tree62e10f14f18a91f2b6b5eaeaace6b0244ca93f45 /gdb/btrace.h
parentafb778a2a85ab4ac883638e309442f454f158692 (diff)
downloadgdb-31fd9caad9fa8e13bbc132dce264f0c3bc53412f.zip
gdb-31fd9caad9fa8e13bbc132dce264f0c3bc53412f.tar.gz
gdb-31fd9caad9fa8e13bbc132dce264f0c3bc53412f.tar.bz2
record-btrace: indicate gaps
Indicate gaps in the trace due to decode errors. Internally, a gap is represented as a btrace function segment without instructions and with a non-zero format-specific error code. Show the gap when traversing the instruction or function call history. Also indicate gaps in "info record". It looks like this: (gdb) info record Active record target: record-btrace Recording format: Branch Trace Store. Buffer size: 64KB. Recorded 32 instructions in 5 functions (1 gaps) for thread 1 (process 7182). (gdb) record function-call-history /cli 1 fib inst 1,9 at src/fib.c:9,14 2 fib inst 10,20 at src/fib.c:6,14 3 [decode error (1): instruction overflow] 4 fib inst 21,28 at src/fib.c:11,14 5 fib inst 29,33 at src/fib.c:6,9 (gdb) record instruction-history 20,22 20 0x000000000040062f <fib+47>: sub $0x1,%rax [decode error (1): instruction overflow] 21 0x0000000000400613 <fib+19>: add $0x1,%rax 22 0x0000000000400617 <fib+23>: mov %rax,0x200a3a(%rip) (gdb) Gaps are ignored during reverse execution and replay. 2015-02-09 Markus Metzger <markus.t.metzger@intel.com> * btrace.c (ftrace_find_call): Skip gaps. (ftrace_new_function): Initialize level. (ftrace_new_call, ftrace_new_tailcall, ftrace_new_return) (ftrace_new_switch): Update level computation. (ftrace_new_gap): New. (ftrace_update_function): Create new function after gap. (btrace_compute_ftrace_bts): Create gap on error. (btrace_stitch_bts): Update parameters. Clear trace if it becomes empty. (btrace_stitch_trace): Update parameters. Update callers. (btrace_clear): Reset the number of gaps. (btrace_insn_get): Return NULL if the iterator points to a gap. (btrace_insn_number): Return zero if the iterator points to a gap. (btrace_insn_end): Allow gaps at the end. (btrace_insn_next, btrace_insn_prev, btrace_insn_cmp): Handle gaps. (btrace_find_insn_by_number): Assert that the found iterator does not point to a gap. (btrace_call_next, btrace_call_prev): Assert that the last function is not a gap. * btrace.h (btrace_bts_error): New. (btrace_function): Update comment. (btrace_function) <insn, insn_offset, number>: Update comment. (btrace_function) <errcode>: New. (btrace_thread_info) <ngaps>: New. (btrace_thread_info) <replay>: Update comment. (btrace_insn_get): Update comment. * record-btrace.c (btrace_ui_out_decode_error): New. (record_btrace_info): Print number of gaps. (btrace_insn_history, btrace_call_history): Call btrace_ui_out_decode_error for gaps. (record_btrace_step_thread, record_btrace_start_replaying): Skip gaps. testsuite/ * gdb.btrace/buffer-size.exp: Update "info record" output. * gdb.btrace/delta.exp: Update "info record" output. * gdb.btrace/enable.exp: Update "info record" output. * gdb.btrace/finish.exp: Update "info record" output. * gdb.btrace/instruction_history.exp: Update "info record" output. * gdb.btrace/next.exp: Update "info record" output. * gdb.btrace/nexti.exp: Update "info record" output. * gdb.btrace/step.exp: Update "info record" output. * gdb.btrace/stepi.exp: Update "info record" output. * gdb.btrace/nohist.exp: Update "info record" output.
Diffstat (limited to 'gdb/btrace.h')
-rw-r--r--gdb/btrace.h40
1 files changed, 34 insertions, 6 deletions
diff --git a/gdb/btrace.h b/gdb/btrace.h
index 694d504..0ddd4c1 100644
--- a/gdb/btrace.h
+++ b/gdb/btrace.h
@@ -86,12 +86,25 @@ enum btrace_function_flag
BFUN_UP_LINKS_TO_TAILCALL = (1 << 1)
};
+/* Decode errors for the BTS recording format. */
+enum btrace_bts_error
+{
+ /* The instruction trace overflowed the end of the trace block. */
+ BDE_BTS_OVERFLOW = 1,
+
+ /* The instruction size could not be determined. */
+ BDE_BTS_INSN_SIZE
+};
+
/* A branch trace function segment.
This represents a function segment in a branch trace, i.e. a consecutive
number of instructions belonging to the same function.
- We do not allow function segments without any instructions. */
+ In case of decode errors, we add an empty function segment to indicate
+ the gap in the trace.
+
+ We do not allow function segments without instructions otherwise. */
struct btrace_function
{
/* The full and minimal symbol for the function. Both may be NULL. */
@@ -110,14 +123,23 @@ struct btrace_function
struct btrace_function *up;
/* The instructions in this function segment.
- The instruction vector will never be empty. */
+ The instruction vector will be empty if the function segment
+ represents a decode error. */
VEC (btrace_insn_s) *insn;
+ /* The error code of a decode error that led to a gap.
+ Must be zero unless INSN is empty; non-zero otherwise. */
+ int errcode;
+
/* The instruction number offset for the first instruction in this
- function segment. */
+ function segment.
+ If INSN is empty this is the insn_offset of the succeding function
+ segment in control-flow order. */
unsigned int insn_offset;
- /* The function number in control-flow order. */
+ /* The function number in control-flow order.
+ If INSN is empty indicating a gap in the trace due to a decode error,
+ we still count the gap as a function. */
unsigned int number;
/* The function level in a back trace across the entire branch trace.
@@ -223,6 +245,9 @@ struct btrace_thread_info
becomes zero. */
int level;
+ /* The number of gaps in the trace. */
+ unsigned int ngaps;
+
/* A bit-vector of btrace_thread_flag. */
enum btrace_thread_flag flags;
@@ -232,7 +257,9 @@ struct btrace_thread_info
/* The function call history iterator. */
struct btrace_call_history *call_history;
- /* The current replay position. NULL if not replaying. */
+ /* The current replay position. NULL if not replaying.
+ Gaps are skipped during replay, so REPLAY always points to a valid
+ instruction. */
struct btrace_insn_iterator *replay;
};
@@ -270,7 +297,8 @@ extern void parse_xml_btrace (struct btrace_data *data, const char *xml);
extern void parse_xml_btrace_conf (struct btrace_config *conf, const char *xml);
/* Dereference a branch trace instruction iterator. Return a pointer to the
- instruction the iterator points to. */
+ instruction the iterator points to.
+ May return NULL if the iterator points to a gap in the trace. */
extern const struct btrace_insn *
btrace_insn_get (const struct btrace_insn_iterator *);