繁体   English   中英

为什么在string.h函数中发生段错误?

[英]Why segfaults occur with string.h functions?

在同事的PC中使用相同的命令,我的程序可以正常工作。 但是在我的电脑上,该程序因段错误而崩溃;

核心的GDB回溯记录如下:

#0 strrchr () at ../sysdeps/x86_64/strrchr.S:32
32     ../sysdeps/x86_64/strrchr.S: no such file or directory
(gdb) bt
#0 strrchr () at ../sysdeps/x86_64/strrchr.S:32
#1 0x00007f10961236d7 in dirname (path=0x324a47a0 <error: Cannot access memory at address 0x324a47a0>) at dirname.c:31

我已经使用-g -ggdb选项编译了可执行文件。

奇怪的是,使用valgrind程序也可以在我的PC中正常运行。

我该如何解决这个问题? 我观察到错误仅在strrchr,strcmp,strlen,... string.h函数中发生。

+编辑:gdb backtrace指示程序在此处崩溃:

char* base_dir = dirname(get_abs_name(test_dir));

其中get_abs_name定义为

char* get_abs_name(char* dir) {
    char abs_path[PATH_MAX];
    char* c = malloc(PATH_MAX*sizeof(char));
    realpath(dir, abs_path);
    strcpy(c, abs_path);
    return c;
}

+ Edit2:“ dir”是某些文件的路径,例如“ ../program/blabla.jpg”。

使用valgrind

printf("%s\n", dir)

通常会打印“ / home / frozenca / path_to_program”。 我猜不出为什么没有valgrind程序就会崩溃..

没有最小,完整和可验证的示例,我们无法确定。 您的代码看起来大部分都是正确的(尽管很复杂),除非您不检查错误。

char* get_abs_name(char* dir) {
    char abs_path[PATH_MAX];
    char* c = malloc(PATH_MAX*sizeof(char));  /* this may return NULL */
    realpath(dir, abs_path);                  /* this may return NULL */
    strcpy(c, abs_path);
    return c;
}

现在,这怎么会导致您看到的错误? 好吧,如果malloc返回NULL,则立即在strcpy崩溃。 但是,如果realpath失败:

  • abs_path的内容仍未定义。
  • 因此strcpy(c, abs_path)将复制未定义的内容。 如果abs_path[0]恰好是\\0这可能导致它仅复制一个字节。 但也可能导致大量堆损坏。 发生哪种情况取决于不相关的条件,例如程序的编译方式以及是否连接了诸如valgrind之类的调试工具

TL; DR:养成检查可能失败的每个功能的习惯。

char* get_abs_name(char* dir) {
    char abs_path[PATH_MAX];
    char* c = malloc(PATH_MAX*sizeof(char));
    if (!c) { return NULL; }
    if (!realpath(dir, abs_path)) {
        free(c);
        return NULL;
    }
    strcpy(c, abs_path);
    return c;
}

或者,在这里,您可以在假设使用GNU系统或POSIX.1-2008系统的情况下对其进行简化:

char * get_abs_name(const char * dir) {
    return realpath(dir, NULL);
}

但是请注意,无论哪种方式,在主程序中,还必须检查get_abs_name()不返回NULL,否则dirname()会崩溃。

完全删除函数,而使用realpath(dir, NULL)的返回值。

转换类型

char* c = malloc(PATH_MAX*sizeof(char));

谢谢!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM