This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

RE: [PATCH 3/3] btrace: support decoder events


Ping.

Thanks,
Markus.

> -----Original Message-----
> From: gdb-patches-owner@sourceware.org [mailto:gdb-patches-
> owner@sourceware.org] On Behalf Of Markus Metzger
> Sent: Friday, April 28, 2017 4:44 PM
> To: gdb-patches@sourceware.org
> Subject: [PATCH 3/3] btrace: support decoder events
> 
> Newer versions of libipt support instruction flow decoder events instead of
> indicating those events with flags in struct pt_insn.  Add support for them in
> GDB.
> 
> 2017-04-28  Markus Metzger  <markus.t.metzger@intel.com>
> 
> gdb/
> 	* btrace.c (handle_pt_insn_events): New.
> 	(ftrace_add_pt): Call handle_pt_insn_events.  Rename ERRCODE into
> 	STATUS.  Split into this and ...
> 	(handle_pt_insn_event_flags): ... this.
> 
> 
> ---
>  gdb/btrace.c | 174 +++++++++++++++++++++++++++++++++++++++++++-------------
> ---
>  1 file changed, 127 insertions(+), 47 deletions(-)
> 
> diff --git a/gdb/btrace.c b/gdb/btrace.c
> index 6780e22..21d0be9 100644
> --- a/gdb/btrace.c
> +++ b/gdb/btrace.c
> @@ -1132,6 +1132,116 @@ pt_btrace_insn (const struct pt_insn &insn)
>  	  pt_btrace_insn_flags (insn)};
>  }
> 
> +/* Handle instruction decode events (libipt-v2).  */
> +
> +static int
> +handle_pt_insn_events (struct pt_insn_decoder *decoder,
> +		       struct btrace_function **pbegin,
> +		       struct btrace_function **pend,
> +		       VEC (bfun_s) **gaps, int status)
> +{
> +#if defined (HAVE_PT_INSN_EVENT)
> +  while (status & pts_event_pending)
> +    {
> +      struct pt_event event;
> +      uint64_t offset;
> +
> +      status = pt_insn_event (decoder, &event, sizeof (event));
> +      if (status < 0)
> +	break;
> +
> +      switch (event.type)
> +	{
> +	default:
> +	  break;
> +
> +	case ptev_enabled:
> +	  if (*pbegin != NULL && event.variant.enabled.resumed == 0)
> +	    {
> +	      *pend = ftrace_new_gap (*pend, BDE_PT_DISABLED);
> +	      if (*pbegin == NULL)
> +		*pbegin = *pend;
> +
> +	      VEC_safe_push (bfun_s, *gaps, *pend);
> +
> +	      pt_insn_get_offset (decoder, &offset);
> +
> +	      warning (_("Non-contiguous trace at instruction %u (offset = 0x%"
> +			 PRIx64 ")."), (*pend)->insn_offset - 1, offset);
> +	    }
> +
> +	  break;
> +
> +	case ptev_overflow:
> +	  *pend = ftrace_new_gap (*pend, BDE_PT_OVERFLOW);
> +	  if (*pbegin == NULL)
> +	    *pbegin = *pend;
> +
> +	  VEC_safe_push (bfun_s, *gaps, *pend);
> +
> +	  pt_insn_get_offset (decoder, &offset);
> +
> +	  warning (_("Overflow at instruction %u (offset = 0x%" PRIx64 ")."),
> +		   (*pend)->insn_offset - 1, offset);
> +
> +	  break;
> +	}
> +    }
> +#endif /* defined (HAVE_PT_INSN_EVENT) */
> +
> +  return status;
> +}
> +
> +/* Handle events indicated by flags in INSN (libipt-v1).  */
> +
> +static void
> +handle_pt_insn_event_flags (struct pt_insn_decoder *decoder,
> +			    const struct pt_insn *insn,
> +			    struct btrace_function **pbegin,
> +			    struct btrace_function **pend,
> +			    VEC (bfun_s) **gaps)
> +{
> +#if defined (HAVE_STRUCT_PT_INSN_ENABLED)
> +  /* Tracing is disabled and re-enabled each time we enter the kernel.  Most
> +     times, we continue from the same instruction we stopped before.  This is
> +     indicated via the RESUMED instruction flag.  The ENABLED instruction flag
> +     means that we continued from some other instruction.  Indicate this as a
> +     trace gap except when tracing just started.  */
> +  if (insn.enabled && (*begin != NULL))
> +    {
> +      uint64_t offset;
> +
> +      *end = ftrace_new_gap (*end, BDE_PT_DISABLED);
> +
> +      VEC_safe_push (bfun_s, *gaps, *end);
> +
> +      pt_insn_get_offset (decoder, &offset);
> +
> +      warning (_("Non-contiguous trace at instruction %u (offset = 0x%" PRIx64
> +		 ", pc = 0x%" PRIx64 ")."), (*end)->insn_offset - 1, offset,
> +	       insn.ip);
> +    }
> +#endif /* defined (HAVE_STRUCT_PT_INSN_ENABLED) */
> +
> +#if defined (HAVE_STRUCT_PT_INSN_RESYNCED)
> +  /* Indicate trace overflows.  */
> +  if (insn.resynced)
> +    {
> +      uint64_t offset;
> +
> +      *end = ftrace_new_gap (*end, BDE_PT_OVERFLOW);
> +      if (*begin == NULL)
> +	*begin = *end;
> +
> +      VEC_safe_push (bfun_s, *gaps, *end);
> +
> +      pt_insn_get_offset (decoder, &offset);
> +
> +      warning (_("Overflow at instruction %u (offset = 0x%" PRIx64 ", pc = 0x%"
> +		 PRIx64 ")."), (*end)->insn_offset - 1, offset, insn.ip);
> +    }
> +#endif /* defined (HAVE_STRUCT_PT_INSN_RESYNCED) */
> +}
> 
>  /* Add function branch trace using DECODER.  */
> 
> @@ -1142,64 +1252,34 @@ ftrace_add_pt (struct pt_insn_decoder *decoder,
>  	       VEC (bfun_s) **gaps)
>  {
>    uint64_t offset;
> -  int errcode;
> +  int status;
> 
>    for (;;)
>      {
>        struct pt_insn insn;
> 
> -      errcode = pt_insn_sync_forward (decoder);
> -      if (errcode < 0)
> +      status = pt_insn_sync_forward (decoder);
> +      if (status < 0)
>  	{
> -	  if (errcode != -pte_eos)
> +	  if (status != -pte_eos)
>  	    warning (_("Failed to synchronize onto the Intel Processor "
> -		       "Trace stream: %s."), pt_errstr (pt_errcode (errcode)));
> +		       "Trace stream: %s."), pt_errstr (pt_errcode (status)));
>  	  break;
>  	}
> 
>        for (;;)
>  	{
> -	  errcode = pt_insn_next (decoder, &insn, sizeof(insn));
> -	  if (errcode < 0)
> +	  /* Handle events from the previous iteration or synchronization.  */
> +	  status = handle_pt_insn_events (decoder, begin, end, gaps, status);
> +	  if (status < 0)
>  	    break;
> 
> -	  /* Look for gaps in the trace - unless we're at the beginning.  */
> -	  if (*begin != NULL)
> -	    {
> -	      /* Tracing is disabled and re-enabled each time we enter the
> -		 kernel.  Most times, we continue from the same instruction we
> -		 stopped before.  This is indicated via the RESUMED instruction
> -		 flag.  The ENABLED instruction flag means that we continued
> -		 from some other instruction.  Indicate this as a trace gap.  */
> -	      if (insn.enabled)
> -		{
> -		  *end = ftrace_new_gap (*end, BDE_PT_DISABLED);
> -
> -		  VEC_safe_push (bfun_s, *gaps, *end);
> -
> -		  pt_insn_get_offset (decoder, &offset);
> -
> -		  warning (_("Non-contiguous trace at instruction %u (offset "
> -			     "= 0x%" PRIx64 ", pc = 0x%" PRIx64 ")."),
> -			   (*end)->insn_offset - 1, offset, insn.ip);
> -		}
> -	    }
> -
> -	  /* Indicate trace overflows.  */
> -	  if (insn.resynced)
> -	    {
> -	      *end = ftrace_new_gap (*end, BDE_PT_OVERFLOW);
> -	      if (*begin == NULL)
> -		*begin = *end;
> -
> -	      VEC_safe_push (bfun_s, *gaps, *end);
> -
> -	      pt_insn_get_offset (decoder, &offset);
> +	  status = pt_insn_next (decoder, &insn, sizeof(insn));
> +	  if (status < 0)
> +	    break;
> 
> -	      warning (_("Overflow at instruction %u (offset = 0x%" PRIx64
> -			 ", pc = 0x%" PRIx64 ")."), (*end)->insn_offset - 1,
> -		       offset, insn.ip);
> -	    }
> +	  /* Handle events indicated by flags in INSN.  */
> +	  handle_pt_insn_event_flags (decoder, &insn, begin, end, gaps);
> 
>  	  *end = ftrace_update_function (*end, insn.ip);
>  	  if (*begin == NULL)
> @@ -1212,11 +1292,11 @@ ftrace_add_pt (struct pt_insn_decoder *decoder,
>  	  ftrace_update_insns (*end, &btinsn);
>  	}
> 
> -      if (errcode == -pte_eos)
> +      if (status == -pte_eos)
>  	break;
> 
>        /* Indicate the gap in the trace.  */
> -      *end = ftrace_new_gap (*end, errcode);
> +      *end = ftrace_new_gap (*end, status);
>        if (*begin == NULL)
>  	*begin = *end;
> 
> @@ -1225,9 +1305,9 @@ ftrace_add_pt (struct pt_insn_decoder *decoder,
>        pt_insn_get_offset (decoder, &offset);
> 
>        warning (_("Decode error (%d) at instruction %u (offset = 0x%" PRIx64
> -		 ", pc = 0x%" PRIx64 "): %s."), errcode,
> +		 ", pc = 0x%" PRIx64 "): %s."), status,
>  	       (*end)->insn_offset - 1, offset, insn.ip,
> -	       pt_errstr (pt_errcode (errcode)));
> +	       pt_errstr (pt_errcode (status)));
>      }
>  }
> 
> --
> 1.8.3.1

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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]