如何调试异常C内存/堆栈问题

时间:2010-05-17 03:21:04

标签: c memory stack alloc

抱歉,我不能具体说明代码,但我看到的问题是异常的。字符串值似乎正在根据其他不相关的代码进行更改。例如,下面传递的参数值只会根据我是否注释掉一个或两个fprintf()调用而改变!通过最后一个fprintf(),该值通常是完全空的(不,我已经检查以确保我没有直接修改参数...我所要做的就是注释掉fprintf()或添加另一个fprintf()并且字符串的值将在某些点发生变化!):

static process_args(char *arg) {
    /* debug */
    fprintf(stderr, "Function arg is %s\n", arg);

    ...do a bunch of stuff including call another function that uses alloc()...

    /* debug */
    fprintf(stderr, "Function arg is now %s\n", arg);    
}

int main(int argc, char *argv[]) {
    char *my_arg;

    ... do a bunch of stuff ...

    /* just to show you it's nothing to do with the argv array */
    my_string = strdup(argv[1]);

    /* debug */
    fprintf(stderr, "Argument 1 is %s\n", my_string);

    process_args(my_string);
}

周围有更多的代码,所以我不能要求有人调试我的程序 - 我想知道的是我如何调试为什么这样的字符串会根据不相关的代码更改或覆盖内存。我的记忆有限吗?我的堆栈太小了?我怎么说?我还能做些什么来追查这个问题?我的程序不是很大,就像一千行代码给出或接受一对动态链接的外部库,但没有什么不寻常的。

HELP! TIA!

4 个答案:

答案 0 :(得分:6)

简单:

  1. 学习使用 Valgrind ,特别是memcheck
  2. 学习使用 GDB ,包括断点和变量检查
  3. 练习变得完美。
  4. 那应该排序。确保在GCC上使用-g选项编译任何库,这样可以保持调试符号,从而使调试输出更有意义。

答案 1 :(得分:2)

有两种情况需要考虑:

  1. arg变量会在process_args的开头和结尾之间更改值。
  2. arg保持不变,但指向的字符串会发生变化。
  3. 您的描述和代码不区分这两者,但重要的是要知道这两者中的哪一个实际发生。

    这将揭示答案:

    fprintf(stderr, "Function arg is %s (%p)\n", arg, (void *)arg);
    ... do bunch of stuff ...
    fprintf(stderr, "Function arg is now %s (%p)\n", arg, (void *)arg);
    

    大多数时候arg没有变化(即你有案例2)。如果是这样,有些东西会破坏你分配的字符串。 Valgrind已经建议,但只能在Linux,AIX和MacOSX上使用,只有50:50的机会找到问题。你真正想要的是GDB观察点:在process_args开始时设置断点,一旦点击,执行(gdb) watch *(long*)argcontinue。当某些内容写入*arg时,GDB将停止(它将在下一条指令上停止)。然后使用(gdb) where命令找出正在发生的事情。

    如果您确实arg更改了其值(案例1),则可能更难调试,并指示某种堆栈损坏,或违反您的平台的过程调用约定。 Valgrind可能完全没有帮助。这与您描述的行为更加一致:注释掉不相关的代码会导致错误发生变化。

    我无法就调试案例1提供任何进一步的建议,因为您尚未透露您的实际平台是什么。

答案 2 :(得分:1)

如果您正在编写用户级应用程序,Valgrind是检测内存泄漏,缓冲区溢出等内存问题的不错选择。以下是快速入门指南:http://valgrind.org/docs/manual/QuickStart.html

答案 3 :(得分:0)

你没有给你的开发工具,但如果你像90%的编码器那样你已经在使用带有可以处理这个问题的调试器的IDE,那么就不需要新的工具了。在持有字符串的内存块上设置监视,然后单步执行代码并查看字符串何时更改。