diff options
| author | Po Lu | 2024-03-09 16:12:40 +0800 |
|---|---|---|
| committer | Po Lu | 2024-03-09 16:13:50 +0800 |
| commit | 5d9a8c3704c156cccea90a46362e6bfae0de87f2 (patch) | |
| tree | 89d4c9455866e4345e5e49d9dfb84541be0d82d9 /src | |
| parent | a4473afefe1a0f171ac6e811853836dd675f93d2 (diff) | |
| download | emacs-5d9a8c3704c156cccea90a46362e6bfae0de87f2.tar.gz emacs-5d9a8c3704c156cccea90a46362e6bfae0de87f2.zip | |
Enable stack overflow recovery on Android
* 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.
Diffstat (limited to 'src')
| -rw-r--r-- | src/sysdep.c | 25 |
1 files changed, 13 insertions, 12 deletions
diff --git a/src/sysdep.c b/src/sysdep.c index 3a6829dd27a..cf2985b4b89 100644 --- a/src/sysdep.c +++ b/src/sysdep.c | |||
| @@ -1853,11 +1853,7 @@ init_sigbus (void) | |||
| 1853 | 1853 | ||
| 1854 | #endif | 1854 | #endif |
| 1855 | 1855 | ||
| 1856 | /* This does not work on Android and interferes with the system | 1856 | #if defined HAVE_STACK_OVERFLOW_HANDLING && !defined WINDOWSNT |
| 1857 | tombstone generation. */ | ||
| 1858 | |||
| 1859 | #if defined HAVE_STACK_OVERFLOW_HANDLING && !defined WINDOWSNT \ | ||
| 1860 | && (!defined HAVE_ANDROID || defined ANDROID_STUBIFY) | ||
| 1861 | 1857 | ||
| 1862 | /* Alternate stack used by SIGSEGV handler below. */ | 1858 | /* Alternate stack used by SIGSEGV handler below. */ |
| 1863 | 1859 | ||
| @@ -1921,6 +1917,8 @@ stack_overflow (siginfo_t *siginfo) | |||
| 1921 | return 0 <= top - addr && top - addr < (bot - top) >> LG_STACK_HEURISTIC; | 1917 | return 0 <= top - addr && top - addr < (bot - top) >> LG_STACK_HEURISTIC; |
| 1922 | } | 1918 | } |
| 1923 | 1919 | ||
| 1920 | /* Signal handler for SIGSEGV before our new handler was installed. */ | ||
| 1921 | static struct sigaction old_sigsegv_handler; | ||
| 1924 | 1922 | ||
| 1925 | /* Attempt to recover from SIGSEGV caused by C stack overflow. */ | 1923 | /* Attempt to recover from SIGSEGV caused by C stack overflow. */ |
| 1926 | 1924 | ||
| @@ -1939,6 +1937,15 @@ handle_sigsegv (int sig, siginfo_t *siginfo, void *arg) | |||
| 1939 | if (!fatal && stack_overflow (siginfo)) | 1937 | if (!fatal && stack_overflow (siginfo)) |
| 1940 | siglongjmp (return_to_command_loop, 1); | 1938 | siglongjmp (return_to_command_loop, 1); |
| 1941 | 1939 | ||
| 1940 | #if defined HAVE_ANDROID && !defined ANDROID_STUBIFY | ||
| 1941 | /* Tombstones (crash reports with stack traces) won't be generated on | ||
| 1942 | Android unless the original SIGSEGV handler is installed and the | ||
| 1943 | signal is resent, such as by returning from the first signal | ||
| 1944 | handler called. */ | ||
| 1945 | sigaction (SIGSEGV, &old_sigsegv_handler, NULL); | ||
| 1946 | return; | ||
| 1947 | #endif /* HAVE_ANDROID && ANDROID_STUBIFY */ | ||
| 1948 | |||
| 1942 | /* Otherwise we can't do anything with this. */ | 1949 | /* Otherwise we can't do anything with this. */ |
| 1943 | deliver_fatal_thread_signal (sig); | 1950 | deliver_fatal_thread_signal (sig); |
| 1944 | } | 1951 | } |
| @@ -1961,7 +1968,7 @@ init_sigsegv (void) | |||
| 1961 | sigfillset (&sa.sa_mask); | 1968 | sigfillset (&sa.sa_mask); |
| 1962 | sa.sa_sigaction = handle_sigsegv; | 1969 | sa.sa_sigaction = handle_sigsegv; |
| 1963 | sa.sa_flags = SA_SIGINFO | SA_ONSTACK | emacs_sigaction_flags (); | 1970 | sa.sa_flags = SA_SIGINFO | SA_ONSTACK | emacs_sigaction_flags (); |
| 1964 | if (sigaction (SIGSEGV, &sa, NULL) < 0) | 1971 | if (sigaction (SIGSEGV, &sa, &old_sigsegv_handler) < 0) |
| 1965 | return 0; | 1972 | return 0; |
| 1966 | 1973 | ||
| 1967 | return 1; | 1974 | return 1; |
| @@ -1969,16 +1976,12 @@ init_sigsegv (void) | |||
| 1969 | 1976 | ||
| 1970 | #else /* not HAVE_STACK_OVERFLOW_HANDLING or WINDOWSNT */ | 1977 | #else /* not HAVE_STACK_OVERFLOW_HANDLING or WINDOWSNT */ |
| 1971 | 1978 | ||
| 1972 | #if !defined HAVE_ANDROID || defined ANDROID_STUBIFY | ||
| 1973 | |||
| 1974 | static bool | 1979 | static bool |
| 1975 | init_sigsegv (void) | 1980 | init_sigsegv (void) |
| 1976 | { | 1981 | { |
| 1977 | return 0; | 1982 | return 0; |
| 1978 | } | 1983 | } |
| 1979 | 1984 | ||
| 1980 | #endif | ||
| 1981 | |||
| 1982 | #endif /* HAVE_STACK_OVERFLOW_HANDLING && !WINDOWSNT */ | 1985 | #endif /* HAVE_STACK_OVERFLOW_HANDLING && !WINDOWSNT */ |
| 1983 | 1986 | ||
| 1984 | static void | 1987 | static void |
| @@ -2125,10 +2128,8 @@ init_signals (void) | |||
| 2125 | #endif | 2128 | #endif |
| 2126 | sigaction (SIGBUS, &thread_fatal_action, 0); | 2129 | sigaction (SIGBUS, &thread_fatal_action, 0); |
| 2127 | #endif | 2130 | #endif |
| 2128 | #if !defined HAVE_ANDROID || defined ANDROID_STUBIFY | ||
| 2129 | if (!init_sigsegv ()) | 2131 | if (!init_sigsegv ()) |
| 2130 | sigaction (SIGSEGV, &thread_fatal_action, 0); | 2132 | sigaction (SIGSEGV, &thread_fatal_action, 0); |
| 2131 | #endif | ||
| 2132 | #ifdef SIGSYS | 2133 | #ifdef SIGSYS |
| 2133 | sigaction (SIGSYS, &thread_fatal_action, 0); | 2134 | sigaction (SIGSYS, &thread_fatal_action, 0); |
| 2134 | #endif | 2135 | #endif |