如果我在C语言中取消引用一个非法地址,我得到SIGSEGV和有效的gdb回溯。但如果我把它传给Snprintf,回溯就会被销毁

问题描述 投票:4回答:1

在我的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.

c segmentation-fault x86-64 backtrace
1个回答
2
投票

进程还是会崩溃,但是回溯是垃圾的。

当我建立这个测试时。

#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.0GNU 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 会对你得到真正的答案有很大的帮助。

© www.soinside.com 2019 - 2024. All rights reserved.