在我的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 ?? ()
我的例子可能看起来很复杂,但我的生产代码在gdb中崩溃了 snprintf()
以完全相同的方式。我已经用 -g -O0
.
进程还是会崩溃,但是回溯是垃圾的。
当我建立这个测试时。
#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 会对你得到真正的答案有很大的帮助。