Fix dlopen of libpthread.so, patched glibc required (Gary Benson, BZ 669432).

This commit is contained in:
Jan Kratochvil 2011-08-10 19:42:06 +02:00
parent b9aa4c4c7b
commit 922e4a0796
3 changed files with 776 additions and 1 deletions

View File

@ -0,0 +1,408 @@
commit 5bfdc32cd3bf373c3b02e1fd864ed8ceab0292b2
Author: Jan Kratochvil <jan.kratochvil@redhat.com>
Date: Mon Aug 8 12:08:53 2011 +0200
+testcase
Index: gdb-7.3.50.20110722/gdb/testsuite/gdb.threads/dlopen-libpthread-lib.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ gdb-7.3.50.20110722/gdb/testsuite/gdb.threads/dlopen-libpthread-lib.c 2011-08-10 18:30:56.000000000 +0200
@@ -0,0 +1,40 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2011 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 <pthread.h>
+#include <assert.h>
+
+static void *
+tfunc (void *arg)
+{
+ void (*notifyp) (void) = arg;
+
+ notifyp ();
+}
+
+void
+f (void (*notifyp) (void))
+{
+ pthread_t t;
+ int i;
+
+ i = pthread_create (&t, NULL, tfunc, notifyp);
+ assert (i == 0);
+
+ i = pthread_join (t, NULL);
+ assert (i == 0);
+}
Index: gdb-7.3.50.20110722/gdb/testsuite/gdb.threads/dlopen-libpthread.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ gdb-7.3.50.20110722/gdb/testsuite/gdb.threads/dlopen-libpthread.c 2011-08-10 18:30:56.000000000 +0200
@@ -0,0 +1,46 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2011 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 <dlfcn.h>
+#include <stddef.h>
+#include <assert.h>
+
+static const char *volatile filename;
+
+static void
+notify (void)
+{
+ filename = NULL; /* notify-here */
+}
+
+int
+main (void)
+{
+ void *h;
+ void (*fp) (void (*) (void));
+
+ assert (filename != NULL);
+ h = dlopen (filename, RTLD_LAZY);
+ assert (h != NULL);
+
+ fp = dlsym (h, "f");
+ assert (fp != NULL);
+
+ fp (notify);
+
+ return 0;
+}
Index: gdb-7.3.50.20110722/gdb/testsuite/gdb.threads/dlopen-libpthread.exp
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ gdb-7.3.50.20110722/gdb/testsuite/gdb.threads/dlopen-libpthread.exp 2011-08-10 18:30:56.000000000 +0200
@@ -0,0 +1,74 @@
+# Copyright 2011 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/>.
+
+if {![istarget *-linux*] || [skip_shlib_tests]} {
+ return 0
+}
+
+load_lib prelink-support.exp
+
+set testfile "dlopen-libpthread"
+set srcmainfile ${testfile}.c
+set srclibfile ${testfile}-lib.c
+set executable ${testfile}
+set binfile_lib ${objdir}/${subdir}/${executable}.so
+set binfile ${objdir}/${subdir}/${executable}
+set lib_dlopen [shlib_target_file ${executable}.so]
+
+# Use build_executable_own_libs as prelinked libpthread.so can produce false
+# PASS - it is OK if GDB processes it still before relocation.
+
+set relink_args [build_executable_own_libs ${testfile}.exp ${executable}.so $srclibfile {debug shlib_pthreads} no]
+if {$relink_args == "" || ![prelink_no $relink_args]
+ || [prepare_for_testing ${testfile}.exp ${executable} ${srcmainfile} {debug shlib_load}] } {
+ return -1
+}
+gdb_load_shlibs $binfile_lib
+
+if { ![runto_main] } {
+ return -1
+}
+
+set test "print _dl_debug_notify"
+gdb_test_multiple $test $test {
+ -re " 0x\[0-9a-f\]+ <_dl_debug_notify>\r\n$gdb_prompt $" {
+ pass $test
+ }
+ -re "No symbol \"_dl_debug_notify\" in current context\\.\r\n$gdb_prompt $" {
+ xfail $test
+ untested ${testfile}.exp
+ return
+ }
+}
+
+set test "libpthread.so not found"
+gdb_test_multiple "info sharedlibrary" $test {
+ -re "/libpthread\\.so.*\r\n$gdb_prompt $" {
+ fail $test
+ }
+ -re "/libc\\.so.*\r\n$gdb_prompt $" {
+ pass $test
+ }
+}
+
+gdb_test "set variable filename=\"$lib_dlopen\""
+
+gdb_breakpoint "notify"
+
+# The error was:
+# Cannot find new threads: generic error
+gdb_continue_to_breakpoint "notify" ".* notify-here .*"
+
+gdb_test "info sharedlibrary" {/libpthread\.so.*} "libpthread.so found"
Index: gdb-7.3.50.20110722/gdb/testsuite/lib/gdb.exp
===================================================================
--- gdb-7.3.50.20110722.orig/gdb/testsuite/lib/gdb.exp 2011-08-10 18:30:55.000000000 +0200
+++ gdb-7.3.50.20110722/gdb/testsuite/lib/gdb.exp 2011-08-10 18:30:56.000000000 +0200
@@ -3563,30 +3563,49 @@ proc build_executable { testname executa
set sources ${executable}.c
}
- set binfile ${objdir}/${subdir}/${executable}
-
- set objects {}
- for {set i 0} "\$i<[llength $sources]" {incr i} {
- set s [lindex $sources $i]
- if { [gdb_compile "${srcdir}/${subdir}/${s}" "${binfile}${i}.o" object $options] != "" } {
- untested $testname
- return -1
- }
- lappend objects "${binfile}${i}.o"
+ # get_compiler_info by gdb_compile_shlib and gdb_compile_shlib_pthreads.
+ set info_options ""
+ if { [lsearch -exact $options "c++"] >= 0 } {
+ set info_options "c++"
}
-
- if { [gdb_compile $objects "${binfile}" executable $options] != "" } {
- untested $testname
+ if [get_compiler_info binfile_unused ${info_options}] {
return -1
}
- set info_options ""
- if { [lsearch -exact $options "c++"] >= 0 } {
- set info_options "c++"
+ set binfile ${objdir}/${subdir}/${executable}
+
+ set func gdb_compile
+ set func_index [lsearch -regexp $options {^(pthreads|shlib|shlib_pthreads)$}]
+ if {$func_index != -1} {
+ set func "${func}_[lindex $options $func_index]"
}
- if [get_compiler_info ${binfile} ${info_options}] {
+
+ # gdb_compile_shlib and gdb_compile_shlib_pthreads do not use the 3rd
+ # parameter. They also requires $sources while gdb_compile and
+ # gdb_compile_pthreads require $objects.
+ if [string match gdb_compile_shlib* $func] {
+ set sources_path {}
+ foreach s $sources {
+ lappend sources_path "${srcdir}/${subdir}/${s}"
+ }
+ set ret [$func $sources_path "${binfile}" $options]
+ } else {
+ set objects {}
+ for {set i 0} "\$i<[llength $sources]" {incr i} {
+ set s [lindex $sources $i]
+ if { [gdb_compile "${srcdir}/${subdir}/${s}" "${binfile}${i}.o" object $options] != "" } {
+ untested $testname
+ return -1
+ }
+ lappend objects "${binfile}${i}.o"
+ }
+ set ret [$func $objects "${binfile}" executable $options]
+ }
+ if { $ret != "" } {
+ untested $testname
return -1
}
+
return 0
}
Index: gdb-7.3.50.20110722/gdb/testsuite/lib/prelink-support.exp
===================================================================
--- gdb-7.3.50.20110722.orig/gdb/testsuite/lib/prelink-support.exp 2011-01-01 16:33:52.000000000 +0100
+++ gdb-7.3.50.20110722/gdb/testsuite/lib/prelink-support.exp 2011-08-10 19:25:41.000000000 +0200
@@ -95,8 +95,9 @@ proc file_copy {src dest} {
# Wrap function build_executable so that the resulting executable is fully
# self-sufficient (without dependencies on system libraries). Parameter
# INTERP may be used to specify a loader (ld.so) to be used that is
-# different from the default system one. Libraries on which the executable
-# depends are copied into directory DIR. Default DIR value to
+# different from the default system one. INTERP can be set to "no" if no ld.so
+# copy should be made. Libraries on which the executable depends are copied
+# into directory DIR. Default DIR value to
# `${objdir}/${subdir}/${EXECUTABLE}.d'.
#
# In case of success, return a string containing the arguments to be used
@@ -151,8 +152,15 @@ proc build_executable_own_libs {testname
if {$interp == ""} {
set interp_system [section_get $binfile .interp]
- set interp ${dir}/[file tail $interp_system]
- file_copy $interp_system $interp
+ if {$interp_system == ""} {
+ fail "$test could not find .interp"
+ } else {
+ set interp ${dir}/[file tail $interp_system]
+ file_copy $interp_system $interp
+ }
+ }
+ if {$interp == "no"} {
+ set interp ""
}
set dests {}
@@ -164,13 +172,19 @@ proc build_executable_own_libs {testname
# Do not lappend it so that "-rpath $dir" overrides any possible "-rpath"s
# specified by the caller to be able to link it for ldd" above.
- set options [linsert $options 0 "ldflags=-Wl,--dynamic-linker,$interp,-rpath,$dir"]
+ set options [linsert $options 0 "ldflags=-Wl,-rpath,$dir"]
+ if {$interp != ""} {
+ set options [linsert $options 0 "ldflags=-Wl,--dynamic-linker,$interp"]
+ }
if {[build_executable $testname $executable $sources $options] == -1} {
return ""
}
- set prelink_args "--dynamic-linker=$interp --ld-library-path=$dir $binfile $interp [concat $dests]"
+ set prelink_args "--ld-library-path=$dir $binfile [concat $dests]"
+ if {$interp != ""} {
+ set prelink_args "--dynamic-linker=$interp $prelink_args $interp"
+ }
return $prelink_args
}
Index: gdb-7.3.50.20110722/gdb/testsuite/gdb.base/break-interp.exp
===================================================================
--- gdb-7.3.50.20110722.orig/gdb/testsuite/gdb.base/break-interp.exp 2011-07-01 21:12:12.000000000 +0200
+++ gdb-7.3.50.20110722/gdb/testsuite/gdb.base/break-interp.exp 2011-08-10 18:32:21.000000000 +0200
@@ -108,14 +108,20 @@ proc strip_debug {dest} {
}
}
+# Former symbol for solib changes notifications was _dl_debug_state, newer one
+# is _dl_debug_notify, the right one one traps by `set stop-on-solib-events 1'.
+
+set solib_bp {(_dl_debug_state|_dl_debug_notify)}
+
# Implementation of reach.
proc reach_1 {func command displacement} {
- global gdb_prompt expect_out
+ global gdb_prompt expect_out solib_bp
- if {$func == "_dl_debug_state"} {
+ if {$func == $solib_bp} {
# Breakpoint on _dl_debug_state can have problems due to its overlap
# with the existing internal breakpoint from GDB.
+ # With also _dl_debug_notify we would need even two breakpoints.
gdb_test_no_output "set stop-on-solib-events 1"
} elseif {! [gdb_breakpoint $func allow-pending]} {
return
@@ -141,21 +147,21 @@ proc reach_1 {func command displacement}
exp_continue
}
-re "Breakpoint \[0-9\]+, \\.?(__GI_)?$func \\(.*\\) at .*:\[0-9\]+\r\n.*$gdb_prompt $" {
- if {$func == "_dl_debug_state"} {
+ if {$func == $solib_bp} {
fail $test
} else {
pass $test
}
}
-re "Breakpoint \[0-9\]+, \[0-9xa-f\]+ in \\.?(__GI_)?$func \\(\\).*\r\n$gdb_prompt $" {
- if {$func == "_dl_debug_state"} {
+ if {$func == $solib_bp} {
fail $test
} else {
pass $test
}
}
-re "Stopped due to shared library event\r\n$gdb_prompt $" {
- if {$func == "_dl_debug_state"} {
+ if {$func == $solib_bp} {
if {$debug_state_count == 0} {
# First stop does not yet relocate the _start function
# descriptor on ppc64.
@@ -174,7 +180,7 @@ proc reach_1 {func command displacement}
fail $test_displacement
}
- if {$func == "_dl_debug_state"} {
+ if {$func == $solib_bp} {
gdb_test_no_output "set stop-on-solib-events 0"
}
}
@@ -373,7 +379,7 @@ proc test_attach {file displacement {rel
}
proc test_ld {file ifmain trynosym displacement} {
- global srcdir subdir gdb_prompt expect_out inferior_exited_re
+ global srcdir subdir gdb_prompt expect_out inferior_exited_re solib_bp
# First test normal `file'-command loaded $FILE with symbols.
@@ -401,9 +407,9 @@ proc test_ld {file ifmain trynosym displ
gdb_test_no_output "set args ${objdir}/${subdir}/$binfile_test" "set args OBJDIR/${subdir}/$binfile_test"
}
- reach "_dl_debug_state" "run" $displacement
+ reach $solib_bp "run" $displacement
- gdb_test "bt" "#0 +\[^\r\n\]*\\m(__GI_)?_dl_debug_state\\M.*" "dl bt"
+ gdb_test "bt" "#0 +\[^\r\n\]*\\m(__GI_)?$solib_bp\\M.*" "dl bt"
if $ifmain {
reach "main" continue "NONE"
@@ -415,7 +421,7 @@ proc test_ld {file ifmain trynosym displ
# Try re-run if the new PIE displacement takes effect.
gdb_test "kill" "" "kill" {Kill the program being debugged\? \(y or n\) } "y"
- reach "_dl_debug_state" "run" $displacement
+ reach $solib_bp "run" $displacement
if $ifmain {
test_core $file $displacement
@@ -448,7 +454,7 @@ proc test_ld {file ifmain trynosym displ
gdb_test "exec-file $file" "exec-file $escapedfile" "load"
if $ifmain {
- reach "_dl_debug_state" run $displacement
+ reach $solib_bp run $displacement
# Use two separate gdb_test_multiple statements to avoid timeouts due
# to slow processing of wildcard capturing long output

358
gdb-dlopen-stap-probe.patch Normal file
View File

@ -0,0 +1,358 @@
From: Gary Benson <gbenson@redhat.com>
To: Jan Kratochvil <jan.kratochvil@redhat.com>
Message-ID: <20110810133605.GB7294@redhat.com>
diff --git a/gdb/infrun.c b/gdb/infrun.c
index 4296d3a..fd5e9c3 100644
--- a/gdb/infrun.c
+++ b/gdb/infrun.c
@@ -321,6 +323,13 @@ static struct symbol *step_start_function;
/* Nonzero if we want to give control to the user when we're notified
of shared library events by the dynamic linker. */
int stop_on_solib_events;
+
+static void
+set_stop_on_solib_events (char *args, int from_tty, struct cmd_list_element *c)
+{
+ update_solib_breakpoints ();
+}
+
static void
show_stop_on_solib_events (struct ui_file *file, int from_tty,
struct cmd_list_element *c, const char *value)
@@ -7153,7 +7162,7 @@ Show stopping for shared library events."), _("\
If nonzero, gdb will give control to the user when the dynamic linker\n\
notifies gdb of shared library events. The most common event of interest\n\
to the user would be loading/unloading of a new library."),
- NULL,
+ set_stop_on_solib_events,
show_stop_on_solib_events,
&setlist, &showlist);
diff --git a/gdb/solib-svr4.c b/gdb/solib-svr4.c
index dffc621..73cbe1c 100644
--- a/gdb/solib-svr4.c
+++ b/gdb/solib-svr4.c
@@ -48,6 +48,8 @@
#include "auxv.h"
#include "exceptions.h"
+#include "stap-probe.h"
+
static struct link_map_offsets *svr4_fetch_link_map_offsets (void);
static int svr4_have_link_map_offsets (void);
static void svr4_relocate_main_executable (void);
@@ -92,6 +94,32 @@ static const char * const solib_break_names[] =
NULL
};
+/* A list of SystemTap probes which, if present in the dynamic linker,
+ allow more fine-grained breakpoints to be placed on shared library
+ events. */
+
+struct probe_info
+ {
+ /* The name of the probe. */
+ const char *name;
+
+ /* Nonzero if this probe must be stopped at even when
+ stop-on-solib-events is off. */
+ int mandatory;
+ };
+
+static const struct probe_info probe_info[] =
+{
+ {"rtld_init_start", 0},
+ {"rtld_init_complete", 1},
+ {"rtld_map_start", 0},
+ {"rtld_reloc_complete", 1},
+ {"rtld_unmap_start", 0},
+ {"rtld_unmap_complete", 1},
+};
+
+#define NUM_PROBES (sizeof(probe_info) / sizeof(probe_info[0]))
+
static const char * const bkpt_names[] =
{
"_start",
@@ -335,6 +363,12 @@ struct svr4_info
CORE_ADDR interp_text_sect_high;
CORE_ADDR interp_plt_sect_low;
CORE_ADDR interp_plt_sect_high;
+
+ /* SystemTap probes. */
+ VEC (stap_probe_p) *probes[NUM_PROBES];
+
+ /* Nonzero if we are using the SystemTap interface. */
+ int using_probes;
};
/* Per-program-space data key. */
@@ -344,8 +378,15 @@ static void
svr4_pspace_data_cleanup (struct program_space *pspace, void *arg)
{
struct svr4_info *info;
+ int i;
info = program_space_data (pspace, solib_svr4_pspace_data);
+ if (info == NULL)
+ return;
+
+ for (i = 0; i < NUM_PROBES; i++)
+ VEC_free (stap_probe_p, info->probes[i]);
+
xfree (info);
}
@@ -1321,6 +1362,126 @@ exec_entry_point (struct bfd *abfd, struct target_ops *targ)
targ);
}
+/* Helper function for svr4_update_solib_event_breakpoints. */
+
+static int
+svr4_update_solib_event_breakpoint (struct breakpoint *b, void *arg)
+{
+ struct svr4_info *info = get_svr4_info ();
+ struct bp_location *loc;
+
+ if (b->type != bp_shlib_event)
+ return 0;
+
+ for (loc = b->loc; loc; loc = loc->next)
+ {
+ int i;
+
+ for (i = 0; i < NUM_PROBES; i++)
+ {
+ if (!probe_info[i].mandatory)
+ {
+ const struct stap_probe *probe;
+ int ix;
+
+ for (ix = 0;
+ VEC_iterate (stap_probe_p, info->probes[i], ix, probe);
+ ++ix)
+ {
+ if (loc->pspace == current_program_space
+ && loc->address == probe->address)
+ {
+ b->enable_state =
+ stop_on_solib_events ? bp_enabled : bp_disabled;
+ return 0;
+ }
+ }
+ }
+ }
+ }
+
+ return 0;
+}
+
+/* Enable or disable optional solib event breakpoints as appropriate.
+ Called whenever stop_on_solib_events is changed. */
+
+static void
+svr4_update_solib_event_breakpoints (void)
+{
+ struct svr4_info *info = get_svr4_info ();
+
+ if (info->using_probes)
+ iterate_over_breakpoints (svr4_update_solib_event_breakpoint, NULL);
+}
+
+/* Both the SunOS and the SVR4 dynamic linkers call a marker function
+ before and after mapping and unmapping shared libraries. The sole
+ purpose of this method is to allow debuggers to set a breakpoint so
+ they can track these changes.
+
+ Some versions of the glibc dynamic linker contain SystemTap probes
+ to allow more fine grained stopping. Given the address of the
+ original marker function, this function attempts to find these
+ probes, and if found, sets breakpoints on those instead. If the
+ probes aren't found, a single breakpoint is set on the original
+ SVR4 marker function. */
+
+static void
+svr4_create_solib_event_breakpoints (struct gdbarch *gdbarch, CORE_ADDR address)
+{
+ struct svr4_info *info = get_svr4_info ();
+ struct obj_section *os;
+
+ os = find_pc_section (address);
+ if (os != NULL)
+ {
+ int all_probes_found = 1;
+ int i;
+
+ for (i = 0; i < NUM_PROBES; i++)
+ {
+ info->probes[i] = find_probes_in_objfile (os->objfile, "rtld",
+ probe_info[i].name);
+
+ if (!VEC_length(stap_probe_p, info->probes[i]))
+ {
+ int j;
+
+ for (j = i - 1; j >= 0; j--)
+ {
+ VEC_free (stap_probe_p, info->probes[j]);
+ info->probes[j] = NULL;
+ }
+
+ all_probes_found = 0;
+ break;
+ }
+ }
+
+ if (all_probes_found)
+ {
+ info->using_probes = 1;
+
+ for (i = 0; i < NUM_PROBES; i++)
+ {
+ const struct stap_probe *probe;
+ int ix;
+
+ for (ix = 0;
+ VEC_iterate (stap_probe_p, info->probes[i], ix, probe);
+ ++ix)
+ create_solib_event_breakpoint (gdbarch, probe->address);
+ }
+
+ svr4_update_solib_event_breakpoints ();
+ return;
+ }
+ }
+
+ create_solib_event_breakpoint (gdbarch, address);
+}
+
/*
LOCAL FUNCTION
@@ -1372,10 +1533,18 @@ enable_break (struct svr4_info *info, int from_tty)
asection *interp_sect;
gdb_byte *interp_name;
CORE_ADDR sym_addr;
+ int i;
info->interp_text_sect_low = info->interp_text_sect_high = 0;
info->interp_plt_sect_low = info->interp_plt_sect_high = 0;
+ for (i = 0; i < NUM_PROBES; i++)
+ {
+ VEC_free (stap_probe_p, info->probes[i]);
+ info->probes[i] = NULL;
+ }
+ info->using_probes = 0;
+
/* If we already have a shared library list in the target, and
r_debug contains r_brk, set the breakpoint there - this should
mean r_brk has already been relocated. Assume the dynamic linker
@@ -1407,7 +1576,7 @@ enable_break (struct svr4_info *info, int from_tty)
That knowledge is encoded in the address, if it's Thumb the low bit
is 1. However, we've stripped that info above and it's not clear
what all the consequences are of passing a non-addr_bits_remove'd
- address to create_solib_event_breakpoint. The call to
+ address to svr4_create_solib_event_breakpoints. The call to
find_pc_section verifies we know about the address and have some
hope of computing the right kind of breakpoint to use (via
symbol info). It does mean that GDB needs to be pointed at a
@@ -1445,7 +1614,7 @@ enable_break (struct svr4_info *info, int from_tty)
+ bfd_section_size (tmp_bfd, interp_sect);
}
- create_solib_event_breakpoint (target_gdbarch, sym_addr);
+ svr4_create_solib_event_breakpoints (target_gdbarch, sym_addr);
return 1;
}
}
@@ -1599,7 +1768,8 @@ enable_break (struct svr4_info *info, int from_tty)
if (sym_addr != 0)
{
- create_solib_event_breakpoint (target_gdbarch, load_addr + sym_addr);
+ svr4_create_solib_event_breakpoints (target_gdbarch,
+ load_addr + sym_addr);
xfree (interp_name);
return 1;
}
@@ -1625,7 +1795,7 @@ enable_break (struct svr4_info *info, int from_tty)
sym_addr = gdbarch_convert_from_func_ptr_addr (target_gdbarch,
sym_addr,
&current_target);
- create_solib_event_breakpoint (target_gdbarch, sym_addr);
+ svr4_create_solib_event_breakpoints (target_gdbarch, sym_addr);
return 1;
}
}
@@ -1641,7 +1811,7 @@ enable_break (struct svr4_info *info, int from_tty)
sym_addr = gdbarch_convert_from_func_ptr_addr (target_gdbarch,
sym_addr,
&current_target);
- create_solib_event_breakpoint (target_gdbarch, sym_addr);
+ svr4_create_solib_event_breakpoints (target_gdbarch, sym_addr);
return 1;
}
}
@@ -2470,4 +2640,5 @@ _initialize_svr4_solib (void)
svr4_so_ops.lookup_lib_global_symbol = elf_lookup_lib_symbol;
svr4_so_ops.same = svr4_same;
svr4_so_ops.keep_data_in_core = svr4_keep_data_in_core;
+ svr4_so_ops.update_breakpoints = svr4_update_solib_event_breakpoints;
}
diff --git a/gdb/solib.c b/gdb/solib.c
index 3296ed4..7ba70ce 100644
--- a/gdb/solib.c
+++ b/gdb/solib.c
@@ -1313,6 +1313,18 @@ no_shared_libraries (char *ignored, int from_tty)
objfile_purge_solibs ();
}
+/* Enable or disable optional solib event breakpoints as appropriate. */
+
+void
+update_solib_breakpoints (void)
+{
+ struct target_so_ops *ops = solib_ops (target_gdbarch);
+
+ if (ops->update_breakpoints != NULL)
+ ops->update_breakpoints ();
+}
+
+
/* Reload shared libraries, but avoid reloading the same symbol file
we already have loaded. */
diff --git a/gdb/solib.h b/gdb/solib.h
index c473d85..7b3881c 100644
--- a/gdb/solib.h
+++ b/gdb/solib.h
@@ -78,4 +78,8 @@ extern void set_solib_ops (struct gdbarch *gdbarch,
extern int libpthread_name_p (const char *name);
+/* Enable or disable optional solib event breakpoints as appropriate. */
+
+extern void update_solib_breakpoints (void);
+
#endif /* SOLIB_H */
diff --git a/gdb/solist.h b/gdb/solist.h
index dad11be..14ede10 100644
--- a/gdb/solist.h
+++ b/gdb/solist.h
@@ -137,6 +137,13 @@ struct target_so_ops
core file (in particular, for readonly sections). */
int (*keep_data_in_core) (CORE_ADDR vaddr,
unsigned long size);
+
+ /* Enable or disable optional solib event breakpoints as
+ appropriate. This should be called whenever
+ stop_on_solib_events is changed. This pointer can be
+ NULL, in which case no enabling or disabling is necessary
+ for this target. */
+ void (*update_breakpoints) (void);
};
/* Free the memory associated with a (so_list *). */

View File

@ -27,7 +27,7 @@ Version: 7.3.50.20110722
# The release always contains a leading reserved number, start it at 1. # The release always contains a leading reserved number, start it at 1.
# `upstream' is not a part of `name' to stay fully rpm dependencies compatible for the testing. # `upstream' is not a part of `name' to stay fully rpm dependencies compatible for the testing.
Release: 4%{?_with_upstream:.upstream}%{?dist} Release: 5%{?_with_upstream:.upstream}%{?dist}
License: GPLv3+ and GPLv3+ with exceptions and GPLv2+ and GPLv2+ with exceptions and GPL+ and LGPLv2+ and BSD and Public Domain License: GPLv3+ and GPLv3+ with exceptions and GPLv2+ and GPLv2+ with exceptions and GPL+ and LGPLv2+ and BSD and Public Domain
Group: Development/Debuggers Group: Development/Debuggers
@ -533,6 +533,10 @@ Patch579: gdb-7.2.50-sparc-add-workaround-to-broken-debug-files.patch
# Improve GDB performance on inferior dlopen calls (Gary Benson, BZ 698001). # Improve GDB performance on inferior dlopen calls (Gary Benson, BZ 698001).
Patch617: gdb-dlopen-skip_inline_frames-perf.patch Patch617: gdb-dlopen-skip_inline_frames-perf.patch
# Fix dlopen of libpthread.so, patched glibc required (Gary Benson, BZ 669432).
Patch618: gdb-dlopen-stap-probe.patch
Patch619: gdb-dlopen-stap-probe-test.patch
BuildRequires: ncurses-devel%{?_isa} texinfo gettext flex bison expat-devel%{?_isa} BuildRequires: ncurses-devel%{?_isa} texinfo gettext flex bison expat-devel%{?_isa}
# --without-system-readline # --without-system-readline
# Requires: readline%{?_isa} # Requires: readline%{?_isa}
@ -795,6 +799,8 @@ rm -f gdb/jv-exp.c gdb/m2-exp.c gdb/objc-exp.c gdb/p-exp.c
%patch556 -p1 %patch556 -p1
%patch579 -p1 %patch579 -p1
%patch617 -p1 %patch617 -p1
%patch618 -p1
%patch619 -p1
%patch393 -p1 %patch393 -p1
%patch335 -p1 %patch335 -p1
@ -1217,6 +1223,9 @@ fi
%{_infodir}/gdb.info* %{_infodir}/gdb.info*
%changelog %changelog
* Wed Aug 10 2011 Jan Kratochvil <jan.kratochvil@redhat.com> - 7.3.50.20110722-5.fc16
- Fix dlopen of libpthread.so, patched glibc required (Gary Benson, BZ 669432).
* Tue Aug 9 2011 Jan Kratochvil <jan.kratochvil@redhat.com> - 7.3.50.20110722-4.fc16 * Tue Aug 9 2011 Jan Kratochvil <jan.kratochvil@redhat.com> - 7.3.50.20110722-4.fc16
- Improve GDB performance on inferior dlopen calls (Gary Benson, BZ 698001). - Improve GDB performance on inferior dlopen calls (Gary Benson, BZ 698001).
- [python] Fix crash when pretty printer fails (Phil Muldoon, BZ 712715). - [python] Fix crash when pretty printer fails (Phil Muldoon, BZ 712715).