[04/10] btrace: Handle stepping and goto for auxiliary instructions.

Message ID 1559119673-30516-5-git-send-email-felix.willgerodt@intel.com
State New
Headers show
Series
  • Extensions for PTWRITE
Related show

Commit Message

felix.willgerodt@intel.com May 29, 2019, 8:47 a.m.
From: Felix Willgerodt <felix.willgerodt@intel.com>


Print the auxiliary data when stepping. Don't allow to goto an auxiliary
instruction.

This patch is in preparation for the ptwrite feature, which is based on
auxiliary instructions.

2019-05-29  Felix Willgerodt  <felix.willgerodt@intel.com>

gdb/ChangeLog:
	* record-btrace.c: (record_btrace_single_step_forward): Handle
	BTRACE_INSN_AUX.
	(record_btrace_single_step_backward): Likewise.
	(record_btrace_goto): Likewise.

---
 gdb/record-btrace.c | 52 ++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 44 insertions(+), 8 deletions(-)

-- 
2.20.1

Comments

Metzger, Markus T June 4, 2019, 12:35 p.m. | #1
Hello Felix,

> @@ -2378,13 +2380,26 @@ record_btrace_single_step_forward (struct thread_info

> *tp)

>    if (record_btrace_replay_at_breakpoint (tp))

>      return btrace_step_stopped ();

> 

> -  /* Skip gaps during replay.  If we end up at a gap (at the end of the trace),

> -     jump back to the instruction at which we started.  */

>    start = *replay;


Please preserve the order of comment and code.

> +

> +  /* Skip gaps during replay.  If we end up at a gap (at the end of the trace),

> +     jump back to the instruction at which we started.  If we're stepping a

> +     BTRACE_INSN_AUX instruction, print the ptwrite string and skip the


Should this say 'print the aux data'?

> +     instruction.  */

>    do

>      {

>        unsigned int steps;

> 

> +      /* If we're stepping a BTRACE_INSN_AUX instruction, print the auxiliary

> +	 data and skip the instruction.  If we are at the end of the trace, jump

> +	 back to the instruction at which we started.  */

> +      bfun = &replay->btinfo->functions[replay->call_index];

> +      next_insn = bfun->insn[replay->insn_index + 1];


The below btrace_insn_next () already advances REPLAY to the next instruction.  You may
use btrace_insn_next (replay) to get that instruction.

> +

> +      if (next_insn.iclass == BTRACE_INSN_AUX)

> +	printf_unfiltered (

> +	    "[%s]\n", btinfo->aux_data[next_insn.aux_data_index].c_str ());

> +

>        /* We will bail out here if we continue stepping after reaching the end

>  	 of the execution history.  */

>        steps = btrace_insn_next (replay, 1);

> @@ -2394,7 +2409,8 @@ record_btrace_single_step_forward (struct thread_info

> *tp)

>  	  return btrace_step_no_history ();

>  	}

>      }

> -  while (btrace_insn_get (replay) == NULL);

> +  while (btrace_insn_get (replay) == NULL

> +	 || next_insn.iclass == BTRACE_INSN_AUX);


Since we now call btrace_insn_get (replay) inside the loop, we should rewrite this.

> @@ -2452,6 +2470,22 @@ record_btrace_single_step_backward (struct

> thread_info *tp)

>    if (record_btrace_replay_at_breakpoint (tp))

>      return btrace_step_stopped ();

> 

> +  /* Check if we're stepping a BTRACE_INSN_AUX instruction and skip it.  */

> +  bfun = &replay->btinfo->functions[replay->call_index];

> +  prev_insn = bfun->insn[replay->insn_index];


Same here.

> +

> +  if (prev_insn.iclass == BTRACE_INSN_AUX)

> +    {

> +      printf_unfiltered ("[%s]\n",

> +			 btinfo->aux_data[prev_insn.aux_data_index].c_str ());

> +      unsigned int steps = btrace_insn_prev (replay, 1);

> +      if (steps == 0)

> +	{

> +	  *replay = start;

> +	  return btrace_step_no_history ();

> +	}

> +    }

> +

>    return btrace_step_spurious ();

>  }

> 

> @@ -2853,25 +2887,27 @@ record_btrace_target::goto_record_end ()

>  /* The goto_record method of target record-btrace.  */

> 

>  void

> -record_btrace_target::goto_record (ULONGEST insn)

> +record_btrace_target::goto_record (ULONGEST insn_number)

