gdb: don't print backtrace when dumping core after an internal error
authorAndrew Burgess <andrew.burgess@embecosm.com>
Wed, 21 Jul 2021 17:23:19 +0000 (18:23 +0100)
committerAndrew Burgess <andrew.burgess@embecosm.com>
Wed, 11 Aug 2021 11:35:15 +0000 (12:35 +0100)
Currently, when GDB hits an internal error, and the user selects to
dump core, the recently added feature to write a backtrace to the
console will kick in, and print a backtrace as well as dumping the
core.

This was certainly not my intention when adding the backtrace on fatal
signal functionality, this feature was intended to produce a backtrace
when GDB crashes due to some fatal signal, internal errors should have
continued to behave as they did before, unchanged.

In this commit I set the signal disposition of SIGABRT back to SIG_DFL
just prior to the call to abort() that GDB uses to trigger the core
dump, this prevents GDB reaching the code that writes the backtrace to
the console.

I've also added a test that checks we don't see a backtrace on the
console after an internal error.

gdb/testsuite/gdb.base/bt-on-fatal-signal.exp
gdb/utils.c

index 8875d00fdb115926df3d54fc338d24ede2a47a49..1f0d61f00ed5fe992253038f5c614510f72ac70c 100644 (file)
@@ -135,3 +135,39 @@ foreach test_data {{SEGV "Segmentation fault"} \
        gdb_exit
     }
 }
+
+# Check that when we get an internal error and choose to dump core, we
+# don't print a backtrace to the console.
+with_test_prefix "internal-error" {
+    # Restart GDB.
+    clean_restart $binfile
+
+    set saw_bt_start false
+
+    gdb_test_multiple "maint internal-error foo" "" {
+       -early -re "internal-error: foo\r\n" {
+           exp_continue
+       }
+       -early -re "^A problem internal to GDB has been detected,\r\n" {
+           exp_continue
+       }
+       -early -re "^further debugging may prove unreliable\\.\r\n" {
+           exp_continue
+       }
+       -early -re "^Quit this debugging session\\? \\(y or n\\)" {
+           send_gdb "y\n"
+           exp_continue
+       }
+       -early -re "^Create a core file of GDB\\? \\(y or n\\)" {
+           send_gdb "y\n"
+           exp_continue
+       }
+       -early -re "----- Backtrace -----\r\n" {
+           set saw_bt_start true
+           exp_continue
+       }
+       eof {
+           gdb_assert { [expr ! $saw_bt_start] }
+       }
+    }
+}
index c59c63565eb1f93ce9c272aa9d893dffad9c8bc2..1c226d5d85e57aacd0568753d8c5d1bda9bf1394 100644 (file)
@@ -201,6 +201,11 @@ dump_core (void)
   setrlimit (RLIMIT_CORE, &rlim);
 #endif /* HAVE_SETRLIMIT */
 
+  /* Ensure that the SIGABRT we're about to raise will immediately cause
+     GDB to exit and dump core, we don't want to trigger GDB's printing of
+     a backtrace to the console here.  */
+  signal (SIGABRT, SIG_DFL);
+
   abort ();            /* ARI: abort */
 }