在我的 x86-64 Linux 程序中,我故意这样做:
char *ptr = 0x3e8;
int x = *(int *)ptr;
当我在 gdb 中运行它时,进程因 SIGSEGV 而崩溃并打印有效的回溯。如果我这样做:
char s[16];
snprintf(s, 16, "%s\n", ptr);
该过程仍然崩溃,但回溯是垃圾:
(gdb) bt
#0 0x00007ffff5da15c7 in ?? ()
#1 0x00007ffff5c704d3 in ?? ()
#2 0x0000000000000000 in ?? ()
我的示例可能看起来很人为,但我的生产代码在
snprintf()
中崩溃了以完全相同的方式。我用 -g -O0
编译.
最佳答案
The process still crashes but the backtrace is trash
当我构建此测试时:
#include <stdio.h>
int main()
{
char *ptr = (char *)0x3e8;
char s[16];
snprintf(s, 16, "%s\n", ptr);
return 0;
}
使用
gcc (Debian 9.3.0-3) 9.3.0
和 GNU C Library (Debian GLIBC 2.30-4) stable release version 2.30.
, 与 libc6-dbg
安装,我得到:Program received signal SIGSEGV, Segmentation fault.
__strlen_avx2 () at ../sysdeps/x86_64/multiarch/strlen-avx2.S:96
96 ../sysdeps/x86_64/multiarch/strlen-avx2.S: No such file or directory.
(gdb) bt
#0 __strlen_avx2 () at ../sysdeps/x86_64/multiarch/strlen-avx2.S:96
#1 0x00007ffff7e48756 in __vfprintf_internal (s=s@entry=0x7fffffffd8b0, format=format@entry=0x555555556004 "%s\n", ap=ap@entry=0x7fffffffda30, mode_flags=mode_flags@entry=0) at vfprintf-internal.c:1688
#2 0x00007ffff7e5a1f6 in __vsnprintf_internal (string=0x7fffffffdb10 "", maxlen=<optimized out>, format=0x555555556004 "%s\n", args=args@entry=0x7fffffffda30, mode_flags=mode_flags@entry=0) at vsnprintf.c:114
#3 0x00007ffff7e335a2 in __GI___snprintf (s=<optimized out>, maxlen=<optimized out>, format=<optimized out>) at snprintf.c:31
#4 0x0000555555555169 in main () at t.c:7
我怀疑您会在标准 x86 Ubuntu 18.04 上从这个测试用例中得到类似的结果,在这种情况下,您并没有告诉我们整个故事,而是 MCVE会帮助你得到真正的答案。
关于c - 如果我在 C 中取消引用非法地址,我会得到带有有效 gdb 回溯的 SIGSEGV。但是如果我将它传递给 snprintf backtrace 就会被丢弃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62295256/