【问题标题】:segfault in vfprintf with corrupted stackvfprintf 中的段错误,堆栈损坏
【发布时间】:2020-09-10 13:09:16
【问题描述】:

我的核心是这样的:

(gdb) bt
#0  0x00007fe7bd2e3735 in vfprintf () from /lib64/libc.so.6
#1  0x00007fe7bd2ee329 in vfwprintf () from /lib64/libc.so.6
Backtrace stopped: previous frame inner to this frame (corrupt stack?)
(gdb) i frame
Stack level 0, frame at 0x7fe7b73e6e20:
 rip = 0x7fe7bd2e3735 in vfprintf; saved rip 0x7fe7bd2ee329
 called by frame at 0x1b
 Arglist at 0x7fe7b73e6e10, args:
 Locals at 0x7fe7b73e6e10, Previous frame's sp is 0x7fe7b73e6e20
 Saved registers:
  rbx at 0x7fe7b73e6de8, rbp at 0x7fe7b73e6e10, r12 at 0x7fe7b73e6df0, r13 at 0x7fe7b73e6df8, r14 at 0x7fe7b73e6e00, r15 at 0x7fe7b73e6e08, rip at 0x7fe7b73e6e18
(gdb)

是否有机会查找即将打印的内容,以便我可以在我的代码中找到它?

【问题讨论】:

  • 您未向我们展示的代码中一定存在错误。
  • valgrind 可能有助于缩小范围。我认为@Jabberwocky 是在要求您发布代码。
  • 反汇编 vfprintf 看看它使用了哪些寄存器?或者只是使用 vfprintf 编写一个玩具程序并反汇编调用站点
  • 调用这个标准函数的代码是有问题的。您将不得不花时间(很抱歉,可能需要很多时间)来跟踪代码中出现问题的位置。这很可能是堆栈的主要覆盖——代码将大量数据复制到堆栈分配的缓冲区太小,并且践踏破坏了堆栈回溯数据,但函数尚未返回。找到它可能会令人沮丧,并且报价可能一经找到就解决了。
  • 使用x/s $rsix/ws $rsi 查看第二个参数,*f*printf 应该是格式字符串。

标签: c gdb


【解决方案1】:

由于堆栈似乎已损坏,因此您无法查看此对 vsprintf 的调用来自代码的何处。

我建议你使用 gcc 标志 '-Wformat' and '-Wformat-overflow' 来编译你的代码,这是为了这个目的。

来自 gcc 文档 (https://gcc.gnu.org/onlinedocs/gcc-9.1.0/gcc/Warning-Options.html):

-Wformat 检查对 printf 和 scanf 等的调用,以确保提供的参数具有适合格式字符串的类型 指定的,以及格式字符串中指定的转换 有道理。 ...

-Wformat-overflow 警告对格式化输入/输出函数(如 sprintf 和 vsprintf)的调用可能会溢出 目标缓冲区。 ...

如果您的代码包含大量编译警告(忽略这是一个不好的做法),并且您只需要格式警告,则可以通过添加编译标志 -Werror=format -Werror=format-overflow

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-05-30
    • 1970-01-01
    • 1970-01-01
    • 2010-10-17
    • 2016-03-11
    • 2015-03-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多