aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorEli Zaretskii2024-01-26 15:01:51 +0200
committerEli Zaretskii2024-01-26 15:01:51 +0200
commitde020255a5cef4349d786fceb19481352c49557b (patch)
tree983b2f255dbdeeb4c3c302adcf7f92ea77c6b75b /src
parent723b0973512c0e6e9fb0f07678124347ccd44b54 (diff)
downloademacs-de020255a5cef4349d786fceb19481352c49557b.tar.gz
emacs-de020255a5cef4349d786fceb19481352c49557b.zip
Fix crash backtraces on MS-Windows, broken by ASLR
* src/w32fns.c (DEFAULT_IMAGE_BASE): Define for 64-bit and 32-bit MinGW builds. (emacs_abort): Correct the callstack addresses for potential relocation of the image base due to ASLR. This makes 'addr2line' be able to interpret emacs_backtrace.txt when ASLR is in effect, which it is on every modern version of MS-Windows. (Bug#63365) * configure.ac (LD_SWITCH_SYSTEM_TEMACS) [mingw32]: Add comment about keeping the image-base values in sync with w32fns.c. * etc/DEBUG (How to disable ASLR): New section.
Diffstat (limited to 'src')
-rw-r--r--src/w32fns.c26
1 files changed, 23 insertions, 3 deletions
diff --git a/src/w32fns.c b/src/w32fns.c
index f8de45da7c9..f44460e52c0 100644
--- a/src/w32fns.c
+++ b/src/w32fns.c
@@ -11121,12 +11121,20 @@ my_exception_handler (EXCEPTION_POINTERS * exception_data)
11121 return prev_exception_handler (exception_data); 11121 return prev_exception_handler (exception_data);
11122 return EXCEPTION_EXECUTE_HANDLER; 11122 return EXCEPTION_EXECUTE_HANDLER;
11123} 11123}
11124#endif 11124#endif /* !CYGWIN */
11125 11125
11126typedef USHORT (WINAPI * CaptureStackBackTrace_proc) (ULONG, ULONG, PVOID *, 11126typedef USHORT (WINAPI * CaptureStackBackTrace_proc) (ULONG, ULONG, PVOID *,
11127 PULONG); 11127 PULONG);
11128 11128
11129#define BACKTRACE_LIMIT_MAX 62 11129#define BACKTRACE_LIMIT_MAX 62
11130/* The below must be kept in sync with the value of the
11131 -Wl,-image-base switch we use in LD_SWITCH_SYSTEM_TEMACS, see
11132 configure.ac. */
11133#if defined MINGW_W64 && EMACS_INT_MAX > LONG_MAX
11134# define DEFAULT_IMAGE_BASE (ptrdiff_t)0x400000000
11135#else /* 32-bit MinGW build */
11136# define DEFAULT_IMAGE_BASE (ptrdiff_t)0x01000000
11137#endif
11130 11138
11131static int 11139static int
11132w32_backtrace (void **buffer, int limit) 11140w32_backtrace (void **buffer, int limit)
@@ -11181,6 +11189,13 @@ emacs_abort (void)
11181 { 11189 {
11182 void *stack[BACKTRACE_LIMIT_MAX + 1]; 11190 void *stack[BACKTRACE_LIMIT_MAX + 1];
11183 int i = w32_backtrace (stack, BACKTRACE_LIMIT_MAX + 1); 11191 int i = w32_backtrace (stack, BACKTRACE_LIMIT_MAX + 1);
11192#ifdef CYGWIN
11193 ptrdiff_t addr_offset = 0;
11194#else /* MinGW */
11195 /* The offset below is zero unless ASLR is in effect. */
11196 ptrdiff_t addr_offset
11197 = DEFAULT_IMAGE_BASE - (ptrdiff_t)GetModuleHandle (NULL);
11198#endif /* MinGW */
11184 11199
11185 if (i) 11200 if (i)
11186 { 11201 {
@@ -11231,8 +11246,13 @@ emacs_abort (void)
11231 { 11246 {
11232 /* stack[] gives the return addresses, whereas we want 11247 /* stack[] gives the return addresses, whereas we want
11233 the address of the call, so decrease each address 11248 the address of the call, so decrease each address
11234 by approximate size of 1 CALL instruction. */ 11249 by approximate size of 1 CALL instruction. We add
11235 sprintf (buf, "%p\r\n", (char *)stack[j] - sizeof(void *)); 11250 ADDR_OFFSET to account for ASLR which changes the
11251 base address of the program's image in memory,
11252 whereas 'addr2line' needs to see addresses relative
11253 to the fixed base recorded in the PE header. */
11254 sprintf (buf, "%p\r\n",
11255 (char *)stack[j] - sizeof(void *) + addr_offset);
11236 if (stderr_fd >= 0) 11256 if (stderr_fd >= 0)
11237 write (stderr_fd, buf, strlen (buf)); 11257 write (stderr_fd, buf, strlen (buf));
11238 if (errfile_fd >= 0) 11258 if (errfile_fd >= 0)