Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to debug unaligned accesses on amd64 using Visual Studio?

I would like to debug and profile some 64-bit software performing unaligned accesses, like in the following example:

int foo[2] = { 1, 2 };
*((int *)((char *)foo + 2)) = 3;

The gcc way

I know of two ways to do so when using gcc and gdb. The first one is by enabling the aligned check bit (bit 18) in the eflags register, directly in my C or C++ code:

asm volatile("pushf \n"
             "pop %%rax \n"
             "or $0x40000, %%rax \n"
             "push %%rax \n"
             "popf \n" ::: "rax");

This is very handy because I can choose within the application itself whether to bypass unaligned access checks or not, for instance when calling known faulty libraries.

The other way is from gdb, at any moment while debugging the executable:

set $eflags |= 1<<18

Again, this can be enabled or disabled at will, scripted etc. Very handy.

Visual Studio

Now I have been totally unable to do the same using Visual Studio 2008 or 2010 on Vista64. Inline assembly in a C++ program is no longer available in x64 mode in any version of Visual Studio, but I can use intrinsics instead:

#include <intrin.h>
/* ... */
__writeeflags(__readeflags() | 0x40000);

This is exactly the same code as on Linux. It sort of works: I get the exception when my faulty code is run. Except the EFL.AC flag is reset to zero each time a breakpoint is hit. Which means I cannot properly debug a large application with lots of complicated breakpoints unless I litter the code with calls to my asm function.

So I tried to manually change EFL |= 0x40000 from the Visual Studio register debug session (which is exactly what I usually do on Linux). No effect either, the bit is set to zero as soon as I resume the debugging. Which means I cannot properly debug code for which I do not have the source code.

I don't understand what's going on here. Is it Visual Studio forcibly setting EFL.AC=0? If so, can I disable that "feature"? Also, is there a way to enable/disable EFL.AC during a debug session?

How do real world Windows developers track unaligned accesses in their code?

Edit: found out about __readeflags, which was not in the list of x64 intrinsics.

like image 700
sam hocevar Avatar asked Mar 31 '11 09:03

sam hocevar


1 Answers

Unfortunately when debugging the x64 debugger in VS clears the alignment check flag on any exception (including the one thrown to step into the debugger in the first place). Have you tried stepping through the code using windbg (a much more powerful windows debugger)? I haven't been able to try it with the AC flag but it should be simple with r efl= or directly from the registers window. If you don't have windbg installed, you can get it from the newest Windows SDK.

like image 129
Aaron Cook Avatar answered Nov 02 '22 12:11

Aaron Cook