public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
From: Tankut Baris Aktemur <tankut.baris.aktemur@intel.com>
To: gdb-patches@sourceware.org
Subject: [PATCH 2/3] gdb/jit: enable tracking multiple jitter objfiles
Date: Mon, 25 May 2020 11:38:46 +0200	[thread overview]
Message-ID: <886ee7b960b7da9ee20ae3c4b889d2b9c3246b33.1590397723.git.tankut.baris.aktemur@intel.com> (raw)
In-Reply-To: <cover.1590397723.git.tankut.baris.aktemur@intel.com>
In-Reply-To: <cover.1590397723.git.tankut.baris.aktemur@intel.com>

Keep track of multiple JITer objfiles and their JIT breakpoints.

This patch is viewed better with 'git diff -w'.

Regression-tested on X86_64 Linux.

gdb/ChangeLog:
2020-05-25  Tankut Baris Aktemur  <tankut.baris.aktemur@intel.com>

	* jit.c (jit_breakpoint_re_set_internal): Iterate over all objfiles
	in the program space to look for JIT symbols.
	(jit_inferior_init): Iterate over all objfiles with JIT breakpoints.
	(jit_event_handler): Ditto.

gdb/testsuite/ChangeLog:
2020-05-25  Tankut Baris Aktemur  <tankut.baris.aktemur@intel.com>

	* gdb.base/jit-reader-simple.exp: Add a scenario for a binary that
	loads two JITers.
---
 gdb/jit.c                                    | 171 +++++++++----------
 gdb/testsuite/gdb.base/jit-reader-simple.exp |  43 ++++-
 2 files changed, 125 insertions(+), 89 deletions(-)

diff --git a/gdb/jit.c b/gdb/jit.c
index fdb1248ed5b..c689ac3f392 100644
--- a/gdb/jit.c
+++ b/gdb/jit.c
@@ -966,58 +966,53 @@ jit_breakpoint_re_set_internal (struct gdbarch *gdbarch,
   struct jit_objfile_data *objf_data;
   CORE_ADDR addr;
 
-  objfile *the_objfile = nullptr;
-  if (!ps_data->objfile_and_bps.empty ())
-    the_objfile = ps_data->objfile_and_bps.begin ()->first;
-
-  if (the_objfile == nullptr)
+  for (objfile *the_objfile : current_program_space->objfiles ())
     {
       /* Lookup the registration symbol.  If it is missing, then we
 	 assume we are not attached to a JIT.  */
-      reg_symbol = lookup_bound_minimal_symbol (jit_break_name);
+      reg_symbol = lookup_minimal_symbol (jit_break_name, nullptr,
+					  the_objfile);
       if (reg_symbol.minsym == NULL
 	  || BMSYMBOL_VALUE_ADDRESS (reg_symbol) == 0)
-	return 1;
+	continue;
 
       desc_symbol = lookup_minimal_symbol (jit_descriptor_name, NULL,
 					   reg_symbol.objfile);
       if (desc_symbol.minsym == NULL
 	  || BMSYMBOL_VALUE_ADDRESS (desc_symbol) == 0)
-	return 1;
+	continue;
 
       objf_data = get_jit_objfile_data (reg_symbol.objfile);
       objf_data->register_code = reg_symbol.minsym;
       objf_data->descriptor = desc_symbol.minsym;
 
       the_objfile = reg_symbol.objfile;
-    }
-  else
-    objf_data = get_jit_objfile_data (the_objfile);
 
-  addr = MSYMBOL_VALUE_ADDRESS (the_objfile, objf_data->register_code);
+      addr = MSYMBOL_VALUE_ADDRESS (the_objfile, objf_data->register_code);
 
-  if (jit_debug)
-    fprintf_unfiltered (gdb_stdlog,
-			"jit_breakpoint_re_set_internal, "
-			"breakpoint_addr = %s\n",
-			paddress (gdbarch, addr));
+      if (jit_debug)
+	fprintf_unfiltered (gdb_stdlog,
+			    "jit_breakpoint_re_set_internal, "
+			    "breakpoint_addr = %s\n",
+			    paddress (gdbarch, addr));
 
-  /* Note that this will insert a fresh value if THE_OBJFILE does not
-     exist as a key.  */
-  jit_objfile_bp &info = ps_data->objfile_and_bps[the_objfile];
+      /* Note that this will insert a fresh value if THE_OBJFILE does not
+	 exist as a key.  */
+      jit_objfile_bp &info = ps_data->objfile_and_bps[the_objfile];
 
-  if (info.cached_code_address == addr)
-    return 0;
+      if (info.cached_code_address == addr)
+	continue;
 
-  /* Delete the old breakpoint.  */
-  if (info.jit_breakpoint != nullptr)
-    delete_breakpoint (info.jit_breakpoint);
+      /* Delete the old breakpoint.  */
+      if (info.jit_breakpoint != nullptr)
+	delete_breakpoint (info.jit_breakpoint);
 
-  /* Put a breakpoint in the registration symbol.  */
-  info.cached_code_address = addr;
-  info.jit_breakpoint = create_jit_event_breakpoint (gdbarch, addr);
+      /* Put a breakpoint in the registration symbol.  */
+      info.cached_code_address = addr;
+      info.jit_breakpoint = create_jit_event_breakpoint (gdbarch, addr);
+    }
 
