首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

M$VC 调试器一个奇怪的BUG解决方法

2012-03-22 
M$VC 调试器一个奇怪的BUG在 VC6 和VS2K5 上试过, 其他版本没试过, 不过可能还是这样子...#include stdio

M$VC 调试器一个奇怪的BUG
在 VC6 和VS2K5 上试过, 其他版本没试过, 不过可能还是这样子...

#include <stdio.h>

int main()
{
printf( "Hello World!\n" );
__asm int 3;
printf( "Hello World!\n" );
__asm _emit 0CDH;
__asm _emit 03H ;
printf( "Hello World!\n" );
return 0;
}

为什么 CD 03 被M$当成单字节指令了. 这个是比较蛋疼, 为啥米不用 CC 要用 CD 03 , 搞不懂nasm弄的啥飞机...

这个帖子有好点的结果了一起领分: http://topic.csdn.net/u/20110721/03/b85d4dda-0579-4972-9b61-ef0187380726.html
等一周没啥结果就大家平分...




[解决办法]
yasm试试?
[解决办法]
这个和nasm啥关系?VC用的不是masm么?
[解决办法]

探讨

nasm 会把 int 3 汇编成 CD 03 然后我才发现了M$VC的这个BUG.
masm 应该没有问题, 不过masm的语法太难看了, 没有试.
我这 yasm 也很悲剧的汇编成了 CD 03 .

版本是 :
NASM version 2.02 compiled on Feb 19 2008
yasm 1.1.0.2352

[解决办法]
jf
[解决办法]
探讨

用gdb试了下, gdb 没出这个毛病...

[解决办法]
2010的结果:
C/C++ code
     6: __asm int 3;0110102B CC                   int         3       7: printf( "Hello World!\n" );0110102C 8B F4                mov         esi,esp  0110102E 68 10 70 10 01       push        offset _RTC_ErrorLevels-28h (1107010h)  01101033 FF 15 D4 82 10 01    call        dword ptr [__imp__printf (11082D4h)]  01101039 83 C4 04             add         esp,4  0110103C 3B F4                cmp         esi,esp  0110103E E8 4D 00 00 00       call        _RTC_CheckEsp (1101090h)       8: __asm _emit 0CDH;01101043 CD 03                int         3
[解决办法]
很奇怪啊,直接给合并了
[解决办法]
探讨

直接手写汇编给 2010 调试试试, 我这没 2010 , 没法试...

[解决办法]
探讨

2010显示的汇编没问题, __asm _emit CD ; _emit 03 就应该是 int 3 ... 看调试结果会不会飞...

[解决办法]
探讨
2010显示的汇编没问题, __asm _emit CD ; _emit 03 就应该是 int 3 ... 看调试结果会不会飞...

[解决办法]
探讨

你试试看这个, 这个应该可以在 2010 下跑..

#include <stdio.h>

void __fastcall foobar( void )
{
printf( "Hello World!\n" );
}

