* Re: [PATCH v3 1/8] btrace: Count gaps as one instruction explicitly.
@ 2016-11-30 23:34 Doug Evans
0 siblings, 0 replies; 3+ messages in thread
From: Doug Evans @ 2016-11-30 23:34 UTC (permalink / raw)
To: Tim Wiederhake; +Cc: gdb-patches, palves, markus.t.metzger
Tim Wiederhake writes:
> This gives all instructions, including gaps, a unique number. Add a
function
> to retrieve the error code if a btrace instruction iterator points to an
> invalid instruction.
>
> 2016-11-21 Tim Wiederhake <tim.wiederhake@intel.com>
>
> gdb/ChangeLog:
>
> * btrace.c (ftrace_call_num_insn, btrace_insn_get_error): New function.
> (ftrace_new_function, btrace_insn_number, btrace_insn_cmp,
> btrace_find_insn_by_number): Remove special case for gaps.
> * btrace.h (btrace_insn_get_error): New export.
> (btrace_insn_number, btrace_find_insn_by_number): Adjust comment.
> * record-btrace.c (btrace_insn_history): Print number for gaps.
> (record_btrace_info, record_btrace_goto): Handle gaps.
>
>
> ---
> gdb/btrace.c | 83
+++++++++++++++++------------------------------------
> gdb/btrace.h | 9 ++++--
> gdb/record-btrace.c | 34 ++++++++--------------
> 3 files changed, 45 insertions(+), 81 deletions(-)
>
> diff --git a/gdb/btrace.c b/gdb/btrace.c
> index 39d537c..7df1b00 100644
> --- a/gdb/btrace.c
> +++ b/gdb/btrace.c
> @@ -141,6 +141,20 @@ ftrace_debug (const struct btrace_function *bfun,
const char *prefix)
> prefix, fun, file, level, ibegin, iend);
> }
>
> +/* Return the number of instructions in a given function call segment.
*/
> +
> +static unsigned int
> +ftrace_call_num_insn (const struct btrace_function* bfun)
> +{
> + if (bfun == NULL)
> + return 0;
> +
> + if (bfun->errcode != 0)
> + return 1;
Hi.
It's not immediately clear why this test is here and why we return 1.
I'm sure there's a reason, and perhaps I just missed the place
in the code that makes it clear why, but if such a comment doesn't already
exist can you add a comment here explaining why this test is here
and why we return 1? [It'll help at least this reader more quickly
understand the why of things.]
> +
> + return VEC_length (btrace_insn_s, bfun->insn);
> +}
> +
> /* Return non-zero if BFUN does not match MFUN and FUN,
> return zero otherwise. */
>
> @@ -216,8 +230,7 @@ ftrace_new_function (struct btrace_function *prev,
> prev->flow.next = bfun;
>
> bfun->number = prev->number + 1;
> - bfun->insn_offset = (prev->insn_offset
> - + VEC_length (btrace_insn_s, prev->insn));
> + bfun->insn_offset = prev->insn_offset + ftrace_call_num_insn
(prev);
> bfun->level = prev->level;
> }
>
> @@ -2150,18 +2163,18 @@ btrace_insn_get (const struct
btrace_insn_iterator *it)
>
> /* See btrace.h. */
>
> -unsigned int
> -btrace_insn_number (const struct btrace_insn_iterator *it)
> +int
> +btrace_insn_get_error (const struct btrace_insn_iterator *it)
> {
> - const struct btrace_function *bfun;
> -
> - bfun = it->function;
> + return it->function->errcode;
> +}
>
> - /* Return zero if the iterator points to a gap in the trace. */
> - if (bfun->errcode != 0)
> - return 0;
> +/* See btrace.h. */
>
> - return bfun->insn_offset + it->index;
> +unsigned int
> +btrace_insn_number (const struct btrace_insn_iterator *it)
> +{
> + return it->function->insn_offset + it->index;
> }
Previously btrace_insn_number watched for bfun->errcode.
Now it does not, which is ok in and of itself.
But I don't see anything in the function comment that says
something like "Do not call this if errcode is non-zero." or some such.
Or maybe in places where this will be called errcode is irrelevant
or must be zero (if the latter then an assert here would be nice)?
>
> /* See btrace.h. */
> @@ -2356,37 +2369,6 @@ btrace_insn_cmp (const struct
btrace_insn_iterator *lhs,
> lnum = btrace_insn_number (lhs);
> rnum = btrace_insn_number (rhs);
>
> - /* A gap has an instruction number of zero. Things are getting more
> - complicated if gaps are involved.
> -
> - We take the instruction number offset from the iterator's function.
> - This is the number of the first instruction after the gap.
> -
> - This is OK as long as both lhs and rhs point to gaps. If only one
of
> - them does, we need to adjust the number based on the other's
regular
> - instruction number. Otherwise, a gap might compare equal to an
> - instruction. */
> -
> - if (lnum == 0 && rnum == 0)
> - {
> - lnum = lhs->function->insn_offset;
> - rnum = rhs->function->insn_offset;
> - }
> - else if (lnum == 0)
> - {
> - lnum = lhs->function->insn_offset;
> -
> - if (lnum == rnum)
> - lnum -= 1;
> - }
> - else if (rnum == 0)
> - {
> - rnum = rhs->function->insn_offset;
> -
> - if (rnum == lnum)
> - rnum -= 1;
> - }
> -
> return (int) (lnum - rnum);
> }
>
> @@ -2398,26 +2380,15 @@ btrace_find_insn_by_number (struct
btrace_insn_iterator *it,
> unsigned int number)
> {
> const struct btrace_function *bfun;
> - unsigned int end, length;
>
> for (bfun = btinfo->end; bfun != NULL; bfun = bfun->flow.prev)
> - {
> - /* Skip gaps. */
> - if (bfun->errcode != 0)
> - continue;
> -
> - if (bfun->insn_offset <= number)
> - break;
> - }
> + if (bfun->insn_offset <= number)
> + break;
>
> if (bfun == NULL)
> return 0;
>
> - length = VEC_length (btrace_insn_s, bfun->insn);
> - gdb_assert (length > 0);
> -
> - end = bfun->insn_offset + length;
> - if (end <= number)
> + if (bfun->insn_offset + ftrace_call_num_insn (bfun) <= number)
> return 0;
>
> it->function = bfun;
> diff --git a/gdb/btrace.h b/gdb/btrace.h
> index 202b986..114242d 100644
> --- a/gdb/btrace.h
> +++ b/gdb/btrace.h
> @@ -405,9 +405,12 @@ extern void parse_xml_btrace_conf (struct
btrace_config *conf, const char *xml);
> extern const struct btrace_insn *
> btrace_insn_get (const struct btrace_insn_iterator *);
>
> +/* Return the error code for a branch trace instruction iterator.
Returns zero
> + if there is no error, i.e. the instruction is valid. */
> +extern int btrace_insn_get_error (const struct btrace_insn_iterator *);
> +
> /* Return the instruction number for a branch trace iterator.
> - Returns one past the maximum instruction number for the end iterator.
> - Returns zero if the iterator does not point to a valid instruction.
*/
> + Returns one past the maximum instruction number for the end
iterator. */
> extern unsigned int btrace_insn_number (const struct
btrace_insn_iterator *);
>
> /* Initialize a branch trace instruction iterator to point to the
begin/end of
> @@ -433,7 +436,7 @@ extern unsigned int btrace_insn_prev (struct
btrace_insn_iterator *,
> extern int btrace_insn_cmp (const struct btrace_insn_iterator *lhs,
> const struct btrace_insn_iterator *rhs);
>
> -/* Find an instruction in the function branch trace by its number.
> +/* Find an instruction or gap in the function branch trace by its
number.
> If the instruction is found, initialize the branch trace instruction
> iterator to point to this instruction and return non-zero.
> Return zero otherwise. */
> diff --git a/gdb/record-btrace.c b/gdb/record-btrace.c
> index 7c0e39f..6c50bab 100644
> --- a/gdb/record-btrace.c
> +++ b/gdb/record-btrace.c
> @@ -439,28 +439,12 @@ record_btrace_info (struct target_ops *self)
> calls = btrace_call_number (&call);
>
> btrace_insn_end (&insn, btinfo);
> -
> insns = btrace_insn_number (&insn);
> - if (insns != 0)
> - {
> - /* The last instruction does not really belong to the trace. */
> - insns -= 1;
> - }
> - else
> - {
> - unsigned int steps;
>
> - /* Skip gaps at the end. */
> - do
> - {
> - steps = btrace_insn_prev (&insn, 1);
> - if (steps == 0)
> - break;
> -
> - insns = btrace_insn_number (&insn);
> - }
> - while (insns == 0);
> - }
> + /* If the last instruction is not a gap, it is the current
instruction
> + that is not actually part of the record. */
> + if (btrace_insn_get (&insn) != NULL)
> + insns -= 1;
>
> gaps = btinfo->ngaps;
> }
> @@ -736,7 +720,11 @@ btrace_insn_history (struct ui_out *uiout,
> /* We have trace so we must have a configuration. */
> gdb_assert (conf != NULL);
>
> - btrace_ui_out_decode_error (uiout, it.function->errcode,
> + ui_out_field_fmt (uiout, "insn-number", "%u",
> + btrace_insn_number (&it));
> + ui_out_text (uiout, "\t");
> +
> + btrace_ui_out_decode_error (uiout, btrace_insn_get_error (&it),
> conf->format);
> }
> else
> @@ -2827,7 +2815,9 @@ record_btrace_goto (struct target_ops *self,
ULONGEST insn)
> tp = require_btrace_thread ();
>
> found = btrace_find_insn_by_number (&it, &tp->btrace, number);
> - if (found == 0)
> +
> + /* Check if the instruction could not be found or is a gap. */
> + if (found == 0 || btrace_insn_get (&it) == NULL)
> error (_("No such instruction."));
>
> record_btrace_set_replay (tp, &it);
> --
> 2.7.4
>
^ permalink raw reply [flat|nested] 3+ messages in thread* [PATCH v3 0/8] Python bindings for btrace recordings
@ 2016-11-21 15:49 Tim Wiederhake
2016-11-21 15:49 ` [PATCH v3 1/8] btrace: Count gaps as one instruction explicitly Tim Wiederhake
0 siblings, 1 reply; 3+ messages in thread
From: Tim Wiederhake @ 2016-11-21 15:49 UTC (permalink / raw)
To: gdb-patches; +Cc: palves, markus.t.metzger
This patch series adds Python bindings for btrace recordings.
V1 of this series can be found here:
https://sourceware.org/ml/gdb-patches/2016-10/msg00733.html
V2 of this series can be found here:
https://sourceware.org/ml/gdb-patches/2016-11/msg00084.html
Changes in V3:
- Rebased to current master.
- Replaced some strncmp with strcmp in patch 4 ("Add record_start function").
- Incorporated Eli's feedback regarding the documentation part.
Tim Wiederhake (8):
btrace: Count gaps as one instruction explicitly.
btrace: Export btrace_decode_error function.
btrace: Use binary search to find instruction.
Add record_start function.
python: Create Python bindings for record history.
python: Implement btrace Python bindings for record history.
python: Add tests for record Python bindings
Add documentation for new instruction record Python bindings.
gdb/Makefile.in | 4 +
gdb/NEWS | 4 +
gdb/btrace.c | 163 +++--
gdb/btrace.h | 21 +-
gdb/doc/python.texi | 237 ++++++
gdb/python/py-btrace.c | 994 ++++++++++++++++++++++++++
gdb/python/py-btrace.h | 32 +
gdb/python/py-record.c | 257 +++++++
gdb/python/py-record.h | 57 ++
gdb/python/python-internal.h | 7 +
gdb/python/python.c | 14 +
gdb/record-btrace.c | 131 ++--
gdb/record-full.c | 20 +
gdb/record.c | 28 +
gdb/record.h | 5 +
gdb/target-debug.h | 2 +
gdb/target-delegates.c | 33 +
gdb/target.c | 7 +
gdb/target.h | 10 +
gdb/testsuite/gdb.python/py-record-btrace.c | 48 ++
gdb/testsuite/gdb.python/py-record-btrace.exp | 160 +++++
21 files changed, 2096 insertions(+), 138 deletions(-)
create mode 100644 gdb/python/py-btrace.c
create mode 100644 gdb/python/py-btrace.h
create mode 100644 gdb/python/py-record.c
create mode 100644 gdb/python/py-record.h
create mode 100644 gdb/testsuite/gdb.python/py-record-btrace.c
create mode 100644 gdb/testsuite/gdb.python/py-record-btrace.exp
--
2.7.4
^ permalink raw reply [flat|nested] 3+ messages in thread* [PATCH v3 1/8] btrace: Count gaps as one instruction explicitly.
2016-11-21 15:49 [PATCH v3 0/8] Python bindings for btrace recordings Tim Wiederhake
@ 2016-11-21 15:49 ` Tim Wiederhake
2016-11-29 15:47 ` Metzger, Markus T
0 siblings, 1 reply; 3+ messages in thread
From: Tim Wiederhake @ 2016-11-21 15:49 UTC (permalink / raw)
To: gdb-patches; +Cc: palves, markus.t.metzger
This gives all instructions, including gaps, a unique number. Add a function
to retrieve the error code if a btrace instruction iterator points to an
invalid instruction.
2016-11-21 Tim Wiederhake <tim.wiederhake@intel.com>
gdb/ChangeLog:
* btrace.c (ftrace_call_num_insn, btrace_insn_get_error): New function.
(ftrace_new_function, btrace_insn_number, btrace_insn_cmp,
btrace_find_insn_by_number): Remove special case for gaps.
* btrace.h (btrace_insn_get_error): New export.
(btrace_insn_number, btrace_find_insn_by_number): Adjust comment.
* record-btrace.c (btrace_insn_history): Print number for gaps.
(record_btrace_info, record_btrace_goto): Handle gaps.
---
gdb/btrace.c | 83 +++++++++++++++++------------------------------------
gdb/btrace.h | 9 ++++--
gdb/record-btrace.c | 34 ++++++++--------------
3 files changed, 45 insertions(+), 81 deletions(-)
diff --git a/gdb/btrace.c b/gdb/btrace.c
index 39d537c..7df1b00 100644
--- a/gdb/btrace.c
+++ b/gdb/btrace.c
@@ -141,6 +141,20 @@ ftrace_debug (const struct btrace_function *bfun, const char *prefix)
prefix, fun, file, level, ibegin, iend);
}
+/* Return the number of instructions in a given function call segment. */
+
+static unsigned int
+ftrace_call_num_insn (const struct btrace_function* bfun)
+{
+ if (bfun == NULL)
+ return 0;
+
+ if (bfun->errcode != 0)
+ return 1;
+
+ return VEC_length (btrace_insn_s, bfun->insn);
+}
+
/* Return non-zero if BFUN does not match MFUN and FUN,
return zero otherwise. */
@@ -216,8 +230,7 @@ ftrace_new_function (struct btrace_function *prev,
prev->flow.next = bfun;
bfun->number = prev->number + 1;
- bfun->insn_offset = (prev->insn_offset
- + VEC_length (btrace_insn_s, prev->insn));
+ bfun->insn_offset = prev->insn_offset + ftrace_call_num_insn (prev);
bfun->level = prev->level;
}
@@ -2150,18 +2163,18 @@ btrace_insn_get (const struct btrace_insn_iterator *it)
/* See btrace.h. */
-unsigned int
-btrace_insn_number (const struct btrace_insn_iterator *it)
+int
+btrace_insn_get_error (const struct btrace_insn_iterator *it)
{
- const struct btrace_function *bfun;
-
- bfun = it->function;
+ return it->function->errcode;
+}
- /* Return zero if the iterator points to a gap in the trace. */
- if (bfun->errcode != 0)
- return 0;
+/* See btrace.h. */
- return bfun->insn_offset + it->index;
+unsigned int
+btrace_insn_number (const struct btrace_insn_iterator *it)
+{
+ return it->function->insn_offset + it->index;
}
/* See btrace.h. */
@@ -2356,37 +2369,6 @@ btrace_insn_cmp (const struct btrace_insn_iterator *lhs,
lnum = btrace_insn_number (lhs);
rnum = btrace_insn_number (rhs);
- /* A gap has an instruction number of zero. Things are getting more
- complicated if gaps are involved.
-
- We take the instruction number offset from the iterator's function.
- This is the number of the first instruction after the gap.
-
- This is OK as long as both lhs and rhs point to gaps. If only one of
- them does, we need to adjust the number based on the other's regular
- instruction number. Otherwise, a gap might compare equal to an
- instruction. */
-
- if (lnum == 0 && rnum == 0)
- {
- lnum = lhs->function->insn_offset;
- rnum = rhs->function->insn_offset;
- }
- else if (lnum == 0)
- {
- lnum = lhs->function->insn_offset;
-
- if (lnum == rnum)
- lnum -= 1;
- }
- else if (rnum == 0)
- {
- rnum = rhs->function->insn_offset;
-
- if (rnum == lnum)
- rnum -= 1;
- }
-
return (int) (lnum - rnum);
}
@@ -2398,26 +2380,15 @@ btrace_find_insn_by_number (struct btrace_insn_iterator *it,
unsigned int number)
{
const struct btrace_function *bfun;
- unsigned int end, length;
for (bfun = btinfo->end; bfun != NULL; bfun = bfun->flow.prev)
- {
- /* Skip gaps. */
- if (bfun->errcode != 0)
- continue;
-
- if (bfun->insn_offset <= number)
- break;
- }
+ if (bfun->insn_offset <= number)
+ break;
if (bfun == NULL)
return 0;
- length = VEC_length (btrace_insn_s, bfun->insn);
- gdb_assert (length > 0);
-
- end = bfun->insn_offset + length;
- if (end <= number)
+ if (bfun->insn_offset + ftrace_call_num_insn (bfun) <= number)
return 0;
it->function = bfun;
diff --git a/gdb/btrace.h b/gdb/btrace.h
index 202b986..114242d 100644
--- a/gdb/btrace.h
+++ b/gdb/btrace.h
@@ -405,9 +405,12 @@ extern void parse_xml_btrace_conf (struct btrace_config *conf, const char *xml);
extern const struct btrace_insn *
btrace_insn_get (const struct btrace_insn_iterator *);
+/* Return the error code for a branch trace instruction iterator. Returns zero
+ if there is no error, i.e. the instruction is valid. */
+extern int btrace_insn_get_error (const struct btrace_insn_iterator *);
+
/* Return the instruction number for a branch trace iterator.
- Returns one past the maximum instruction number for the end iterator.
- Returns zero if the iterator does not point to a valid instruction. */
+ Returns one past the maximum instruction number for the end iterator. */
extern unsigned int btrace_insn_number (const struct btrace_insn_iterator *);
/* Initialize a branch trace instruction iterator to point to the begin/end of
@@ -433,7 +436,7 @@ extern unsigned int btrace_insn_prev (struct btrace_insn_iterator *,
extern int btrace_insn_cmp (const struct btrace_insn_iterator *lhs,
const struct btrace_insn_iterator *rhs);
-/* Find an instruction in the function branch trace by its number.
+/* Find an instruction or gap in the function branch trace by its number.
If the instruction is found, initialize the branch trace instruction
iterator to point to this instruction and return non-zero.
Return zero otherwise. */
diff --git a/gdb/record-btrace.c b/gdb/record-btrace.c
index 7c0e39f..6c50bab 100644
--- a/gdb/record-btrace.c
+++ b/gdb/record-btrace.c
@@ -439,28 +439,12 @@ record_btrace_info (struct target_ops *self)
calls = btrace_call_number (&call);
btrace_insn_end (&insn, btinfo);
-
insns = btrace_insn_number (&insn);
- if (insns != 0)
- {
- /* The last instruction does not really belong to the trace. */
- insns -= 1;
- }
- else
- {
- unsigned int steps;
- /* Skip gaps at the end. */
- do
- {
- steps = btrace_insn_prev (&insn, 1);
- if (steps == 0)
- break;
-
- insns = btrace_insn_number (&insn);
- }
- while (insns == 0);
- }
+ /* If the last instruction is not a gap, it is the current instruction
+ that is not actually part of the record. */
+ if (btrace_insn_get (&insn) != NULL)
+ insns -= 1;
gaps = btinfo->ngaps;
}
@@ -736,7 +720,11 @@ btrace_insn_history (struct ui_out *uiout,
/* We have trace so we must have a configuration. */
gdb_assert (conf != NULL);
- btrace_ui_out_decode_error (uiout, it.function->errcode,
+ ui_out_field_fmt (uiout, "insn-number", "%u",
+ btrace_insn_number (&it));
+ ui_out_text (uiout, "\t");
+
+ btrace_ui_out_decode_error (uiout, btrace_insn_get_error (&it),
conf->format);
}
else
@@ -2827,7 +2815,9 @@ record_btrace_goto (struct target_ops *self, ULONGEST insn)
tp = require_btrace_thread ();
found = btrace_find_insn_by_number (&it, &tp->btrace, number);
- if (found == 0)
+
+ /* Check if the instruction could not be found or is a gap. */
+ if (found == 0 || btrace_insn_get (&it) == NULL)
error (_("No such instruction."));
record_btrace_set_replay (tp, &it);
--
2.7.4
^ permalink raw reply [flat|nested] 3+ messages in thread* RE: [PATCH v3 1/8] btrace: Count gaps as one instruction explicitly.
2016-11-21 15:49 ` [PATCH v3 1/8] btrace: Count gaps as one instruction explicitly Tim Wiederhake
@ 2016-11-29 15:47 ` Metzger, Markus T
0 siblings, 0 replies; 3+ messages in thread
From: Metzger, Markus T @ 2016-11-29 15:47 UTC (permalink / raw)
To: Wiederhake, Tim, gdb-patches; +Cc: palves
> -----Original Message-----
> From: Wiederhake, Tim
> Sent: Monday, November 21, 2016 4:49 PM
> To: gdb-patches@sourceware.org
> Cc: palves@redhat.com; Metzger, Markus T <markus.t.metzger@intel.com>
> Subject: [PATCH v3 1/8] btrace: Count gaps as one instruction explicitly.
>
> This gives all instructions, including gaps, a unique number. Add a function
> to retrieve the error code if a btrace instruction iterator points to an
> invalid instruction.
>
> 2016-11-21 Tim Wiederhake <tim.wiederhake@intel.com>
>
> gdb/ChangeLog:
>
> * btrace.c (ftrace_call_num_insn, btrace_insn_get_error): New function.
> (ftrace_new_function, btrace_insn_number, btrace_insn_cmp,
> btrace_find_insn_by_number): Remove special case for gaps.
> * btrace.h (btrace_insn_get_error): New export.
> (btrace_insn_number, btrace_find_insn_by_number): Adjust comment.
> * record-btrace.c (btrace_insn_history): Print number for gaps.
> (record_btrace_info, record_btrace_goto): Handle gaps.
Looks good to me.
Thanks,
Markus.
Intel Deutschland GmbH
Registered Address: Am Campeon 10-12, 85579 Neubiberg, Germany
Tel: +49 89 99 8853-0, www.intel.de
Managing Directors: Christin Eisenschmid, Christian Lamprechter
Chairperson of the Supervisory Board: Nicole Lau
Registered Office: Munich
Commercial Register: Amtsgericht Muenchen HRB 186928
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2016-11-30 23:34 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-11-30 23:34 [PATCH v3 1/8] btrace: Count gaps as one instruction explicitly Doug Evans
-- strict thread matches above, loose matches on Subject: below --
2016-11-21 15:49 [PATCH v3 0/8] Python bindings for btrace recordings Tim Wiederhake
2016-11-21 15:49 ` [PATCH v3 1/8] btrace: Count gaps as one instruction explicitly Tim Wiederhake
2016-11-29 15:47 ` Metzger, Markus T
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox