diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
index c6bd6f68363..5fdfdea3f05 100644
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -6406,7 +6406,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 85ac3d9aab6..ea8d6421fd6 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -32290,6 +32290,11 @@
 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 sometime 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 906e627a068..7c32e87ebdb 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" ".*"
+}