-  return 0;
+  return (ps_data->objfile_and_bps.empty ()) ? 1 : 0;
 }
 
 /* The private data passed around in the frame unwind callback
@@ -1268,40 +1263,40 @@ jit_inferior_init (struct gdbarch *gdbarch)
   if (jit_breakpoint_re_set_internal (gdbarch, ps_data) != 0)
     return;
 
-  /* Fetch the saved objfile.  */
-  objfile *objf = nullptr;
-  if (!ps_data->objfile_and_bps.empty ())
-    objf = (ps_data->objfile_and_bps.begin ())->first;
+  for (auto &objf_and_bp : ps_data->objfile_and_bps)
+    {
+      objfile *objf = objf_and_bp.first;
 
-  /* Read the descriptor so we can check the version number and load
-     any already JITed functions.  */
-  if (!jit_read_descriptor (gdbarch, &descriptor, objf))
-    return;
+      /* Read the descriptor so we can check the version number and load
+	 any already JITed functions.  */
+      if (!jit_read_descriptor (gdbarch, &descriptor, objf))
+	continue;
 
-  /* Check that the version number agrees with that we support.  */
-  if (descriptor.version != 1)
-    {
-      printf_unfiltered (_("Unsupported JIT protocol version %ld "
-			   "in descriptor (expected 1)\n"),
-			 (long) descriptor.version);
-      return;
-    }
+      /* Check that the version number agrees with that we support.  */
+      if (descriptor.version != 1)
+	{
+	  printf_unfiltered (_("Unsupported JIT protocol version %ld "
+			       "in descriptor (expected 1)\n"),
+			     (long) descriptor.version);
+	  continue;
+	}
 
-  /* If we've attached to a running program, we need to check the
-     descriptor to register any functions that were already
-     generated.  */
-  for (cur_entry_addr = descriptor.first_entry;
-       cur_entry_addr != 0;
-       cur_entry_addr = cur_entry.next_entry)
-    {
-      jit_read_code_entry (gdbarch, cur_entry_addr, &cur_entry);
+      /* If we've attached to a running program, we need to check the
+	 descriptor to register any functions that were already
+	 generated.  */
+      for (cur_entry_addr = descriptor.first_entry;
+	   cur_entry_addr != 0;
+	   cur_entry_addr = cur_entry.next_entry)
+	{
+	  jit_read_code_entry (gdbarch, cur_entry_addr, &cur_entry);
 
-      /* This hook may be called many times during setup, so make sure
-	 we don't add the same symbol file twice.  */
-      if (jit_find_objf_with_entry_addr (cur_entry_addr) != NULL)
-	continue;
+	  /* This hook may be called many times during setup, so make sure
+	     we don't add the same symbol file twice.  */
+	  if (jit_find_objf_with_entry_addr (cur_entry_addr) != NULL)
+	    continue;
 
-      jit_register_code (gdbarch, cur_entry_addr, &cur_entry);
+	  jit_register_code (gdbarch, cur_entry_addr, &cur_entry);
+	}
     }
 }
 
@@ -1357,38 +1352,38 @@ jit_event_handler (struct gdbarch *gdbarch)
 
   jit_program_space_data *ps_data = get_jit_program_space_data ();
 
-  /* Fetch the saved objfile.  */
-  objfile *objf = nullptr;
-  if (!ps_data->objfile_and_bps.empty ())
-    objf = (ps_data->objfile_and_bps.begin ())->first;
-
-  /* Read the descriptor from remote memory.  */
-  if (!jit_read_descriptor (gdbarch, &descriptor, objf))
-    return;
-  entry_addr = descriptor.relevant_entry;
-
-  /* Do the corresponding action.  */
-  switch (descriptor.action_flag)
+  for (auto &objf_and_bp : ps_data->objfile_and_bps)
     {
-    case JIT_NOACTION:
-      break;
-    case JIT_REGISTER:
-      jit_read_code_entry (gdbarch, entry_addr, &code_entry);
-      jit_register_code (gdbarch, entry_addr, &code_entry);
-      break;
-    case JIT_UNREGISTER:
-      objf = jit_find_objf_with_entry_addr (entry_addr);
-      if (objf == NULL)
-	printf_unfiltered (_("Unable to find JITed code "
-			     "entry at address: %s\n"),
-			   paddress (gdbarch, entry_addr));
-      else
-	objf->unlink ();
+      objfile *objf = objf_and_bp.first;
 
-      break;
-    default:
-      error (_("Unknown action_flag value in JIT descriptor!"));
-      break;
+      /* Read the descriptor from remote memory.  */
+      if (!jit_read_descriptor (gdbarch, &descriptor, objf))
+	continue;
+      entry_addr = descriptor.relevant_entry;
+
+      /* Do the corresponding action.  */
+      switch (descriptor.action_flag)
+	{
+	case JIT_NOACTION:
+	  break;
+	case JIT_REGISTER:
+	  jit_read_code_entry (gdbarch, entry_addr, &code_entry);
+	  jit_register_code (gdbarch, entry_addr, &code_entry);
+	  break;
+	case JIT_UNREGISTER:
+	  objf = jit_find_objf_with_entry_addr (entry_addr);
+	  if (objf == NULL)
+	    printf_unfiltered (_("Unable to find JITed code "
+				 "entry at address: %s\n"),
+			       paddress (gdbarch, entry_addr));
+	  else
+	    objf->unlink ();
+
+	  break;
+	default:
+	  error (_("Unknown action_flag value in JIT descriptor!"));
+	  break;
+	}
     }
 }
 
