public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
From: Antoine Tremblay <antoine.tremblay@ericsson.com>
To: <gdb-patches@sourceware.org>
Cc: Antoine Tremblay <antoine.tremblay@ericsson.com>
Subject: [PATCH v3 13/18] Export tracing control breakpoints functions via global function pointers
Date: Tue, 05 Jul 2016 13:41:00 -0000	[thread overview]
Message-ID: <1467726030-13020-14-git-send-email-antoine.tremblay@ericsson.com> (raw)
In-Reply-To: <1467726030-13020-1-git-send-email-antoine.tremblay@ericsson.com>

Since ARM has 2 instructions sets ARM, and Thumb and thus 2 breakpoint
instructions. GDBServer needs to know what kind of breakpoint to set in
the IPA for it's tracing controls breakpoints (stop_tracing, flush_trace_buffer,
about_to_request_buffer_space).

Since qSymbol does not carry the Thumb bit on the symbol address, this
patch exports a function pointer with the address of the function to be
read by GDBServer.

This way the Thumb bit is carried in that value and GDBServer sets the
proper breakpoint.

This patch adds a test that collects 10MB of data, so that a flush is
triggered after the IPA reaches its 5MB limit.

gdb/gdbserver/ChangeLog:
	* tracepoint.c (stop_tracing, flush_trace_buffer,
	about_to_request_buffer_space): Rename with _ptr suffix.
	(struct ipa_sym_addresses)<stop_tracing, flush_trace_buffer,
	about_to_request_buffer_space>: Likewise.
	(symbol_list): Likewise.
	(stop_tracing): Remove function export.
	(flush_trace_buffer): Likewise.
	(about_to_request_buffer_space): Likewise.
	(cmd_qtstart): Read breakpoint addresses from the inferior.
	(handle_tracepoint_bkpts): Likewise.
	(stop_tracing_ptr, flush_trace_buffer_ptr,
	(tracepoint_bkpt_ptr_type): New typedef.
	about_to_request_buffer_space_ptr): New globals.
	(upload_fast_traceframes): Read breakpoint address from the inferior.

gdb/testsuite/ChangeLog:

	* ftrace-flush-buffer.exp: New file.
	* ftrace-flush-buffer.c: Likewise.
---
 gdb/gdbserver/tracepoint.c                      | 94 ++++++++++++++++++------
 gdb/testsuite/gdb.trace/ftrace-flush-buffer.c   | 42 +++++++++++
 gdb/testsuite/gdb.trace/ftrace-flush-buffer.exp | 98 +++++++++++++++++++++++++
 3 files changed, 213 insertions(+), 21 deletions(-)
 create mode 100644 gdb/testsuite/gdb.trace/ftrace-flush-buffer.c
 create mode 100644 gdb/testsuite/gdb.trace/ftrace-flush-buffer.exp

diff --git a/gdb/gdbserver/tracepoint.c b/gdb/gdbserver/tracepoint.c
index a139f67..87211e9 100644
--- a/gdb/gdbserver/tracepoint.c
+++ b/gdb/gdbserver/tracepoint.c
@@ -109,9 +109,9 @@ trace_vdebug (const char *fmt, ...)
 # define gdb_trampoline_buffer_error IPA_SYM_EXPORTED_NAME (gdb_trampoline_buffer_error)
 # define collecting IPA_SYM_EXPORTED_NAME (collecting)
 # define gdb_collect_ptr IPA_SYM_EXPORTED_NAME (gdb_collect_ptr)
-# define stop_tracing IPA_SYM_EXPORTED_NAME (stop_tracing)
-# define flush_trace_buffer IPA_SYM_EXPORTED_NAME (flush_trace_buffer)
-# define about_to_request_buffer_space IPA_SYM_EXPORTED_NAME (about_to_request_buffer_space)
+# define stop_tracing_ptr IPA_SYM_EXPORTED_NAME (stop_tracing_ptr)
+# define flush_trace_buffer_ptr IPA_SYM_EXPORTED_NAME (flush_trace_buffer_ptr)
+# define about_to_request_buffer_space_ptr IPA_SYM_EXPORTED_NAME (about_to_request_buffer_space_ptr)
 # define trace_buffer_is_full IPA_SYM_EXPORTED_NAME (trace_buffer_is_full)
 # define stopping_tracepoint IPA_SYM_EXPORTED_NAME (stopping_tracepoint)
 # define expr_eval_result IPA_SYM_EXPORTED_NAME (expr_eval_result)
