public inbox for archer-commits@sourceware.org
help / color / mirror / Atom feed
* [SCM]  archer-mmetzger-btrace: record-btrace, disas: omit pc prefix
@ 2013-02-15 11:12 mmetzger
  0 siblings, 0 replies; only message in thread
From: mmetzger @ 2013-02-15 11:12 UTC (permalink / raw)
  To: archer-commits

The branch, archer-mmetzger-btrace has been updated
       via  25be2d9660d4357cf0d08c52fd96f8df29d389b0 (commit)
       via  9bd06db6df3084f844955c0b1c839bfad0abd9b8 (commit)
       via  86c07aaddf5f8e16baf0674c58df9218a6754706 (commit)
      from  204dbf91e3accdb741a90d00ed0833bb41457210 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email.

- Log -----------------------------------------------------------------
commit 25be2d9660d4357cf0d08c52fd96f8df29d389b0
Author: Markus Metzger <markus.t.metzger@intel.com>
Date:   Wed Feb 13 08:43:47 2013 +0100

    record-btrace, disas: omit pc prefix
    
    Add a disassembly flag to omit the pc prefix and use it in the "record
    disassembly" command of record-btrace.
    
    The pc prefix would appear multiple times in the branch trace disassembly,
    which is more confusing than helpful.
    
    Signed-off-by: Markus Metzger <markus.t.metzger@intel.com>
    
    	* record-btrace.c (disas_itrace): Omit the pc prefix in the branch
    	trace disassembly.
    	* disasm.c (dump_insns): Omit the pc prefix, if requested.
    	* disasm.h (DISASSEMBLY_OMIT_PC): New.
    
    Change-Id: I5c38256cc742ad9d6482ecc4d8800ab016c6f11b

commit 9bd06db6df3084f844955c0b1c839bfad0abd9b8
Author: Markus Metzger <markus.t.metzger@intel.com>
Date:   Thu Jan 31 08:53:33 2013 +0100

    btrace: add record-btrace target
    
    Add a target for branch tracing.
    
    I'm not quite sure when to use ui_out_~ functions and when to use
    print_funfiltered.  I tried to copy what others are doing, but I'm
    not sure whether I got it right.
    
    For the "record backtrace" command, I assume that symbols can be compared
    by comparing their pointers.  For comparing files, I use
    compare_filenames_for_search.  I'm not sure whether this is the appropriate
    function to use in this context.
    
    Signed-off-by: Markus Metzger  <markus.t.metzger@intel.com>
    
    	* Makefile.in (SFILES): Add record-btrace.c
    	(COMMON_OBS): Add record-btrace.o
    	* record-btrace.c: New.
    	* btrace.h (struct btrace_thread_info) <itrace>: New field.
    	(struct btrace_thread_info) <begin>: New field.
    	(struct btrace_thread_info) <end>: New field.
    	* common/btrace-common.h (btrace_inst): New struct.
    	(btrace_inst_s): New typedef.
    
    Change-Id: I6398cad67cd7de80f09173a601bc00d77fe8809f

commit 86c07aaddf5f8e16baf0674c58df9218a6754706
Author: Markus Metzger <markus.t.metzger@intel.com>
Date:   Fri Feb 15 11:30:12 2013 +0100

    record: allow +/- when specifying an instruction range
    
    When specifying a range of instructions in "record disassemble", "record"
    backtrace", and "record list", allow the second argument to be preceded by '+'
    or '-'.  In this case, it specifies the distance from the first argument.
    
    Signed-off-by: Markus Metzger <markus.t.metzger@intel.com>
    
    	* record.c (get_insn_range): Accept '+' and '-'.
    	(_initialize_record): Update help texts for "record disassemble",
    	"record backtrace", and "record list".
    
    Change-Id: Ifeeca384007dfe7b9f3c1b3f3b053e4991e95acf

-----------------------------------------------------------------------