diff --git a/gdb/testsuite/gdb.base/jit-reader-simple.exp b/gdb/testsuite/gdb.base/jit-reader-simple.exp
index c036e71c3fb..930c59c0124 100644
--- a/gdb/testsuite/gdb.base/jit-reader-simple.exp
+++ b/gdb/testsuite/gdb.base/jit-reader-simple.exp
@@ -34,6 +34,7 @@ standard_testfile
 set libname $testfile-jit
 set srcfile_lib $srcdir/$subdir/$libname.c
 set binfile_lib [standard_output_file $libname.so]
+set binfile_lib2 [standard_output_file ${libname}2.so]
 
 # Build a standalone JIT binary.
 
@@ -53,12 +54,15 @@ proc build_standalone_jit {{options ""}} {
 
 proc build_shared_jit {{options ""}} {
     global testfile
-    global srcfile_lib binfile_lib
+    global srcfile_lib binfile_lib binfile_lib2
 
     lappend options "debug additional_flags=-fPIC"
     if { [gdb_compile_shlib $srcfile_lib $binfile_lib $options] != "" } {
 	return -1
     }
+    if { [gdb_compile_shlib $srcfile_lib $binfile_lib2 $options] != "" } {
+	return -1
+    }
 
     return 0
 }
@@ -83,6 +87,15 @@ if {[gdb_compile ${srcdir}/${subdir}/${srcfile_dl} $binfile_dl executable \
     return -1
 }
 
+# Build the program that loads *two* JIT libraries.
+set binfile_dl2 $binfile-dl2
+set options [list debug shlib=${binfile_lib} shlib=${binfile_lib2}]
+if {[gdb_compile ${srcdir}/${subdir}/${srcfile_dl} $binfile_dl2 executable \
+	 $options] == -1 } {
+    untested "failed to compile two-jitter binary"
+    return -1
+}
+
 # STANDALONE is true when the JIT reader is included directly in the
 # main program.  False when the JIT reader is in a separate shared
 # library.  If CHANGE_ADDR is true, force changing the JIT descriptor
@@ -160,3 +173,31 @@ foreach standalone {1 0} {
 	}
     }
 }
+
+# Now start the program that loads two JITer libraries and expect to
+# see JIT breakpoints defined for both.
+
+with_test_prefix "two JITers" {
+    clean_restart $binfile_dl2
+
+    if {![runto_main]} {
+	untested "could not run to main for the two-JITer test"
+	return -1
+    }
+
+    set num_bps 0
+    set ws "\[ \t\]+"
+    gdb_test_multiple "maint info breakpoints" "have two jit breakpoints" {
+	-re "jit events${ws}keep y${ws}$hex <__jit_debug_register_code> inf 1\r\n" {
+	    incr num_bps
+	    exp_continue
+	}
+	-re "$gdb_prompt $" {
+	    if {$num_bps == 2} {
+		pass $gdb_test_name
+	    } else {
+		fail $gdb_test_name
+	    }
+	}
+    }
+}
-- 
2.17.1


  parent reply	other threads:[~2020-05-25  9:39 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-05-25  9:38 [PATCH 0/3] Handling multiple JITers Tankut Baris Aktemur
2020-05-25  9:38 ` [PATCH 1/3] gdb/jit: use a map to store objfile and jit breakpoint info Tankut Baris Aktemur
2020-06-14 17:50   ` Simon Marchi
2020-06-16  9:47     ` Aktemur, Tankut Baris
2020-05-25  9:38 ` Tankut Baris Aktemur [this message]
2020-06-14 17:09   ` [PATCH 2/3] gdb/jit: enable tracking multiple jitter objfiles Simon Marchi
2020-06-16  9:48     ` Aktemur, Tankut Baris
2020-05-25  9:38 ` [PATCH 3/3] gdb/testsuite: fix minor things in jit tests Tankut Baris Aktemur
2020-06-14 18:09   ` Simon Marchi
2020-06-15  7:15     ` Aktemur, Tankut Baris
2020-06-12 11:12 ` [PATCH 0/3] Handling multiple JITers Aktemur, Tankut Baris

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=886ee7b960b7da9ee20ae3c4b889d2b9c3246b33.1590397723.git.tankut.baris.aktemur@intel.com \
    --to=tankut.baris.aktemur@intel.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).