使用gdb

时间:2016-01-18 00:19:28

标签: c string segmentation-fault gdb

我有一小段代码,它将换行符分隔的单词作为输入,并作为输出吐出(word,1)。这是代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char *argv[]) {
    char *str1, *str2, *token;
    char *saveptr1;
    char buffer[100];
    while (fgets(buffer, sizeof(buffer), stdin) != NULL) {
        token = strtok_r(buffer, '\n', &saveptr1);
        printf("(%s,1)\n", token);
    } 
    exit(EXIT_SUCCESS);
}

此代码正常工作并提供预期的输出。但是,当我使用gdb单步执行代码时,我在第9行得到以下错误:strtok_r行。

  

编程接收信号SIGSEGV,分段故障。   strtok_r()at ../sysdeps/x86_64/strtok.S:101   101 ../sysdeps/x86_64/strtok.S:没有这样的文件或目录。

这令人费解。我甚至没有&#34;踩到&#34; strtok_r行,我只是&#34; nexting&#34;它,即踩过来。为什么在GDB期间抛出此错误?我很焦虑,因为我有一个真实的,更大的程序,我无法调试因为这个问题。实际上,对于大多数所有字符串函数(strncmpstrncpy)都会出现此问题。

编辑:编译器确实警告过一个赋值来自整数而没有在此行进行强制转换,我应该将2和2放在一起。

1 个答案:

答案 0 :(得分:1)

您将字符文字而不是字符串文字传递给strtok_r,库函数strtok_r崩溃尝试取消引用无效指针。

GDB尝试显示位于strtok_r的{​​{1}}的程序集源代码(它从标准C库调试信息中知道这一点),但它无法在该位置找到源文件。

您当然应该以这种方式纠正代码:

../sysdeps/x86_64/strtok.S

最好使用token = strtok_r(buffer, "\n", &saveptr1); 从编译器启用尽可能多的警告并修复代码,直到编译器不再检测到任何可疑代码为止。

事实上,您提到使用-Wall -Wextra -Werror:此功能非常容易出错。它没有做大多数人的想法,它永远不是正确的工具。阅读相关文档并仔细验证是否正确使用它,以及在这些地方没有更好的替代方案。