printf的论据不足 [英] printf insufficient arguments

查看:132
本文介绍了printf的论据不足的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的问题是有关与失踪的说法一个printf后的行为:

My question is about the behavior after a printf with a missing argument:

printf("%s blah blah %d", int); // integer was given as argument (and not int written)

我已经知道,如果有用于格式化参数不足,行为
不确定的。

I already know that if there are insufficient arguments for the format, the behavior is undefined.

问题是,它是否是未定义的printf的结果或对整个方案?

The question is whether it is undefined for the printf outcome or for the whole program?


  • 当%试过了未经授权的内存地址阅读崩溃可能发生。 (它发生在我身上)

  • 可以碰撞发生[长]与printf完成后? (印制一些垃圾字符串和一个整数)

编辑:

要澄清我不是问编译错误或警告,也不能执行这条线时,程序崩溃。可问题是,此线后随机已经执行该行程序崩溃。

To clarify I'm not asking about compilation errors or warnings, nor can a program crash when executing this line. The question is can this line make the program crash randomly after this line already executed.

推荐答案

基本上整个程序。 printf的开始服用参数从堆栈和,在这种情况下,需要一个 INT 值得太多。这通常是这样的返回地址。因此当printf的返回时,它返回到任何随机数碰巧是在堆栈上下。通常的结果 - 如果你是幸运的 - 是分段错误

Basically for the whole program. Printf starts taking arguments off the stack and, in this case, takes an int worth too much. That's usually something like the return address. So when the printf returns, it returns to whatever random number happens to be next on the stack. The usual result -- if you're lucky -- is a segmentation fault.

由于它推参数入栈中,它会弹出他们,所以它试图获得 INT 第一。

Because it pushes arguments onto the stack, it pops them off, so it tries to get the int first.

如果你的的运气好,找到code的可寻址块。这导致你的第二个情况下,如果地址变成随机字符散列的地址。现在它要尝试打印字符串,直到它找到一个随机NUL字符。

If you're not lucky, it finds an addressable chunk of code. That leads to your second case, where the address becomes the address of that hash of random characters. Now it's going to try to print a string until it find a random NUL character.

更新

由于约阿希姆指出,这一细节被调用约定来确定,因此,让一个明确的例子。当printf函数被调用,要么返回地址被首先推或它的最后推动。我们假设它的第一个推(更常见于平常的架构),所以此调用将需要PUSH返回地址,格式字符串的PUSH地址,PUSH一个int值 - 比方说42这给了我们这个堆栈:

As Joachim points out, the specifics of this are determined by the calling convention, so let's make an explicit example. When the printf function is to be called, either the return address is pushed first or its pushed last. We assume it's pushed first (more common on the usual architecture), so this call is going to need PUSH return-address, PUSH address of the format string, PUSH an int value -- let's say 42. That gives us this stack:

RTN ADDR
ADDR OF STRING
42

和离开堆栈指针SP指向堆栈中的下一位置。

and leaves the stack pointer SP pointing to the next location on the stack.

现在的printf的开始跨preT的字符串。它看起来对 INT 参数的地址,并计算出它的SP-1。因此字符串参数的地址必须是SP-2 ...但是这是格式字符串的地址,因为没有字符串参数。然后,当它看起来格式字符串的地址,它希望找到SP-3,但是这是返回地址,执行code的地址。这应该,大多数在任何机器上,导致段错误。

Now the printf starts to interpret the string. It looks for the address of the int parameter, and figures out it's SP-1. So the address of the string parameter must be SP-2 ... but that's the address of the format string, since there is no string parameter. Then when it looks for the address of the format string, it wants to find SP-3, but that's the return address, an address of executable code. That should, on most any machine, cause a segmentation fault.

如果您通过调用约定的其他选项,你会发现他们每个人都看的部分的错误的事情,因为无论什么时候,printf的认为它需要参照的三件事关堆栈,而不是两个具有。

If you go through the other options for calling convention, you'll find every one of them looks at some wrong thing, because no matter what, printf thinks it needs to refer to three things off the stack, not the two it has.

这篇关于printf的论据不足的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