+static void ATTRIBUTE_NORETURN
+handle_fatal_signal (int sig)
+{
+#ifdef GDB_PRINT_INTERNAL_BACKTRACE
+ const auto sig_write = [] (const char *msg) -> void
+ {
+ gdb_stderr->write_async_safe (msg, strlen (msg));
+ };
+
+ if (bt_on_fatal_signal)
+ {
+ sig_write ("\n\n");
+ sig_write (_("Fatal signal: "));
+ sig_write (strsignal (sig));
+ sig_write ("\n");
+
+ gdb_internal_backtrace ();
+
+ sig_write (_("A fatal error internal to GDB has been detected, "
+ "further\ndebugging is not possible. GDB will now "
+ "terminate.\n\n"));
+ sig_write (_("This is a bug, please report it."));
+ if (REPORT_BUGS_TO[0] != '\0')
+ {
+ sig_write (_(" For instructions, see:\n"));
+ sig_write (REPORT_BUGS_TO);
+ sig_write (".");
+ }
+ sig_write ("\n\n");
+
+ gdb_stderr->flush ();
+ }
+#endif
+
+ /* If possible arrange for SIG to have its default behaviour (which
+ should be to terminate the current process), unblock SIG, and reraise
+ the signal. This ensures GDB terminates with the expected signal. */
+ if (signal (sig, SIG_DFL) != SIG_ERR
+ && unblock_signal (sig))
+ raise (sig);
+
+ /* The above failed, so try to use SIGABRT to terminate GDB. */
+#ifdef SIGABRT
+ signal (SIGABRT, SIG_DFL);
+#endif
+ abort (); /* ARI: abort */
+}
+
+/* The SIGSEGV handler for this thread, or NULL if there is none. GDB
+ always installs a global SIGSEGV handler, and then lets threads
+ indicate their interest in handling the signal by setting this
+ thread-local variable.
+
+ This is a static variable instead of extern because on various platforms
+ (notably Cygwin) extern thread_local variables cause link errors. So
+ instead, we have scoped_segv_handler_restore, which also makes it impossible
+ to accidentally forget to restore it to the original value. */
+
+static thread_local void (*thread_local_segv_handler) (int);