1、下载Windbg。
2、编写如下代码:
#include <stdlib.h>
#include <stdio.h>
struct UK
{
union{
int k;
double v;
char n;
} kvn;
char * p;
};
void TestUK()
{
int i = 0;
i++;
printf("i=%d\n", i);
}
int main()
{
int size1 = sizeof(struct UK);
printf("size of struc UK = %d\n", size1);
int c = getchar();
printf("call TestUK");
TestUK();
return 0;
}
3、使用VS2010编译上面的代码。注意要关闭优化选项(已禁用 (/Od))
4、设置符号文件路径
5、打开可执行程序
6、打断点
打开可执行文件后,程序会自动暂停。显示如下信息:
在输入框中,输入x TestUnion!main
搜索main函数对应的内存地址。结果为
00f41030 TestUnion!main (void)
设断点
bp 00f41030
7、断点调试
输入 g 命令。运行代码。此时,代码停在main函数起始处。
输入 p 。可单步跟踪。
注:关闭优化的原因:打开优化后,编译器会优化对函数TestUK的调用。这样,x TestUnion!TestUK 就打不到地址了。
这是优化前后优化后的汇编代码
优化前
TestUnion!main:
00031030 55 push ebp
00031031 8bec mov ebp,esp
00031033 83ec08 sub esp,8
00031036 c745fc10000000 mov dword ptr [ebp-4],10h
0003103d 8b45fc mov eax,dword ptr [ebp-4]
00031040 50 push eax
00031041 68fc200300 push offset TestUnion!GS_ExceptionPointers+0x10 (000320fc)
00031046 ff15a4200300 call dword ptr [TestUnion!_imp__printf (000320a4)]
0003104c 83c408 add esp,8
0003104f ff159c200300 call dword ptr [TestUnion!_imp__getchar (0003209c)]
00031055 8945f8 mov dword ptr [ebp-8],eax
00031058 6814210300 push offset TestUnion!GS_ExceptionPointers+0x28 (00032114)
0003105d ff15a4200300 call dword ptr [TestUnion!_imp__printf (000320a4)]
00031063 83c404 add esp,4
00031066 e895ffffff call TestUnion!TestUK (00031000)
0003106b 33c0 xor eax,eax
0003106d 8be5 mov esp,ebp
0003106f 5d pop ebp
00031070 c3 ret
优化后
011e1002 35a4201e01 xor eax,offset TestUnion!_imp__printf (011e20a4)
011e1007 6a10 push 10h
011e1009 68fc201e01 push offset TestUnion!`string' (011e20fc)
011e100e ffd6 call esi
011e1010 ff159c201e01 call dword ptr [TestUnion!_imp__getchar (011e209c)]
011e1016 6814211e01 push offset TestUnion!`string' (011e2114)
011e101b ffd6 call esi
011e101d 6a01 push 1
011e101f 68f4201e01 push offset TestUnion!`string' (011e20f4)
011e1024 ffd6 call esi
011e1026 83c414 add esp,14h
011e1029 33c0 xor eax,eax
011e102b 5e pop esi
011e102c c3 ret
【1】 《Windows用户 态程序高效排错》