c - 如果我在 C 中取消引用非法地址,我会得到带有有效 gdb 回溯的 SIGSEGV。但是如果我将它传递给 snprintf backtrace 就会被丢弃

标签 c segmentation-fault x86-64 backtrace

在我的 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.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会帮助你得到真正的答案。

关于c - 如果我在 C 中取消引用非法地址,我会得到带有有效 gdb 回溯的 SIGSEGV。但是如果我将它传递给 snprintf backtrace 就会被丢弃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62295256/

相关文章:

c - 基本的,关于说明符

objective-c - 在 C 和 Objective-C 中,我们应该使用 0.5f 还是 0.5?

c - 段错误: Reading values from a text file

c - x86_64 linux 上 C 程序中的内联汇编

c - 程序输出值而不初始引用变量(牛和牛)

c - 指向一维数组的双指针

ios - 应用程序被 SIGSEGV 终止

c - MPI 段错误(信号 11)

assembly - 由于从越界内存中跳过 cmov,难以调试 SEGV

linux - 通过 linux x86-64 函数调用保留了哪些寄存器