Summary of changes:
 gdb/Makefile.in            |    4 +-
 gdb/btrace.h               |   26 ++
 gdb/common/btrace-common.h |   20 +-
 gdb/disasm.c               |    4 +-
 gdb/disasm.h               |    1 +
 gdb/record-btrace.c        |  976 ++++++++++++++++++++++++++++++++++++++++++++
 gdb/record.c               |   35 ++-
 7 files changed, 1059 insertions(+), 7 deletions(-)
 create mode 100644 gdb/record-btrace.c

First 500 lines of diff:
diff --git a/gdb/Makefile.in b/gdb/Makefile.in
index a36d576..5366d9e 100644
--- a/gdb/Makefile.in
+++ b/gdb/Makefile.in
@@ -760,7 +760,7 @@ SFILES = ada-exp.y ada-lang.c ada-typeprint.c ada-valprint.c ada-tasks.c \
 	regset.c sol-thread.c windows-termcap.c \
 	common/gdb_vecs.c common/common-utils.c common/xml-utils.c \
 	common/ptid.c common/buffer.c gdb-dlfcn.c common/agent.c \
-	common/format.c btrace.c
+	common/format.c btrace.c record-btrace.c
 
 LINTFILES = $(SFILES) $(YYFILES) $(CONFIG_SRCS) init.c
 
@@ -930,7 +930,7 @@ COMMON_OBS = $(DEPFILES) $(CONFIG_OBS) $(YYOBJ) \
 	inferior.o osdata.o gdb_usleep.o record.o record-full.o gcore.o \
 	gdb_vecs.o jit.o progspace.o skip.o probe.o \
 	common-utils.o buffer.o ptid.o gdb-dlfcn.o common-agent.o \
-	format.o registry.o btrace.o
+	format.o registry.o btrace.o record-btrace.o
 
 TSOBS = inflow.o
 
diff --git a/gdb/btrace.h b/gdb/btrace.h
index 26fafc7..61404e7 100644
--- a/gdb/btrace.h
+++ b/gdb/btrace.h
@@ -29,6 +29,25 @@
 #include "btrace-common.h"
 
 struct thread_info;
+struct btrace_thread_info;
+
+/* Branch trace iteration state for the "record disassemble" command.  */
+struct btrace_disas_state
+{
+  /* The instruction index range [begin; end[ that has been disassembled last.
+     If end < begin, nothing has been disassembled, yet.  */
+  unsigned int begin;
+  unsigned int end;
+};
+
+/* Branch trace iteration state for the "record backtrace" command.  */
+struct btrace_bt_state
+{
+  /* The instruction index range [begin; end[ that has been covered last time.
+     If end < begin, the branch trace has just been updated.  */
+  unsigned int begin;
+  unsigned int end;
+};
 
 /* Branch trace information per thread.
 
@@ -47,6 +66,7 @@ struct btrace_thread_info
 
   /* The current branch trace for this thread.  */
   VEC (btrace_block_s) *btrace;
+  VEC (btrace_inst_s) *itrace;
 
   /* The current iterator position in the above trace vector.
      In additon to valid vector indices, the iterator can be:
@@ -54,6 +74,12 @@ struct btrace_thread_info
        -1            one before the head
        VEC_length()  one after the tail  */
   int iterator;
+
+  /* The iteration state for "record disassemble".  */
+  struct btrace_disas_state disas;
+
+  /* The iteration state for "record backtrace".  */
+  struct btrace_bt_state bt;
 };
 
 /* Enable branch tracing for a thread.  */
diff --git a/gdb/common/btrace-common.h b/gdb/common/btrace-common.h
index 90372ba..c3f52f9 100644
--- a/gdb/common/btrace-common.h
+++ b/gdb/common/btrace-common.h
@@ -49,12 +49,26 @@ struct btrace_block
   CORE_ADDR end;
 };
 
-/* Branch trace is represented as a vector of branch trace blocks starting with
-   the most recent block.  */
+/* A branch trace instruction.
+
+   This represents a single instruction in a branch trace.  */
+struct btrace_inst
+{
+  /* The address of this instruction.  */
+  CORE_ADDR ip;
+};
+
+
+/* Branch trace may be represented as a vector of either:
+
+   - branch trace blocks starting with the most recent block.
+   - branch trace instructions starting with the oldest instruction.  */
 typedef struct btrace_block btrace_block_s;
