From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga06.intel.com (mga06.intel.com [134.134.136.31]) by sourceware.org (Postfix) with ESMTPS id 20804388E839 for ; Mon, 25 May 2020 09:39:14 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 20804388E839 IronPort-SDR: /J/5fYvIU5/1GMgErsFjKS6isneqBheBzZGjluvRG4KbxwtywPeC+xdXhvj6yXp695KT9P5BVs 1XekT46gg44w== X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga006.fm.intel.com ([10.253.24.20]) by orsmga104.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 25 May 2020 02:39:13 -0700 IronPort-SDR: wOemn1TRAvc5f1YVjkuswZ5e4slNU5EbNCShLH5eMdU3JSDThm0evAJ8rhb8LjCfP9j2Nq0wEH UDt38hOmpaIw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.73,433,1583222400"; d="scan'208";a="468005588" Received: from irvmail001.ir.intel.com ([163.33.26.43]) by fmsmga006.fm.intel.com with ESMTP; 25 May 2020 02:39:13 -0700 Received: from ulvlx001.iul.intel.com (ulvlx001.iul.intel.com [172.28.207.17]) by irvmail001.ir.intel.com (8.14.3/8.13.6/MailSET/Hub) with ESMTP id 04P9dCD6026888; Mon, 25 May 2020 10:39:12 +0100 Received: from ulvlx001.iul.intel.com (localhost [127.0.0.1]) by ulvlx001.iul.intel.com with ESMTP id 04P9dC1v001375; Mon, 25 May 2020 11:39:12 +0200 Received: (from taktemur@localhost) by ulvlx001.iul.intel.com with LOCAL id 04P9dCui001371; Mon, 25 May 2020 11:39:12 +0200 From: Tankut Baris Aktemur 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 Message-Id: <886ee7b960b7da9ee20ae3c4b889d2b9c3246b33.1590397723.git.tankut.baris.aktemur@intel.com> X-Mailer: git-send-email 1.7.0.7 In-Reply-To: References: In-Reply-To: References: X-Spam-Status: No, score=-24.0 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_NONE, KAM_DMARC_STATUS, KAM_LAZY_DOMAIN_SECURITY, KAM_STOCKGEN, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 25 May 2020 09:39:17 -0000 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 * 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 * 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