@@ -151,9 +151,9 @@ struct ipa_sym_addresses
   CORE_ADDR addr_gdb_trampoline_buffer_error;
   CORE_ADDR addr_collecting;
   CORE_ADDR addr_gdb_collect_ptr;
-  CORE_ADDR addr_stop_tracing;
-  CORE_ADDR addr_flush_trace_buffer;
-  CORE_ADDR addr_about_to_request_buffer_space;
+  CORE_ADDR addr_stop_tracing_ptr;
+  CORE_ADDR addr_flush_trace_buffer_ptr;
+  CORE_ADDR addr_about_to_request_buffer_space_ptr;
   CORE_ADDR addr_trace_buffer_is_full;
   CORE_ADDR addr_stopping_tracepoint;
   CORE_ADDR addr_expr_eval_result;
@@ -188,9 +188,9 @@ static struct
   IPA_SYM(gdb_trampoline_buffer_error),
   IPA_SYM(collecting),
   IPA_SYM(gdb_collect_ptr),
-  IPA_SYM(stop_tracing),
-  IPA_SYM(flush_trace_buffer),
-  IPA_SYM(about_to_request_buffer_space),
+  IPA_SYM(stop_tracing_ptr),
+  IPA_SYM(flush_trace_buffer_ptr),
+  IPA_SYM(about_to_request_buffer_space_ptr),
   IPA_SYM(trace_buffer_is_full),
   IPA_SYM(stopping_tracepoint),
   IPA_SYM(expr_eval_result),
@@ -368,14 +368,14 @@ read_inferior_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len)
 #  define UNKNOWN_SIDE_EFFECTS() do {} while (0)
 #endif
 
-IP_AGENT_EXPORT_FUNC void
+void
 stop_tracing (void)
 {
   /* GDBserver places breakpoint here.  */
   UNKNOWN_SIDE_EFFECTS();
 }
 
