[gdb/f16] Fix dlopen of libpthread.so, patched glibc required (Gary Benson, BZ 669432).
Jan Kratochvil
jankratochvil at fedoraproject.org
Wed Aug 10 17:42:25 UTC 2011
commit 922e4a0796ed02d391ea64de0735185d12a52819
Author: Jan Kratochvil <jan.kratochvil at redhat.com>
Date: Wed Aug 10 19:42:06 2011 +0200
Fix dlopen of libpthread.so, patched glibc required (Gary Benson, BZ 669432).
gdb-dlopen-stap-probe-test.patch | 408 ++++++++++++++++++++++++++++++++++++++
gdb-dlopen-stap-probe.patch | 358 +++++++++++++++++++++++++++++++++
gdb.spec | 11 +-
3 files changed, 776 insertions(+), 1 deletions(-)
---
diff --git a/gdb-dlopen-stap-probe-test.patch b/gdb-dlopen-stap-probe-test.patch
new file mode 100644
index 0000000..55a6a92
--- /dev/null
+++ b/gdb-dlopen-stap-probe-test.patch
@@ -0,0 +1,408 @@
+commit 5bfdc32cd3bf373c3b02e1fd864ed8ceab0292b2
+Author: Jan Kratochvil <jan.kratochvil at 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
diff --git a/gdb-dlopen-stap-probe.patch b/gdb-dlopen-stap-probe.patch
new file mode 100644
index 0000000..5352299
--- /dev/null
+++ b/gdb-dlopen-stap-probe.patch
@@ -0,0 +1,358 @@
+From: Gary Benson <gbenson at redhat.com>
+To: Jan Kratochvil <jan.kratochvil at redhat.com>
+Message-ID: <20110810133605.GB7294 at 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,
+ ¤t_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,
+ ¤t_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 *). */
diff --git a/gdb.spec b/gdb.spec
index ca03f93..2c15a06 100644
--- a/gdb.spec
+++ b/gdb.spec
@@ -27,7 +27,7 @@ Version: 7.3.50.20110722
# 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.
-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
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).
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}
# --without-system-readline
# 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
%patch579 -p1
%patch617 -p1
+%patch618 -p1
+%patch619 -p1
%patch393 -p1
%patch335 -p1
@@ -1217,6 +1223,9 @@ fi
%{_infodir}/gdb.info*
%changelog
+* Wed Aug 10 2011 Jan Kratochvil <jan.kratochvil at 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 at redhat.com> - 7.3.50.20110722-4.fc16
- Improve GDB performance on inferior dlopen calls (Gary Benson, BZ 698001).
- [python] Fix crash when pretty printer fails (Phil Muldoon, BZ 712715).
More information about the scm-commits
mailing list