给定堆栈和寄存器的状态,我们能否预测 printf 未定义行为的结果

2024-03-25

下面是一些用于课堂测验的简单 C 代码:

#include <stdio.h>

int main() {
  float a = 2.3;
  printf("%d\n", a);
  return 0;
}

编译并运行于:

苹果 LLVM 版本 6.1.0 (clang-602.0.53)(基于LLVM 3.6.0svn)
目标:x86_64-苹果达尔文14.5.0

这段代码的输出是undefined。我试图通过检查附近的内存来预测输出a使用调试器(Xgdb 中的命令)。例如,当地址为a is 0x7fff5fbffb98,那么上下文附近&a如下:

0x7fff5fbffb98: 1075000115
0x7fff5fbffb9c: 0
0x7fff5fbffba0: 1606417336
0x7fff5fbffba4: 32767
0x7fff5fbffba8: -1754266167
0x7fff5fbffbac: 32767
0x7fff5fbffbb0: -1754266167
0x7fff5fbffbb4: 32767

然后输出printf is 1606417352。我知道使用不正确的说明符时的输出是未定义的。出于好奇,我预计这种未定义行为的输出与运行堆栈或寄存器中的某些内存相关,但我还没有弄清楚如何将其关联起来。

那么使用哪个地址或寄存器来设置这个输出printf?换句话说,给定运行堆栈的状态以及所有寄存器中的所有值,我们是否可以预测(如果可以的话如何预测)这种未定义行为的输出?


你尝试使用%d for float:

d说明符用于有符号十进制整数

f说明符用于十进制浮点数

使用错误的说明符会导致未定义的行为 https://en.wikipedia.org/wiki/Undefined_behavior

您依赖于自动变量的地址:

我尝试通过查看附近的内存来预测输出

a是一个自动变量,每次编译代码时它的地址都会改变,因此每次编译代码时memory-near-a也会改变。

因此,“查看 a 附近的内存”也会导致未定义的行为。

解决方案:

你与未定义的行为无关(在本例中),所以忘记它以节省时间,它会让你的生活更轻松。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

给定堆栈和寄存器的状态,我们能否预测 printf 未定义行为的结果 的相关文章

随机推荐