]> git.eshelyaron.com Git - emacs.git/commitdiff
Enable stack overflow recovery on Android
authorPo Lu <luangruo@yahoo.com>
Sat, 9 Mar 2024 08:12:40 +0000 (16:12 +0800)
committerEshel Yaron <me@eshelyaron.com>
Mon, 11 Mar 2024 09:21:40 +0000 (10:21 +0100)
* src/sysdep.c (handle_sigsegv): Return after restoring the
original signal handler, which should proceed to call debuggerd
to generate a tombstone.
(init_sigsegv): Save the original signal handler on Android, to
be restored after a signal is received.
(init_signals): Call init_sigsegv on Android.

(cherry picked from commit 5d9a8c3704c156cccea90a46362e6bfae0de87f2)

src/sysdep.c

index 3a6829dd27a56fc031ebc8845c101f62599b0de0..cf2985b4b89eb694f919bbd07ef3805938f85238 100644 (file)
@@ -1853,11 +1853,7 @@ init_sigbus (void)
 
 #endif
 
-/* This does not work on Android and interferes with the system
-   tombstone generation.  */
-
-#if defined HAVE_STACK_OVERFLOW_HANDLING && !defined WINDOWSNT \
-  && (!defined HAVE_ANDROID || defined ANDROID_STUBIFY)
+#if defined HAVE_STACK_OVERFLOW_HANDLING && !defined WINDOWSNT
 
 /* Alternate stack used by SIGSEGV handler below.  */
 
@@ -1921,6 +1917,8 @@ stack_overflow (siginfo_t *siginfo)
     return 0 <= top - addr && top - addr < (bot - top) >> LG_STACK_HEURISTIC;
 }
 
+/* Signal handler for SIGSEGV before our new handler was installed.  */
+static struct sigaction old_sigsegv_handler;
 
 /* Attempt to recover from SIGSEGV caused by C stack overflow.  */
 
@@ -1939,6 +1937,15 @@ handle_sigsegv (int sig, siginfo_t *siginfo, void *arg)
   if (!fatal && stack_overflow (siginfo))
     siglongjmp (return_to_command_loop, 1);
 
+#if defined HAVE_ANDROID && !defined ANDROID_STUBIFY
+  /* Tombstones (crash reports with stack traces) won't be generated on
+     Android unless the original SIGSEGV handler is installed and the
+     signal is resent, such as by returning from the first signal
+     handler called.  */
+  sigaction (SIGSEGV, &old_sigsegv_handler, NULL);
+  return;
+#endif /* HAVE_ANDROID && ANDROID_STUBIFY */
+
   /* Otherwise we can't do anything with this.  */
   deliver_fatal_thread_signal (sig);
 }
@@ -1961,7 +1968,7 @@ init_sigsegv (void)
   sigfillset (&sa.sa_mask);
   sa.sa_sigaction = handle_sigsegv;
   sa.sa_flags = SA_SIGINFO | SA_ONSTACK | emacs_sigaction_flags ();
-  if (sigaction (SIGSEGV, &sa, NULL) < 0)
+  if (sigaction (SIGSEGV, &sa, &old_sigsegv_handler) < 0)
     return 0;
 
   return 1;
@@ -1969,16 +1976,12 @@ init_sigsegv (void)
 
 #else /* not HAVE_STACK_OVERFLOW_HANDLING or WINDOWSNT */
 
-#if !defined HAVE_ANDROID || defined ANDROID_STUBIFY
-
 static bool
 init_sigsegv (void)
 {
   return 0;
 }
 
-#endif
-
 #endif /* HAVE_STACK_OVERFLOW_HANDLING && !WINDOWSNT */
 
 static void
@@ -2125,10 +2128,8 @@ init_signals (void)
 #endif
     sigaction (SIGBUS, &thread_fatal_action, 0);
 #endif
-#if !defined HAVE_ANDROID || defined ANDROID_STUBIFY
   if (!init_sigsegv ())
     sigaction (SIGSEGV, &thread_fatal_action, 0);
-#endif
 #ifdef SIGSYS
   sigaction (SIGSYS, &thread_fatal_action, 0);
 #endif