【问题标题】:gdb seems to affect function return value that's stored in $eax?gdb 似乎会影响存储在 $eax 中的函数返回值?
【发布时间】:2016-10-18 10:49:47
【问题描述】:

"printf" 返回实际打印的字符数,所以我有:

#include<stdio.h>
int main()
{
  printf("1");
  printf("55555");
  printf("10________");
  printf("13___________");
  printf("18________________");
  printf("28__________________________");
}

这个程序会输出

15555510________13___________18________________28__________________________

然后我尝试在gdb中调试,查看gdb的返回值:

(gdb) b main
Breakpoint 1 at 0x804844c: file testp.c, line 4.
(gdb) r
Starting program: /home/a/cpp/a.out 

Breakpoint 1, main () at testp.c:4
4     printf("1");
(gdb) n               # will return "1" to $eax
5     printf("55555");
(gdb) p $eax          # I expect it will print "1" here, wrong!
$1 = 49
(gdb) n
6     printf("10________");
(gdb) p $eax          # I expect it will print "5" here, right!
$2 = 5
(gdb) n
7     printf("13____________");
(gdb) p $eax          # I expect it will print "10" here, right!
$3 = 10

如您所见,当第一个 printf 运行时,$eax 的值与我的预期不同。后来的值似乎是正确的。 为什么是这样?为什么第一个 printf 不向 $eax 返回“1”?我想 c 风格的 ABI 将返回值存储在 $eax 中,对吧?

谢谢

【问题讨论】:

    标签: linux gcc gdb return printf


    【解决方案1】:

    gcc 可以用更高效的代码替换对printf 的调用,例如对putsputchar 的调用,在某些情况下优化不会改变函数的记录行为(例如,当输出不需要进行任何格式化,并且您不使用返回值)。这就是这里发生的事情。您在 %eax 中看到 49,因为 putchar 返回输出的字符或 EOF

    (gdb) disass /m main
    Dump of assembler code for function main:
    3   {
       0x000000000040057d <+0>: push   %rbp
       0x000000000040057e <+1>: mov    %rsp,%rbp
    
    4     printf("1");
       0x0000000000400581 <+4>: mov    $0x31,%edi
       0x0000000000400586 <+9>: callq  0x400450 <putchar@plt>
    
    5     printf("55555");
       0x000000000040058b <+14>:    mov    $0x400664,%edi
       0x0000000000400590 <+19>:    mov    $0x0,%eax
       0x0000000000400595 <+24>:    callq  0x400460 <printf@plt>
    

    要让 gcc 始终生成对 printf 的调用,您可以使用 -fno-builtin-printf 选项。

    【讨论】:

    • 谢谢,-fno-builtin-printf 对我有用。我只是很困惑,我没有使用“-O”选项或进行任何优化,为什么 gcc 仍然进行一些优化?如何手动完全禁用它?
    • 即使使用-O0,gcc 仍然会为printfstrcpy 等标准函数替换等效的、更有效的代码,除非你给它-fno-builtinno-builtin-nameoffunc 选项。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-12-21
    • 1970-01-01
    • 2013-08-12
    • 1970-01-01
    • 1970-01-01
    • 2012-04-04
    • 1970-01-01
    相关资源
    最近更新 更多