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
next prev 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).