comparison src/emacs.c @ 4871:d8d92ad084b8

rewrite check for bad memory in debug_can_save_memory -------------------- ChangeLog entries follow: -------------------- src/ChangeLog addition: 2010-01-15 Ben Wing <ben@xemacs.org> * 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.
author Ben Wing <ben@xemacs.org>
date Fri, 15 Jan 2010 04:47:00 -0600
parents 95c4ced5c07c
children a6c778975d7d 17362f371cc2 8b63e21b0436
comparison
equal deleted inserted replaced
4870:db9f7328bee1 4871:d8d92ad084b8
3371 EMACS_REESTABLISH_SIGNAL (signum, debug_memory_error); 3371 EMACS_REESTABLISH_SIGNAL (signum, debug_memory_error);
3372 EMACS_UNBLOCK_SIGNAL (signum); 3372 EMACS_UNBLOCK_SIGNAL (signum);
3373 LONGJMP (memory_error_jump, 1); 3373 LONGJMP (memory_error_jump, 1);
3374 } 3374 }
3375 3375
3376 /* Used in debug_can_access_memory(). Made into a global, externally
3377 accessible variable to make absolutely sure that no compiler will
3378 optimize away the memory-read function in debug_can_access_memory();
3379 see comments there. */
3380
3381 volatile int dcam_saveval;
3382
3376 /* Return whether all bytes in the specified memory block can be read. */ 3383 /* Return whether all bytes in the specified memory block can be read. */
3377 int 3384 int
3378 debug_can_access_memory (const void *ptr, Bytecount len) 3385 debug_can_access_memory (const void *ptr, Bytecount len)
3379 { 3386 {
3380 /* Use volatile to protect variables from being clobbered by longjmp. */ 3387 /* Use volatile to protect variables from being clobbered by longjmp. */
3381 SIGTYPE (*volatile old_sigbus) (int); 3388 SIGTYPE (*volatile old_sigbus) (int);
3382 SIGTYPE (*volatile old_sigsegv) (int); 3389 SIGTYPE (*volatile old_sigsegv) (int);
3383 volatile int old_errno = errno; 3390 volatile int old_errno = errno;
3384 volatile int retval = 1; 3391 volatile int retval = 1;
3385 3392
3393 assert (len > 0);
3386 if (!SETJMP (memory_error_jump)) 3394 if (!SETJMP (memory_error_jump))
3387 { 3395 {
3388 old_sigbus = 3396 old_sigbus =
3389 (SIGTYPE (*) (int)) EMACS_SIGNAL (SIGBUS, debug_memory_error); 3397 (SIGTYPE (*) (int)) EMACS_SIGNAL (SIGBUS, debug_memory_error);
3390 old_sigsegv = 3398 old_sigsegv =
3391 (SIGTYPE (*) (int)) EMACS_SIGNAL (SIGSEGV, debug_memory_error); 3399 (SIGTYPE (*) (int)) EMACS_SIGNAL (SIGSEGV, debug_memory_error);
3392 3400
3401 /* We could just do memcmp (ptr, ptr, len), but we want to avoid any
3402 possibility that a super-optimizing compiler might optimize away such
3403 a call by concluding that its result is always 1. */
3393 if (len > 1) 3404 if (len > 1)
3394 /* If we can, try to avoid problems with super-optimizing compilers 3405 /* Instead, if length is > 1, do off-by-one comparison.
3395 that might decide that memcmp (ptr, ptr, len) can be optimized 3406 We save the value somewhere that is externally accessible to
3396 away since its result is always 1. */ 3407 make absolutely sure that a compiler won't optimize away the
3397 memcmp (ptr, (Rawbyte *) ptr + 1, len - 1); 3408 call by concluding that the return value isn't really used.
3409 */
3410 dcam_saveval = memcmp (ptr, (Rawbyte *) ptr + 1, len - 1);
3398 else 3411 else
3399 memcmp (ptr, ptr, len); 3412 {
3413 /* We can't do the off-by-one trick with only one byte, so instead,
3414 we compare to a fixed-sized buffer. */
3415 char randval[1];
3416 randval[0] = 0;
3417 dcam_saveval = memcmp (randval, ptr, len);
3418 }
3400 } 3419 }
3401 else 3420 else
3402 retval = 0; 3421 retval = 0;
3403 EMACS_SIGNAL (SIGBUS, old_sigbus); 3422 EMACS_SIGNAL (SIGBUS, old_sigbus);
3404 EMACS_SIGNAL (SIGSEGV, old_sigsegv); 3423 EMACS_SIGNAL (SIGSEGV, old_sigsegv);