From: John R. <jr...@Bi...> - 2003-08-18 14:17:22
|
Zeljko Vrba wrote: > On Thu, Aug 14, 2003 at 11:29:44AM -0700, John Reiser wrote: > >>>Lucky for us, so does the x86. There is a flag you can set in some >>>register or other which makes the CPU trap on unaligned access. So long >>>as we don't do it internally, you could set that and watch all the >>>unaligned accesses in your program (even without Valgrind). >> >>Yes, it's the AC [Alignment Check] bit of the processor flags, >>which is bit 18 (the bit with positional value (1<<18) or 0x40000). >>It checks for unaligned access in user mode. >> > > But not only AC. As I recall, some other bit in some control register (CR) > must be enabled also. And even then, AC occurs only in user mode (ring 3). Did you try the example? It runs as expected in Linux 2.4.20, namely: generates SIGBUS for unaligned access from user mode (ring 3). So the AM bit (also bit 18, but in CR0) is enabled by the kernel. Valgrind (memcheck) applies only to user mode, so there is no additional restriction on this method of checking alignment of memory accesses. Even better, you can check any executable without recompilation: $ gdb a.elf (gdb) b main # any place you want to start checking (gdb) run Breakpoint 1 (gdb) set var $ps |= 1<<18 # set AlignmentCheck bit of eflags (gdb) continue and now gdb will catch SIGBUS for any unaligned access. To continue past each unaligned access: (gdb) handle SIGBUS nopass print stop # notify gdb+user, and not a.elf (gdb) set var $ps &= ~(1<<18) # clear AlignmentCheck bit of eflags (gdb) stepi # perform unaligned access (gdb) set var $ps |= (1<<18) # set AlignmentCheck bit of eflags (gdb) continue and those commands may be put into a gdb macro command for ease of use. |