>  {

>    struct thread_info *tp;

>    struct btrace_insn_iterator it;

>    unsigned int number;

>    int found;

> 

> -  number = insn;

> +  number = insn_number;

> 

>    /* Check for wrap-arounds.  */

> -  if (number != insn)

> +  if (number != insn_number)

>      error (_("Instruction number out of range."));

> 

>    tp = require_btrace_thread ();

> 

>    found = btrace_find_insn_by_number (&it, &tp->btrace, number);

> +  const struct btrace_insn *insn = btrace_insn_get (&it);


You need to check FOUND before dereferencing IT.

> 

> -  /* Check if the instruction could not be found or is a gap.  */

> -  if (found == 0 || btrace_insn_get (&it) == NULL)

> +  /* Check if the instruction could not be found or is a gap or an

> +     auxilliary instruction.  */

> +  if ((found == 0) || (insn == NULL) || (insn->iclass == BTRACE_INSN_AUX))

>      error (_("No such instruction."));

> 

>    record_btrace_set_replay (tp, &it);

> --

> 2.20.1


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, Gary Kershaw
Chairperson of the Supervisory Board: Nicole Lau
Registered Office: Munich
Commercial Register: Amtsgericht Muenchen HRB 186928

Patch

diff --git a/gdb/record-btrace.c b/gdb/record-btrace.c
index 5f70c4838a9..573326924a2 100644
--- a/gdb/record-btrace.c
+++ b/gdb/record-btrace.c
@@ -2366,6 +2366,8 @@  record_btrace_single_step_forward (struct thread_info *tp)
 {
   struct btrace_insn_iterator *replay, end, start;
   struct btrace_thread_info *btinfo;
+  const struct btrace_function *bfun;
+  struct btrace_insn next_insn;
 
   btinfo = &tp->btrace;
   replay = btinfo->replay;
@@ -2378,13 +2380,26 @@  record_btrace_single_step_forward (struct thread_info *tp)
   if (record_btrace_replay_at_breakpoint (tp))
     return btrace_step_stopped ();
 
-  /* Skip gaps during replay.  If we end up at a gap (at the end of the trace),
-     jump back to the instruction at which we started.  */
   start = *replay;
+
+  /* Skip gaps during replay.  If we end up at a gap (at the end of the trace),
+     jump back to the instruction at which we started.  If we're stepping a
+     BTRACE_INSN_AUX instruction, print the ptwrite string and skip the
+     instruction.  */
   do
     {
       unsigned int steps;
 
+      /* If we're stepping a BTRACE_INSN_AUX instruction, print the auxiliary
+	 data and skip the instruction.  If we are at the end of the trace, jump
+	 back to the instruction at which we started.  */
+      bfun = &replay->btinfo->functions[replay->call_index];
+      next_insn = bfun->insn[replay->insn_index + 1];
+
+      if (next_insn.iclass == BTRACE_INSN_AUX)
+	printf_unfiltered (
+	    "[%s]\n", btinfo->aux_data[next_insn.aux_data_index].c_str ());
+
       /* We will bail out here if we continue stepping after reaching the end
 	 of the execution history.  */
       steps = btrace_insn_next (replay, 1);
@@ -2394,7 +2409,8 @@  record_btrace_single_step_forward (struct thread_info *tp)
 	  return btrace_step_no_history ();
 	}
     }
-  while (btrace_insn_get (replay) == NULL);
+  while (btrace_insn_get (replay) == NULL
+	 || next_insn.iclass == BTRACE_INSN_AUX);
 
   /* Determine the end of the instruction trace.  */
   btrace_insn_end (&end, btinfo);
@@ -2415,6 +2431,8 @@  record_btrace_single_step_backward (struct thread_info *tp)
 {
   struct btrace_insn_iterator *replay, start;
   struct btrace_thread_info *btinfo;
+  const struct btrace_function *bfun;
+  struct btrace_insn prev_insn;
 
   btinfo = &tp->btrace;
   replay = btinfo->replay;
@@ -2452,6 +2470,22 @@  record_btrace_single_step_backward (struct thread_info *tp)
   if (record_btrace_replay_at_breakpoint (tp))
     return btrace_step_stopped ();
 
+  /* Check if we're stepping a BTRACE_INSN_AUX instruction and skip it.  */
+  bfun = &replay->btinfo->functions[replay->call_index];
+  prev_insn = bfun->insn[replay->insn_index];
+
+  if (prev_insn.iclass == BTRACE_INSN_AUX)
+    {
+      printf_unfiltered ("[%s]\n",
+			 btinfo->aux_data[prev_insn.aux_data_index].c_str ());
+      unsigned int steps = btrace_insn_prev (replay, 1);
+      if (steps == 0)
+	{
+	  *replay = start;
+	  return btrace_step_no_history ();
+	}
+    }
+
   return btrace_step_spurious ();
 }
 
@@ -2853,25 +2887,27 @@  record_btrace_target::goto_record_end ()
 /* The goto_record method of target record-btrace.  */
 
 void
-record_btrace_target::goto_record (ULONGEST insn)
+record_btrace_target::goto_record (ULONGEST insn_number)
 {
   struct thread_info *tp;
   struct btrace_insn_iterator it;
   unsigned int number;
   int found;
 
-  number = insn;
+  number = insn_number;
 
   /* Check for wrap-arounds.  */
-  if (number != insn)
+  if (number != insn_number)
     error (_("Instruction number out of range."));
 
   tp = require_btrace_thread ();
 
   found = btrace_find_insn_by_number (&it, &tp->btrace, number);
+  const struct btrace_insn *insn = btrace_insn_get (&it);
 
-  /* Check if the instruction could not be found or is a gap.  */
-  if (found == 0 || btrace_insn_get (&it) == NULL)
+  /* Check if the instruction could not be found or is a gap or an
+     auxilliary instruction.  */
+  if ((found == 0) || (insn == NULL) || (insn->iclass == BTRACE_INSN_AUX))
     error (_("No such instruction."));
 
   record_btrace_set_replay (tp, &it);