# HG changeset patch # User Ben Wing # Date 1263552420 21600 # Node ID d8d92ad084b8b3b8c8b23f370d47c369613bab76 # Parent db9f7328bee1db28293183593790f4792989dacd rewrite check for bad memory in debug_can_save_memory -------------------- ChangeLog entries follow: -------------------- src/ChangeLog addition: 2010-01-15 Ben Wing * emacs.c: * emacs.c (debug_can_access_memory): When checking for bad memory, we need to read all bytes from memory; try even harder to avoid the possibility that a super-optimizing compiler will optimize away the memory reads. diff -r db9f7328bee1 -r d8d92ad084b8 src/ChangeLog --- a/src/ChangeLog Fri Jan 15 04:41:21 2010 -0600 +++ b/src/ChangeLog Fri Jan 15 04:47:00 2010 -0600 @@ -1,3 +1,11 @@ +2010-01-15 Ben Wing + + * emacs.c: + * emacs.c (debug_can_access_memory): + When checking for bad memory, we need to read all bytes from memory; + try even harder to avoid the possibility that a super-optimizing + compiler will optimize away the memory reads. + 2010-01-15 Ben Wing * syswindows.h (LOCAL_FILE_FORMAT_TO_TSTR): diff -r db9f7328bee1 -r d8d92ad084b8 src/emacs.c --- a/src/emacs.c Fri Jan 15 04:41:21 2010 -0600 +++ b/src/emacs.c Fri Jan 15 04:47:00 2010 -0600 @@ -3373,6 +3373,13 @@ LONGJMP (memory_error_jump, 1); } +/* Used in debug_can_access_memory(). Made into a global, externally + accessible variable to make absolutely sure that no compiler will + optimize away the memory-read function in debug_can_access_memory(); + see comments there. */ + +volatile int dcam_saveval; + /* Return whether all bytes in the specified memory block can be read. */ int debug_can_access_memory (const void *ptr, Bytecount len) @@ -3383,6 +3390,7 @@ volatile int old_errno = errno; volatile int retval = 1; + assert (len > 0); if (!SETJMP (memory_error_jump)) { old_sigbus = @@ -3390,13 +3398,24 @@ old_sigsegv = (SIGTYPE (*) (int)) EMACS_SIGNAL (SIGSEGV, debug_memory_error); + /* We could just do memcmp (ptr, ptr, len), but we want to avoid any + possibility that a super-optimizing compiler might optimize away such + a call by concluding that its result is always 1. */ if (len > 1) - /* If we can, try to avoid problems with super-optimizing compilers - that might decide that memcmp (ptr, ptr, len) can be optimized - away since its result is always 1. */ - memcmp (ptr, (Rawbyte *) ptr + 1, len - 1); + /* Instead, if length is > 1, do off-by-one comparison. + We save the value somewhere that is externally accessible to + make absolutely sure that a compiler won't optimize away the + call by concluding that the return value isn't really used. + */ + dcam_saveval = memcmp (ptr, (Rawbyte *) ptr + 1, len - 1); else - memcmp (ptr, ptr, len); + { + /* We can't do the off-by-one trick with only one byte, so instead, + we compare to a fixed-sized buffer. */ + char randval[1]; + randval[0] = 0; + dcam_saveval = memcmp (randval, ptr, len); + } } else retval = 0;