int __declspec(naked) main()
{__asm {
push edi;
mov edi , offset foobar ;
……

[解决办法]
探讨

引用:
反汇编是

这个不用反汇编, 这个本来就已经是汇编了, 你调试看看, 是不是会飞掉....

[解决办法]
探讨

引用:

引用:
反汇编是

这个不用反汇编, 这个本来就已经是汇编了, 你调试看看, 是不是会飞掉....

我不懂什么叫飞……
遇到int 3就停了啊

[解决办法]
探讨

引用:



引用:

引用:
反汇编是

这个不用反汇编, 这个本来就已经是汇编了, 你调试看看, 是不是会飞掉....

我不懂什么叫飞……
遇到int 3就停了啊

到crtexe.c有异常出现


[解决办法]
探讨

停了你就按 F10 继续跑, 最后就会跑到不知道啥地方去...
比如上面给你的代码, 本来 foobar 地址是 0x0040100a , 结果运行

CD 03
call edi

后, edi 的结果成了 0x00802014 , 然后 call edi 就运行到 0x00802014 去了, 这个地方就谁都不知道是个啥了...

[解决办法]
探讨

不是最后一个, 是倒数第二个, 你应该是在 call stack 里看是最后一个.
你的也应该是输出两个 Hello World! 吧.
用 gdb 调试应该会输出 4 个 Hello World!

[解决办法]
那你可以去微软MSDN报告了
[解决办法]
探讨
引用:

引用:
2010显示的汇编没问题, __asm _emit CD ; _emit 03 就应该是 int 3 ... 看调试结果会不会飞...

这应该很正常的,vc编译器在反汇编窗口内,会自作主张的从内存里的数据翻译成对应的汇编执行令,
这些内存可能是数据段的内存,vc也经常反汇编成一些让人哭笑不……

[解决办法]
2010break 后反汇编
Assembly code
  1628: int __declspec(naked) main()  1629: {__asm {  1630:     push edi;01171420 57                   push        edi    1631:     mov edi , offset foobar ;01171421 BF 1E 10 17 01       mov         edi,offset foobar (117101Eh)    1632:     call edi;01171426 FF D7                call        edi    1633:     _emit 0CCH ;01171428 CC                   int         3    1634:     call edi;01171429 FF D7                call        edi    1635:     _emit 0CDH ;0117142B CD                   db          cdh    1636:     _emit 03H ;0117142C 03 FF                add         edi,edi  0117142E D7                   xlat        byte ptr [ebx]    1638:     call edi;0117142F FF D7                call        edi    1639:     call edi;01171431 FF D7                call        edi    1640:     pop edi;01171433 5F                   pop         edi    1641:     ret01171434 C3                   ret
[解决办法]
INT 3指令有两种形式,一种是0xcc 一种是0xcd 0x03,其中第二种是INT n的标准形式。 0xCC是特别针对breakpoint优化的。可以查看Intel Instruction Set Reference第二卷.

Opcode Instruction Description
CC INT 3 Interrupt 3—trap to debugger
CD ib INT imm8 Interrupt vector number specified by immediate byte

The INT 3 instruction generates a special one byte opcode (CC) that is intended for calling the debug exception handler. (This one byte form is valuable because it can be used to replace the first byte of any instruction with a breakpoint, including other one byte instructions, without over-writing other code). To further support its function as a debug breakpoint, the interrupt generated with the CC opcode also differs from the regular software interrupts as follows:
? Interrupt redirection does not happen when in VME mode; the interrupt is handled by a
protected-mode handler.
? The virtual-8086 mode IOPL checks do not occur. The interrupt is taken without faulting at
any IOPL level.

Note that the “normal” 2-byte opcode for INT 3 (CD03) does not have these special features.
Intel and Microsoft assemblers will not generate the CD03 opcode from any mnemonic, but this
opcode can be created by direct numeric code definition or by self-modifying code.

注意到最后一段特别提到intel和ms的汇编引擎不会生成CD03的操作码。
所以,这个问题可以认为是MS的bug吧~~
[解决办法]
楼主参考一下这个
VC++内联汇编(MSDN相关内容完整翻译)
[解决办法]


探讨

看了楼上的, 偶越来越感觉这个是M$故意留下来的BUG, 他们可能自己也用这玩意ANTI-DEBUG. 不过这只能阻止 M$VC 调试啊, 我试了 gdb / ida 都没这个问题...

[解决办法]
cout<<"abc"<<"xxx"<<"sss"<<"sss";
把这种一连串的 <<翻成 operator<<(operator<<)这样的函数调用来写,写着写着,能把vc2005弄崩了。
[解决办法]
探讨

cout<<"abc"<<"xxx"<<"sss"<<"sss";
把这种一连串的 <<翻成 operator<<(operator<<)这样的函数调用来写,写着写着,能把vc2005弄崩了。

[解决办法]
顶顶更健康~
[解决办法]
这个bug在《软件调试》里面有提到过 确实是VC编译器的BUG
[解决办法]
可惜我只装了VC++2010的编译器和库,没装IDE,验证不了。不过用TD调试嵌入CD 03指令的exe是没有问题的。

[解决办法]
vs2008跑挂了,但是指向了第一条int 3指令。不是后面的__asm _emit 0CDH;
__asm _emit 03H ;

热点排行