大家好,调试 C语言代码一定要懂得汇编吗? 我用的是VC编译器!我发现在运行调试的时候如果出现运行时错误,VC都会跳转到一段汇编代码中, 例如调试下面这段代码:int changeit(char a[]);
main(){
char a[]="test it";
changeit(a);
}
int changeit(char a[]){
int i;
int len=strlen(a);
for(i=0;i<len;i++){
printf("%s",a[i]);
}
return 0;
}
我编译通过,运行时候出现错误:“0xMMMMMMMM 引用的 0xMMMMMM 内存,该内存不能为read.”然后VC跳转到以下代码中定位了:00402302   test        edx,edx
00402304   je          $L1748+0FEh (00402324)
00402306   mov         ecx,dword ptr [p]
0040230C   movsx       edx,byte ptr [ecx] <------------------ //箭头指向这里!
0040230F   test        edx,edx
00402311   je          $L1748+0FEh (00402324)
00402313   mov         eax,dword ptr [p]用 VC调试必须懂汇编吗? 如果出现上面的情况怎么解决,怎样找出代码的问题呢?为什么VC不会定位到程序里面出错的地方,而定位到汇编里面,难于调试。 好像 VC里面不能加例如log这种日志信息,这样我根本不知道程序执行到哪里出的错误,大家都是怎么解决的?有没有让VC打印Log的方法跟踪程序啊?

解决方案 »

  1.   

    #include <iostream> using namespace std; 
    int changeit(char a[]);
    void main(){
    char a[]="test it";
    changeit(a);
    }
    int changeit(char a[]){
    int i;
    int len=strlen(a);
    for(i=0;i<len;i++){
    printf("%c",a[i]); ========================跟vc没有什么关系,你的程序写错了。
    }
    return 0;
    }
    不要懂汇编,但是你要对编译器比较熟悉,其实是可以看到代码在哪里调用的时候出错的,在函数的调用堆栈找到你调用的函数语句,双击就到出错的地方了。
      

  2.   

    你说的是在 Disassembly的那个窗口,鼠标移动到 movsx地方双击吗?没有反映啊
    我点击调试悬浮小窗口里面的 Call Stack按钮,显示调用栈代码,不知道你说得是不是这个? 里面的代码为:_output(_iobuf * 0x0040d088, const char * 0x0040c026, char * 0x0012fecc) line 677 + 31 bytes
    printf(const char * 0x0040c024 `string') line 60 + 18 bytes
    changeit(char * 0x0012ff78) line 15 + 20 bytes
    main() line 9 + 9 bytes
    mainCRTStartup() line 206 + 25 bytes
    KERNEL32! 77e889d5()
    箭头指向 -->_output(_iobuf * 0x0040d088, const char * 0x0040c026, char * 0x0012fecc),而调用_output的就是我的代码printf,但是怎么知道我的printf哪里有错误呢?比如空指针什么的?
      

  3.   

    一般在进入printf之前设置断点,看看传进去得参数有没有问题,到汇编得时候再看已经太晚了,除非你对汇编非常之精通
      

  4.   

    我在调试窗口的Auto的Context里面,看这些变量的值也没有问题:
     a[i]  116 't'
     i     0
     len   7
    但是不知道怎么看第二次循环
      

  5.   

    你得错误不是变量值,而是%c写成%s,%s要求后面是一个字符串指针,而你a[i]是一个字符
    把一个字符当指针使,当然错上天了
    你都不仔细看人家给你得答复,1楼都用箭头给你标出来了
      

  6.   

    我主要不理解VC 他根本没有报错说是我代码输出格式的问题“printf("%c"...)”
    而直接报错说 内存不能为read,应该在哪里怎么看到详细的出错信息呢? 而不是根据语法认为的判断?
      

  7.   

    报错的地方往往都不是导致错误的地方,这在调试过程中总是这样,不仅仅是vc。指望看到详细的出错信息,这在真正的研发中
    时绝对不可能的。你出错的原因是把字符当指针,这样你在访问这个伪指针时就访问到非法的地址,自然会导致内存不能为read错误。所以我不是建议你不要在出错的地方跟,那儿已经太晚了,你需要在出错的上一级函数,甚至上很多级函数前设置断点,在错误真正被触发前找到出错的原因。这是debug最头疼也最常见的事情,调试比开发麻烦1万倍都不止,是真正体现技术的地方。学语言对它就如同幼儿园对大学一样。
      

  8.   

    这在java也一样,除非你写的代码太简单,否则调试都需要耐心细心加经验的