如果我在C中取消引用一个非法地址,我会得到带有有效gdb回溯的SIGSEGV。但如果我把它传给snprintf,回溯就会被破坏

如果我在C中取消引用一个非法地址,我会得到带有有效gdb回溯的SIGSEGV。但如果我把它传给snprintf,回溯就会被破坏,c,segmentation-fault,x86-64,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 0x00007FF5DA15C7英寸??() #1 0x00007FF5C704D3英寸??() #2 0x000000000

在我的x86-64 Linux程序中,我故意执行以下操作:

char *ptr = 0x3e8;
int x = *(int *)ptr;
当我在gdb中运行它时,进程由于SIGSEGV而崩溃,并打印一个有效的回溯。如果我这样做:

char s[16]; 
snprintf(s, 16, "%s\n", ptr);
进程仍然崩溃,但回溯是垃圾:

(gdb)bt
#0 0x00007FF5DA15C7英寸??()
#1 0x00007FF5C704D3英寸??()
#2 0x0000000000000000英寸??()
我的示例可能看起来有些做作,但我的生产代码在
snprintf()
中以完全相同的方式崩溃。我用
-g-O0
编译过

进程仍然崩溃,但回溯是垃圾

当我构建此测试时:

#include <stdio.h>

int main()
{
  char *ptr = (char *)0x3e8;
  char s[16];
  snprintf(s, 16, "%s\n", ptr);
  return 0;
}

我怀疑在标准的x86 Ubuntu 18.04上,您可能会从这个测试用例中得到类似的结果,在这种情况下,您没有告诉我们全部情况,而an将有助于您获得真正的答案。

可能snprintf没有设置调试程序可以识别的堆栈框架,因为它不是用-O0编译的。Gdb不应该这样做“croak”当程序有一个bug,这会使它成为一个毫无用处的调试器。这不是UB吗?这段代码可能会在审判日结束。是的,但问题更多的是“为什么
gdb
在第二种情况下像这样,而不是在第一种情况下?”@TanveerBadar Pet peeve:说未定义的行为会让恶魔飞出你的鼻子或其他任何愚蠢的结果都没有错,但别忘了这样的说法是一种修辞手段。这不是现实。这是一个很好的方法,可以教人们不要依赖未定义的行为来做出可预测的行为。当有人想Ts深入挖掘并了解真实世界中实际发生的事情。调试通常使我们从效果到因果关系。我们可以了解一些可能导致的原因和影响。你是对的。我注意到的这个更大的程序是我修改了很多的HoSTAPD(与C++原Bug库等链接)。。我对未修改的hostapd进行了相同的测试,发现堆栈跟踪良好。因此,我要做的是删除我一次添加一个的部分,并查看问题何时开始发生
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