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 +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 . */ ++ ++#include ++#include ++ ++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 . */ ++ ++#include ++#include ++#include ++ ++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 . ++ ++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 +To: Jan Kratochvil +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, + ¤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 - 7.3.50.20110722-5.fc16 +- Fix dlopen of libpthread.so, patched glibc required (Gary Benson, BZ 669432). + * Tue Aug 9 2011 Jan Kratochvil - 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).