0

抱歉,我无法具体说明代码,但我看到的问题是异常的。字符串值似乎会根据其他不相关的代码而改变。例如,下面传递的参数的值将仅根据我是否注释掉一两个 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);
}

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

帮助!蒂亚!

4

4 回答 4

6

简单的:

  1. 学习使用Valgrind,特别是memcheck
  2. 学习使用GDB,包括断点和变量检查
  3. 熟能生巧。

那应该排序它。确保您使用 GCC 上的选项编译任何库,该-g选项会保留调试符号,以便您的调试输出更有意义。

于 2010-05-17T03:24:20.667 回答
2

有两种情况需要考虑:

  1. 变量在的arg开始和结束之间改变值process_args
  2. arg保持不变,但它指向的字符串已更改。

您的描述和您的代码并没有区分两者,但重要的是要知道两者中的哪一个实际发生。

这将揭示答案:

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. 当有东西写入时 GDB 将停止*arg(它实际上会在下一条指令时停止)。然后使用(gdb) where命令找出发生了什么。

如果您确实arg更改了它的值(案例 1),那可能更难调试,并表明某种堆栈损坏,或者违反了您平台的过程调用约定。Valgrind 可能对此毫无帮助。这与您描述的行为更一致:注释掉不相关的代码会导致错误发生变化。

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

于 2010-05-17T03:57:14.597 回答
1

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

于 2010-05-17T03:32:50.103 回答
0

您没有提供开发工具,但如果您像 90% 的编码人员一样,您已经在使用带有调试器的 IDE,可以处理此问题,无需新工具。在保存字符串的内存块上设置监视,然后单步执行代码并查看字符串何时更改。

于 2010-05-17T03:35:40.623 回答