空函数的计算器

stackoverflow for empty function

看看这段代码:

void f()
{
    f();
}

我知道因为调用了这么多f()函数,所以出现了Whosebug。 但我的问题是导致此错误的堆栈中到底存储了什么,每个 f() 函数调用的 return 地址? 因为这个函数没有变量,所以为什么会出现Whosebug?

对于每个被调用的函数,堆栈存储其return地址,以便在函数returns时在下一条指令处恢复执行。这是 call stack.

正如其他答案所说,这是因为 return 地址。

void f(){
  f();
}

编译为

f:
  call f #Let's assume f has the address 0x1000 for later purposes
  ret

但是 call 有什么作用呢? 它做了两件事:

  1. 将当前地址压入堆栈
  2. 呼叫指定地址。 它本质上是:
f:
  push %rip
  jmp 0x1000
  ret

如果您“展开”此调用,您将拥有:

f:
  push %rip
  push %rip
  push %rip
  push %rip
  push %rip
  push %rip
  ....

等等。如您所见,您总是将一个地址压入堆栈。这一直有效,直到您点击其他区域并覆盖它们。 (此图假定架构具有 backwards-growing 堆栈,例如 x86)

[heap].......[stack pointer][stack] #Start
[heap]......[stack pointer][stack ] push %rip
[heap].....[stack pointer][stack  ] push %rip
[heap]....[stack pointer][stack   ] push %rip
[heap]...[stack pointer][stack    ] push %rip
[heap]..[stack pointer][stack     ] push %rip
[heap].[stack pointer][stack      ] push %rip
[heap][stack pointer][stack       ] push %rip
[heap[stack pointer][stack        ]# Boom, you for example reached the heap and you are overwriting it.