-IP_AGENT_EXPORT_FUNC void
+void
 flush_trace_buffer (void)
 {
   /* GDBserver places breakpoint here.  */
@@ -1379,7 +1379,7 @@ init_trace_buffer (LONGEST bufsize)
 
 #ifdef IN_PROCESS_AGENT
 
-IP_AGENT_EXPORT_FUNC void
+void
 about_to_request_buffer_space (void)
 {
   /* GDBserver places breakpoint here while it goes about to flush
@@ -3095,6 +3095,7 @@ cmd_qtstart (char *packet)
 {
   struct tracepoint *tpoint, *prev_ftpoint, *prev_stpoint;
   CORE_ADDR tpptr = 0, prev_tpptr = 0;
+  CORE_ADDR addr_flush_trace_buffer, addr_stop_tracing;
 
   trace_debug ("Starting the trace");
 
@@ -3291,14 +3292,29 @@ cmd_qtstart (char *packet)
 			  " in lib");
 	}
 
-      stop_tracing_bkpt = set_breakpoint_at (ipa_sym_addrs.addr_stop_tracing,
+      if (read_inferior_data_pointer (ipa_sym_addrs.addr_stop_tracing_ptr,
+				      &addr_stop_tracing))
+	{
+	  internal_error (__FILE__, __LINE__,
+			  "Error reading addr_stop_tracing_ptr variable"
+			  " in lib");
+	}
+
+      stop_tracing_bkpt = set_breakpoint_at (addr_stop_tracing,
 					     stop_tracing_handler);
       if (stop_tracing_bkpt == NULL)
 	error ("Error setting stop_tracing breakpoint");
 
-      flush_trace_buffer_bkpt
-	= set_breakpoint_at (ipa_sym_addrs.addr_flush_trace_buffer,
-			     flush_trace_buffer_handler);
+      if (read_inferior_data_pointer (ipa_sym_addrs.addr_flush_trace_buffer_ptr,
+				      &addr_flush_trace_buffer))
+	{
+	  internal_error (__FILE__, __LINE__,
+			  "Error reading addr_flsh_trace_ptr variable"
+			  " in lib");
+	}
+
+      flush_trace_buffer_bkpt = set_breakpoint_at (addr_flush_trace_buffer,
+						   flush_trace_buffer_handler);
       if (flush_trace_buffer_bkpt == NULL)
 	error ("Error setting flush_trace_buffer breakpoint");
     }
@@ -4385,6 +4401,8 @@ tracepoint_finished_step (struct thread_info *tinfo, CORE_ADDR stop_pc)
 int
 handle_tracepoint_bkpts (struct thread_info *tinfo, CORE_ADDR stop_pc)
 {
+  CORE_ADDR addr_stop_tracing, addr_flush_trace_buffer;
+
   /* Pull in fast tracepoint trace frames from the inferior in-process
      agent's buffer into our buffer.  */
 
@@ -4393,9 +4411,25 @@ handle_tracepoint_bkpts (struct thread_info *tinfo, CORE_ADDR stop_pc)
 
   upload_fast_traceframes ();
 
+  if (read_inferior_data_pointer (ipa_sym_addrs.addr_stop_tracing_ptr,
+				  &addr_stop_tracing))
+    {
+      internal_error (__FILE__, __LINE__,
+		      "Error reading addr_stop_tracing_ptr variable"
+		      " in lib");
+    }
+
+  if (read_inferior_data_pointer (ipa_sym_addrs.addr_flush_trace_buffer_ptr,
+				  &addr_flush_trace_buffer))
+    {
+      internal_error (__FILE__, __LINE__,
+		      "Error reading addr_flsh_trace_ptr variable"
+		      " in lib");
+    }
+
   /* Check if the in-process agent had decided we should stop
      tracing.  */
-  if (stop_pc == ipa_sym_addrs.addr_stop_tracing)
+  if (stop_pc == addr_stop_tracing)
     {
       int ipa_trace_buffer_is_full;
       CORE_ADDR ipa_stopping_tracepoint;
@@ -4452,7 +4486,7 @@ handle_tracepoint_bkpts (struct thread_info *tinfo, CORE_ADDR stop_pc)
       stop_tracing ();
       return 1;
     }
-  else if (stop_pc == ipa_sym_addrs.addr_flush_trace_buffer)
+  else if (stop_pc == addr_flush_trace_buffer)
     {
       trace_debug ("lib stopped at flush_trace_buffer");
       return 1;
@@ -5774,12 +5808,16 @@ gdb_collect (struct tracepoint *tpoint, unsigned char *regs)
 /* These global variables points to the corresponding functions.  This is
    necessary on powerpc64, where asking for function symbol address from gdb
    results in returning the actual code pointer, instead of the descriptor
-   pointer.  */
+   pointer.
+   These variables are also needed for ARM so that the address contains the
+   Thumb bit if the address is in thumb mode.
+ */
 
 typedef void (*gdb_collect_ptr_type) (struct tracepoint *, unsigned char *);
 typedef ULONGEST (*get_raw_reg_ptr_type) (const unsigned char *, int);
 typedef LONGEST (*get_trace_state_variable_value_ptr_type) (int);
 typedef void (*set_trace_state_variable_value_ptr_type) (int, LONGEST);
+typedef void (*tracepoint_bkpt_ptr_type) (void);
 
 EXTERN_C_PUSH
 IP_AGENT_EXPORT_VAR gdb_collect_ptr_type gdb_collect_ptr = gdb_collect;
@@ -5788,6 +5826,11 @@ IP_AGENT_EXPORT_VAR get_trace_state_variable_value_ptr_type
   get_trace_state_variable_value_ptr = get_trace_state_variable_value;
 IP_AGENT_EXPORT_VAR set_trace_state_variable_value_ptr_type
   set_trace_state_variable_value_ptr = set_trace_state_variable_value;
+IP_AGENT_EXPORT_VAR tracepoint_bkpt_ptr_type stop_tracing_ptr = stop_tracing;
+IP_AGENT_EXPORT_VAR tracepoint_bkpt_ptr_type
+  flush_trace_buffer_ptr = flush_trace_buffer;
+IP_AGENT_EXPORT_VAR tracepoint_bkpt_ptr_type
+  about_to_request_buffer_space_ptr = about_to_request_buffer_space;
 EXTERN_C_POP
 
 #endif
@@ -6238,6 +6281,7 @@ upload_fast_traceframes (void)
   struct breakpoint *about_to_request_buffer_space_bkpt;
   CORE_ADDR ipa_trace_buffer_lo;
   CORE_ADDR ipa_trace_buffer_hi;
+  CORE_ADDR addr_about_to_request_buffer_space;
 
   if (read_inferior_uinteger (ipa_sym_addrs.addr_traceframe_read_count,
 			      &ipa_traceframe_read_count_racy))
@@ -6260,9 +6304,17 @@ upload_fast_traceframes (void)
   if (ipa_traceframe_write_count_racy == ipa_traceframe_read_count_racy)
     return;
 
+  if (read_inferior_data_pointer
+      (ipa_sym_addrs.addr_about_to_request_buffer_space_ptr,
+       &addr_about_to_request_buffer_space))
+    {
+      internal_error (__FILE__, __LINE__,
+		      "Error reading  variable"
+		      "addr_about_to_request_buffer_space_ptr inn lib");
+    }
+
   about_to_request_buffer_space_bkpt
-    = set_breakpoint_at (ipa_sym_addrs.addr_about_to_request_buffer_space,
-			 NULL);
+    = set_breakpoint_at (addr_about_to_request_buffer_space, NULL);
 
   if (read_inferior_uinteger (ipa_sym_addrs.addr_trace_buffer_ctrl_curr,
 			      &ipa_trace_buffer_ctrl_curr))
diff --git a/gdb/testsuite/gdb.trace/ftrace-flush-buffer.c b/gdb/testsuite/gdb.trace/ftrace-flush-buffer.c
new file mode 100644
index 0000000..c115f00
--- /dev/null
+++ b/gdb/testsuite/gdb.trace/ftrace-flush-buffer.c
@@ -0,0 +1,42 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2011-2016 Free Software Foundation, Inc.
+
+   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 "trace-common.h"
+
+static void
+begin (void)
+{}
+
+static void
+end (void)
+{}
+
+int
+main ()
+{
+  int i = 0;
+  int table[1048576];
+
+  begin ();
+  for (i; i < 10; i++)
+    {
+      FAST_TRACEPOINT_LABEL(set_point);
+    }
+
+  end ();
+  return 0;
+}
diff --git a/gdb/testsuite/gdb.trace/ftrace-flush-buffer.exp b/gdb/testsuite/gdb.trace/ftrace-flush-buffer.exp
new file mode 100644
index 0000000..08fa26a
--- /dev/null
+++ b/gdb/testsuite/gdb.trace/ftrace-flush-buffer.exp
@@ -0,0 +1,98 @@
+# Copyright 2011-2016 Free Software Foundation, Inc.
+# 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/>.
+
+# The IPA flushes its internal buffer to GDBServer as it reaches 5MB
+# (hardcoded).  This test checks that this does not crash the inferiror by
+# collecting 10MB of data.
+
+load_lib "trace-support.exp"
+
+standard_testfile
+set executable $testfile
+set expfile $testfile.exp
+
+# Some targets have leading underscores on assembly symbols.
+set additional_flags [gdb_target_symbol_prefix_flags]
+
+if [prepare_for_testing $expfile $executable $srcfile \
+	[list debug $additional_flags]] {
+    untested "failed to prepare for trace tests"
+    return -1
+}
+
+if ![runto_main] {
+    fail "Can't run to main to check for trace support"
+    return -1
+}
+
+if ![gdb_target_supports_trace] {
+    unsupported "target does not support trace"
+    return -1
+}
+
+if {![gdb_target_supports_fast_trace]} {
+    unsupported "Target does not support fast tracepoints."
+    return -1
+}
+
+set libipa [get_in_proc_agent]
+set remote_libipa [gdb_load_shlib $libipa]
+
+# Can't use prepare_for_testing, because that splits compiling into
+# building objects and then linking, and we'd fail with "linker input
+# file unused because linking not done" when building the object.
+
+if { [gdb_compile "$srcdir/$subdir/$srcfile" $binfile \
+	  executable [list debug $additional_flags shlib=$libipa] ] != "" } {
+    untested "failed to compile ftrace tests"
+    return -1
+}
+clean_restart ${executable}
+
+if ![runto_main] {
+    fail "Can't run to main for ftrace tests"
+    return 0
+}
+
+gdb_reinitialize_dir $srcdir/$subdir
+
+if { [gdb_test "info sharedlibrary" ".*${remote_libipa}.*" "IPA loaded"] != 0 } {
+    untested "Could not find IPA lib loaded"
+    return 1
+}
+
+gdb_test "break begin" ".*" ""
+
+gdb_test "break end" ".*" ""
+
+gdb_test "ftrace set_point" "Fast tracepoint .*" \
+    "fast tracepoint at set_point"
+
+gdb_trace_setactions "collect at set_point: define actions" \
+    "" \
+    "collect table" "^$"
+
+gdb_test "continue" \
+    ".*Breakpoint \[0-9\]+, begin .*" \
+    "advance to trace begin"
+
+gdb_test_no_output "tstart" "start trace experiment"
+
+gdb_test "continue" \
+    ".*Breakpoint \[0-9\]+, end .*" \
+    "advance through tracing"
+
+gdb_test "tstatus" ".*Trace .*" "check on trace status"
+
+gdb_test "tstop" "" ""
-- 
2.8.1

  parent reply	other threads:[~2016-07-05 13:41 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-07-05 13:41 [PATCH v3 00/18] Fast tracepoint support for ARMv7 Antoine Tremblay
2016-07-05 13:41 ` [PATCH v3 11/18] Use software single step to step out of a fast tracepoint jump pad Antoine Tremblay
2016-07-05 13:41 ` Antoine Tremblay [this message]
2016-07-05 13:41 ` [PATCH v3 16/18] arm: Move insn_references_pc to common code Antoine Tremblay
2016-07-05 13:41 ` [PATCH v3 02/18] arm-tdep.c: Refactor displaced stepping relocation functions Antoine Tremblay
2016-07-05 13:41 ` [PATCH v3 08/18] Move Thumb 32 bits instruction decode functions to arch/arm-insn-reloc.c Antoine Tremblay
2016-07-05 13:41 ` [PATCH v3 06/18] arm-tdep.c: Use relocation visitor in Thumb 16-bits instruction decoding Antoine Tremblay
2016-07-05 13:41 ` [PATCH v3 12/18] Add ARM/Thumb instruction assembler for fast tracepoints Antoine Tremblay
2016-07-05 13:41 ` [PATCH v3 03/18] arm-tdep.c: Move debug printout from decode to copy function Antoine Tremblay
2016-07-05 13:41 ` [PATCH v3 15/18] JIT conditions support for ARM tracepoints Antoine Tremblay
2016-07-05 13:42 ` [PATCH v3 17/18] arm fast tracepoints: Relocation of ARM instructions Antoine Tremblay
2016-07-05 13:42 ` [PATCH v3 07/18] Move ARM instruction decode functions to arch/arm-insn-reloc.c Antoine Tremblay
2016-07-05 13:42 ` [PATCH v3 18/18] arm fast tracepoints: Relocation of Thumb 32-bits instructions Antoine Tremblay
2016-07-05 13:42 ` [PATCH v3 09/18] Move Thumb 16 bits instruction decode functions to arch/arm-insn-reloc.c Antoine Tremblay
2016-07-05 13:42 ` [PATCH v3 01/18] arm-tdep.c: Replace arguments to decode function by a structure Antoine Tremblay
2016-07-05 13:42 ` [PATCH v3 10/18] gdbserver: pass pointer to struct tracepoint to install_fast_tracepoint_jump_pad Antoine Tremblay
2016-07-05 13:42 ` [PATCH v3 14/18] Fast tracepoint support for ARM on Linux Antoine Tremblay
2016-07-05 13:56 ` [PATCH v3 04/18] arm-tdep.c: Use relocation visitor in ARM instruction decoding Antoine Tremblay
2016-07-05 13:56 ` [PATCH v3 05/18] arm-tdep.c: Use relocation visitor in Thumb 32-bits " Antoine Tremblay

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1467726030-13020-14-git-send-email-antoine.tremblay@ericsson.com \
    --to=antoine.tremblay@ericsson.com \
    --cc=gdb-patches@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).