【问题标题】:fsantize=address worked well but segmentation fault persisted after fixing the bug : C programmingfsantize=address 运行良好,但修复错误后分段错误仍然存​​在:C 编程
【发布时间】:2023-01-19 13:52:58
【问题描述】:

下面是当我在使用 gcc 构建时最初没有使用 fsanitize=address 时出现分段错误的堆栈跟踪。当我通过查看下面的跟踪详细信息来查看代码时,我没有在行号为convert_text (string=0x1a50276 "TESTER233", size=10) at caomenu.pc:12795的代码中发现任何错误

#0  0x00007ffff34bea9f in raise () from /lib64/libc.so.6
#1  0x00007ffff3491e05 in abort () from /lib64/libc.so.6
#2  0x00007ffff3501047 in __libc_message () from /lib64/libc.so.6
#3  0x00007ffff350819c in malloc_printerr () from /lib64/libc.so.6
#4  0x00007ffff350844c in munmap_chunk () from /lib64/libc.so.6
#5  0x00007ffff34f72e5 in fclose@@GLIBC_2.2.5 () from /lib64/libc.so.6
#6  0x000000000047337e in WriteTrace (cEntryText=0x488d73 "Running convert_text") at caomenu.pc:18426
#7  0x000000000045014a in convert_text (string=0x1a50276 "TESTER233", size=10) at caomenu.pc:12795
#8  0x0000000000450cca in load_user_data () at caomenu.pc:12922
#9  0x00000000004500c1 in display_user_security () at caomenu.pc:12772
#10 0x0000000000403862 in menu1 () at caomenu.pc:993
#11 0x00000000004017fa in main (ac=2, av=0x7fffffffe208) at caomenu.pc:562

下面是我用来跟踪发生的分段错误时的堆栈跟踪。这次使用了带有 gcc 的 -fsanitize=address 并构建了它。

gcc -fsanitize=address -g -o scrmenu caomenu.c superbox.c 

这给了我堆栈跟踪,它表示确切的行号 (at caomenu.pc:13169),如下所示,代码中有错误。

(gdb) bt
#0  0x0000000000500cad in process_user_security () at caomenu.pc:13169
#1  0x00000000004fb291 in display_user_security () at caomenu.pc:12780
#2  0x000000000040732f in menu1 () at caomenu.pc:993
#3  0x0000000000402ed8 in main (ac=2, av=0x7fffffffe208) at caomenu.pc:562
(gdb)

在第 13169 行,以下是试图访问未初始化指针的语句,因为 commline 被声明为整数。但是之前没有初始化这个语句。

orCommodity[commline].commnum = 0; 

在检查代码并用零 (int commline=0;) 初始化 commline 之后,代码被优雅地执行,没有任何分段错误。

所以,我得出一个结论,未初始化 commline 是整个问题的罪魁祸首。所以我再次在没有 fsanitize=address 的情况下运行代码,并预计这次它会给出任何分段错误。但令我惊讶的是,它再次抛出与上面第一个场景中所示相同的行 (caomenu.pc:12795)。所以我一直在敲我的头,如果不初始化 commline (int commline;) 是真正的罪魁祸首,它应该在代码中修复后顺利运行。但我在 stck 跟踪中得到了相同的行 12795,这不是越野车。如果有这方面的专家,可以对此有所了解。

【问题讨论】:

  • 你有另一个错误。更多代码可能会有所帮助。
  • 您的代码中很可能存在错误,例如写入已释放的内存、覆盖缓冲区或导致未定义行为的类似问题。这就是我们在没有看到您的任何代码的情况下可以说的全部内容。
  • 任何不合格的编译器都应该警告您不要使用未初始化的变量。 -Wall -Wextra -pedantic-errors。少用头撞墙,多解决编译器已经发现并向您指出的错误 :)
  • -fsanitize=address 无法捕获所有错误。 valgrind 可以抓到更多。 (这是数学上不可能一个自动化的工具来捕捉全部错误:<en.wikipedia.org/wiki/Rice%27s_theorem>.)
  • 笔记:“程序测试可以用来显示错误的存在,但绝不能证明它们不存在!”

标签: c debugging gcc gdb


【解决方案1】:

下面是代码。堆栈跟踪表明 fclose(Tracefile) 的某些问题;

我的观察是,该程序能够显示多达 146 条记录,有时显示 151 条记录,然后在此行 (fclose(TrcFile); ) 出现分段错误。不确定出了什么问题以及如何准确解决这个问题。

void WriteTrace( char *cEntryText ) {

    char cTimeStamp[40];                         /* time stamp variable */
    char cTimeFormat[]="%H:%M:%S: ";             /* time stamp format */

    GetTimeStamp( &cTimeStamp[0], sizeof(cTimeStamp), &cTimeFormat[0] );
    TrcFile = fopen( cTraceFile, cTrcOpenFlag ); /* open the file */
    cTrcOpenFlag[0] = 'a';                       /* after first, always app} */
    fprintf(TrcFile, "%s",   cTimeStamp);        /* write the time stamp */
    fprintf(TrcFile, "%s
", cEntryText);        /* write the entry */
    fclose(TrcFile);                             /* close the trace file */
    return;                                      /* return to caller */
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多