aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/breakpoint.c23
-rw-r--r--gdb/doc/gdb.texinfo5
-rw-r--r--gdb/testsuite/gdb.base/nostdlib.exp69
3 files changed, 72 insertions, 25 deletions
diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
index b2017ef..cf9cd76 100644
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -6424,7 +6424,28 @@ print_breakpoint_location (const breakpoint *b, const bp_location *loc)
uiout->field_stream ("at", stb);
}
else
- uiout->field_string ("pending", b->locspec->to_string ());
+ {
+ /* Internal breakpoints don't have a locspec string, but can become
+ pending if the shared library the breakpoint is in is unloaded.
+ For most internal breakpoint types though, after unloading the
+ shared library, the breakpoint will be deleted and never recreated
+ (see internal_breakpoint::re_set). But for two internal
+ breakpoint types bp_shlib_event and bp_thread_event this is not
+ true. Usually we don't expect the libraries that contain these
+ breakpoints to ever be unloaded, but a buggy inferior might do
+ such a thing, in which case GDB should be prepared to handle this
+ case.
+
+ If these two breakpoint types become pending then there will be no
+ locspec string. */
+ gdb_assert (b->locspec != nullptr
+ || (!user_breakpoint_p (b)
+ && (b->type == bp_shlib_event
+ || b->type == bp_thread_event)));
+ const char *locspec_str
+ = (b->locspec != nullptr ? b->locspec->to_string () : "");
+ uiout->field_string ("pending", locspec_str);
+ }
if (loc && is_breakpoint (b)
&& breakpoint_condition_evaluation_mode () == condition_evaluation_target
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 8f1f0bb..19abd97 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -32429,6 +32429,11 @@ by a symbol name.
If this breakpoint is pending, this field is present and holds the
text used to set the breakpoint, as entered by the user.
+@value{GDBN}'s internal breakpoints (@pxref{maint info breakpoints})
+can sometimes become pending too, for these breakpoints the
+@var{pending} field will be empty as @value{GDBN} automatically
+creates these breakpoints as shared libraries are loaded.
+
@item evaluated-by
Where this breakpoint's condition is evaluated, either @samp{host} or
@samp{target}.
diff --git a/gdb/testsuite/gdb.base/nostdlib.exp b/gdb/testsuite/gdb.base/nostdlib.exp
index 906e627..7c32e87 100644
--- a/gdb/testsuite/gdb.base/nostdlib.exp
+++ b/gdb/testsuite/gdb.base/nostdlib.exp
@@ -24,33 +24,54 @@ require !use_gdb_stub
# dependent on whether the system libraries are already prelinked.
# prelink: Could not set /lib64/libm-2.11.1.so owner or mode: Operation not permitted
set compile {
- gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-nostdlib}
-}
-set board [target_info name]
-if [board_info $board exists mathlib] {
- set mathlib [board_info $dest mathlib]
- set_board_info mathlib ""
- set err [eval $compile]
- set_board_info mathlib $mathlib
-} else {
- set_board_info mathlib ""
- set err [eval $compile]
- unset_board_info mathlib
-}
-if {$err != ""} {
- untested "failed to compile"
- return -1
+ gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable $opts
}
-clean_restart $binfile
+foreach_with_prefix pie { "nopie" "pie" } {
+ # OPTS and BINFILE are used by the COMPILE string (defined above)
+ # when it is evaluated below.
+ set opts [list debug additional_flags=-nostdlib $pie]
+ set binfile [standard_output_file $testfile-$pie]
+
+ set board [target_info name]
+ if [board_info $board exists mathlib] {
+ set mathlib [board_info $dest mathlib]
+ set_board_info mathlib ""
+ set err [eval $compile]
+ set_board_info mathlib $mathlib
+ } else {
+ set_board_info mathlib ""
+ set err [eval $compile]
+ unset_board_info mathlib
+ }
+ if {$err != ""} {
+ untested "failed to compile"
+ return -1
+ }
-gdb_breakpoint "*marker"
-gdb_breakpoint "*_start"
+ clean_restart $binfile
-gdb_run_cmd
+ gdb_breakpoint "*marker"
+ gdb_breakpoint "*_start"
-# Breakpoint 2, Stopped due to shared library event
-# _start () at ./gdb.base/nostdlib.c:20
-gdb_test "" {Breakpoint [0-9]+, .*_start .*} "stop at run"
+ gdb_run_cmd
-gdb_test "continue" {Breakpoint [0-9]+, marker .*} "continue to marker"
+ # Breakpoint 2, Stopped due to shared library event
+ # _start () at ./gdb.base/nostdlib.c:20
+ gdb_test "" {Breakpoint [0-9]+, .*_start .*} "stop at run"
+
+ gdb_test "continue" {Breakpoint [0-9]+, marker .*} "continue to marker"
+
+ # When compiling as PIE the executable will be a dynamic
+ # executable, the dynamic linker performs the PIE relocation.
+ # Some versions of glibc would (possibly due to a bug) report the
+ # dynamic linker as unmapped during startup, which places the
+ # 'shlib event' breakpoint(s) into the PENDING state.
+ #
+ # At one point trying to print these internal breakpoints in a
+ # PENDING state would crash GDB, so lets make sure that doesn't
+ # happen now. We don't really care about the exact output,
+ # gdb_test will spot if running this command crashes GDB, which is
+ # all we're really checking for.
+ gdb_test "maint info breakpoints" ".*"
+}