+typedef struct btrace_inst btrace_inst_s;
 
-/* Define functions operating on a vector of branch trace blocks.  */
+/* Define functions operating on branch trace vectors.  */
 DEF_VEC_O (btrace_block_s);
+DEF_VEC_O (btrace_inst_s);
 
 /* Target specific branch trace information.  */
 struct btrace_target_info;
diff --git a/gdb/disasm.c b/gdb/disasm.c
index 9d61379..e643c2d 100644
--- a/gdb/disasm.c
+++ b/gdb/disasm.c
@@ -122,7 +122,9 @@ dump_insns (struct gdbarch *gdbarch, struct ui_out *uiout,
 	    num_displayed++;
 	}
       ui_out_chain = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
-      ui_out_text (uiout, pc_prefix (pc));
+
+      if ((flags & DISASSEMBLY_OMIT_PC) == 0)
+	ui_out_text (uiout, pc_prefix (pc));
       ui_out_field_core_addr (uiout, "address", gdbarch, pc);
 
       if (!build_address_symbolic (gdbarch, pc, 0, &name, &offset, &filename,
diff --git a/gdb/disasm.h b/gdb/disasm.h
index 20ceb2b..3743ccc 100644
--- a/gdb/disasm.h
+++ b/gdb/disasm.h
@@ -23,6 +23,7 @@
 #define DISASSEMBLY_RAW_INSN	(0x1 << 1)
 #define DISASSEMBLY_OMIT_FNAME	(0x1 << 2)
 #define DISASSEMBLY_FILENAME	(0x1 << 3)
+#define DISASSEMBLY_OMIT_PC	(0x1 << 4)
 
 struct ui_out;
 struct ui_file;
diff --git a/gdb/record-btrace.c b/gdb/record-btrace.c
new file mode 100644
index 0000000..6725f16
--- /dev/null
+++ b/gdb/record-btrace.c
@@ -0,0 +1,976 @@
+/* Branch trace support for GDB, the GNU debugger.
+
+   Copyright (C) 2013 Free Software Foundation, Inc.
+
+   Contributed by Intel Corp. <markus.t.metzger@intel.com>
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include "defs.h"
+#include "record.h"
+#include "gdbthread.h"
+#include "regcache.h"
+#include "target.h"
+#include "gdbcmd.h"
+#include "disasm.h"
+#include "observer.h"
+#include "exceptions.h"
+#include "cli/cli-utils.h"
+#include "source.h"
+#include "ui-out.h"
+#include "symtab.h"
+
+/* The target_ops of record-btrace.  */
+static struct target_ops record_btrace_ops;
+
+/* A new thread observer enabling branch tracing for the new thread.  */
+static struct observer *record_btrace_thread_observer;
+
+/* The record backtrace state.  */
+
+struct rec_bt_state
+{
+  /* The last function symbol.  */
+  struct minimal_symbol *mfun;
+  struct symbol *fun;
+
+  /* The name of the last function.  */
+  const char *function;
+
+  /* The last file name.  */
+  const char *filename;
+
+  /* The min and max line in the above file.  */
+  int begin;
+  int end;
+};
+
+/* A vector of record backtrace states.  */
+typedef struct rec_bt_state rec_bt_s;
+DEF_VEC_O (rec_bt_s);
+
+/* Define debug output flags.  */
+
+enum record_btrace_debug_flag
+  {
+    /* Print an overview of record-btrace functions.  */
+    debug_functions = 1 << 0,
+
+    /* Print details on "record backtrace".  */
+    debug_backtrace = 1 << 1
+  };
+
+/* Print a record-btrace debug message.  Use do ... while (0) to avoid
+   ambiguities when used in if statements.  */
+
+#define DEBUG(mask, msg, args...)					\
+  do									\
+    {									\
+      if ((record_debug & mask) != 0)					\
+        fprintf_unfiltered (gdb_stdlog,					\
+			    "record-btrace: " msg "\n", ##args);	\
+    }									\
+  while (0)
+
+#define DEBUG_FUN(msg, args...) DEBUG (debug_functions, msg, ##args)
+#define DEBUG_BT(msg, args...) DEBUG (debug_backtrace, "[bt] " msg, ##args)
+
+
+/* Initialize the "record disassemble" iteration state.  */
+
+static void
+btrace_init_disas_state (struct btrace_thread_info *btinfo)
+{
+  DEBUG_FUN ("init disas iterator");
+
+  btinfo->disas.begin = 1;
+  btinfo->disas.end = 0;
+}
+
+/* Initialize the "record backtrace" iteration state.  */
+
+static void
+btrace_init_bt_state (struct btrace_thread_info *btinfo)
+{
+  DEBUG_FUN ("init bt iterator");
+
+  btinfo->bt.begin = 1;
+  btinfo->bt.end = 0;
+}
+
+/* Compute the instruction trace from the block trace.  */
+
+static VEC (btrace_inst_s) *
+compute_itrace (VEC (btrace_block_s) *btrace)
+{
+  VEC (btrace_inst_s) *itrace;
+  struct gdbarch *gdbarch;
+  unsigned int b;
+
+  DEBUG_FUN ("compute itrace");
+
+  itrace = NULL;
+  gdbarch = target_gdbarch ();
+  b = VEC_length (btrace_block_s, btrace);
+
+  while (b-- != 0)
+    {
+      btrace_block_s *block;
+      CORE_ADDR ip;
+
+      block = VEC_index (btrace_block_s, btrace, b);
+      ip = block->begin;
+
+      /* Add instructions for this block.  */
+      for (;;)
+	{
+	  btrace_inst_s *inst;
+	  int size;
+
+	  /* We should hit the end of the block.  Warn if we went too far.  */
+	  if (block->end < ip)
+	    {
+	      warning (_("Trace disassembly may be corrupted."));
+	      break;
+	    }
+
+	  inst = VEC_safe_push (btrace_inst_s, itrace, NULL);
+	  inst->ip = ip;
+
+	  /* We're done once we pushed the instruction at the end.  */
+	  if (block->end == ip)
+	    break;
+
+	  size = gdb_insn_length (gdbarch, ip);
+
+	  /* Make sure we terminate if we fail to compute the size.  */
+	  if (size <= 0)
+	    {
+	      warning (_("Trace disassembly may be incomplete."));
+	      break;
+	    }
+
+	  ip += size;
+	}
+    }
+
+  return itrace;
+}
+
+/* Fetch the branch trace for TP.  */
+
+static void
+fetch_btrace (struct thread_info *tp)
+{
+  struct btrace_thread_info *btinfo;
+
+  DEBUG_FUN ("fetch trace");
+
+  btinfo = &tp->btrace;
+  if (btinfo->target == NULL)
+    return;
+
+  if (!target_btrace_has_changed (btinfo->target))
+    return;
+
+  VEC_free (btrace_block_s, btinfo->btrace);
+  VEC_free (btrace_inst_s, btinfo->itrace);
+
+  btinfo->btrace = target_read_btrace (btinfo->target);
+
+  /* The first block ends at the current pc.  */
+  if (!VEC_empty (btrace_block_s, btinfo->btrace))
+    {
+      struct regcache *regcache;
+      struct btrace_block *head;
+
+      regcache = get_thread_regcache (tp->ptid);
+      head = VEC_index (btrace_block_s, btinfo->btrace, 0);
+      if (head != NULL && head->end == 0)
+	head->end = regcache_read_pc (regcache);
+    }
+
+  btinfo->itrace = compute_itrace (btinfo->btrace);
+
+  /* Re-initialize branch trace iterators.  */
+  btrace_init_disas_state (btinfo);
+  btrace_init_bt_state (btinfo);
+}
+
+/* Update the branch trace for the current thread and return a pointer to it's
+   branch trace information struct.
+
+   Fails if there is no thread or no trace.  */
+
+static struct btrace_thread_info *
+require_btrace (void)
+{
+  struct thread_info *tp;
+  struct btrace_thread_info *btinfo;
+
+  DEBUG_FUN ("update trace");
+
+  tp = find_thread_ptid (inferior_ptid);
+  btinfo = &tp->btrace;
+
+  if (tp == NULL)
+    error (_("No thread."));
+
+  fetch_btrace (tp);
+
+  if (VEC_empty (btrace_inst_s, btinfo->itrace))
+    error (_("No trace."));
+
+  return btinfo;
+}
+
+/* Enable branch tracing for one thread.  */
+
+static void
+record_btrace_enable (struct thread_info *tp)
+{
+  DEBUG_FUN ("enable thread %d (%s)", tp->num, target_pid_to_str (tp->ptid));
+
+  if (tp->btrace.target != NULL)
+    error (_("Branch tracing is already enabled for thread %d (%s)."),
+	   tp->num, target_pid_to_str (tp->ptid));
+
+  tp->btrace.target = target_enable_btrace (tp->ptid);
+}
+
+/* Enable branch tracing for one thread.  Warn on errors.  */
+
+static void
+record_btrace_enable_warn (struct thread_info *tp)
+{
+  volatile struct gdb_exception error;
+
+  TRY_CATCH (error, RETURN_MASK_ERROR)
+    record_btrace_enable (tp);
+
+  if (error.message != NULL)
+    warning ("%s", error.message);
+}
+
+/* Disable branch tracing for one thread.  */
+
+static void
+record_btrace_disable (struct thread_info *tp)
+{
+  struct btrace_thread_info *btp;
+
+  DEBUG_FUN ("disable thread %d (%s)", tp->num, target_pid_to_str (tp->ptid));
+
+  btp = &tp->btrace;
+  if (btp->target == NULL)
+    error (_("Branch tracing is not enabled for thread %d (%s)."),
+	   tp->num, target_pid_to_str (tp->ptid));
+
+  target_disable_btrace (btp->target);
+  btp->target = NULL;
+
+  VEC_free (btrace_block_s, btp->btrace);
+}
+
+/* Callback function to enable branch tracing for one thread.  */
+
+static void
+record_btrace_disable_callback (void *arg)
+{
+  volatile struct gdb_exception error;
+  struct thread_info *tp;
+
+  tp = arg;
+
+  TRY_CATCH (error, RETURN_MASK_ERROR)
+    record_btrace_disable (tp);
+
+  if (error.message != NULL)
+    warning ("%s", error.message);
+}
+
+/* Enable automatic tracing of new threads.  */
+
+static void
+record_btrace_auto_enable (void)
+{
+  DEBUG_FUN ("attach thread observer");
+
+  record_btrace_thread_observer
+    = observer_attach_new_thread (record_btrace_enable_warn);
+}
+
+/* Disable automatic tracing of new threads.  */
+
+static void
+record_btrace_auto_disable (void)
+{
+  /* The observer may have been detached, already.  */
+  if (record_btrace_thread_observer == NULL)
+    return;
+
+  DEBUG_FUN ("detach thread observer");
+
+  observer_detach_new_thread (record_btrace_thread_observer);
+  record_btrace_thread_observer = NULL;
+}
+
+/* The to_open method of target record-btrace.  */
+
+static void
+record_btrace_open (char *args, int from_tty)
+{
+  struct cleanup *disable_chain;
+  struct thread_info *tp;
+
+  DEBUG_FUN ("open");
+
+  if (RECORD_IS_USED)
+    error (_("The process is already being recorded."));
+
+  if (!target_has_execution)
+    error (_("The program is not being run."));
+
+  if (!target_supports_btrace ())
+    error (_("Target does not support branch tracing."));
+
+  gdb_assert (record_btrace_thread_observer == NULL);
+
+  disable_chain = make_cleanup (null_cleanup, NULL);
+  ALL_THREADS (tp)
+    if (args == NULL || *args == 0 || number_is_in_list (args, tp->num))
+      {
+	record_btrace_enable (tp);
+
+	(void) make_cleanup (record_btrace_disable_callback, tp);
+      }
+


hooks/post-receive
--
Repository for Project Archer.


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2013-02-15 11:12 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-02-15 11:12 [SCM] archer-mmetzger-btrace: record-btrace, disas: omit pc prefix mmetzger

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).