1

我正在修改一些汇编代码来执行 printf。第一次调用 printf 时,它工作得很好。但是第二次,它对 printf 的调用变得很糟糕。我正在使用 gdb 进行调试。

原始部分代码是

    movq    192(%rsp), %rax         # 8-byte Reload
    movq    (%rax), %rcx
    movq    200(%rsp), %rdx         # 8-byte Reload
    movq    (%rdx), %rsi
    movq    %rcx, %rdi
    movq    24(%rsp), %r8           # 8-byte Reload
    addq    %r8, %rdi
    movq    $0, (%rsi)
    movq    216(%rsp), %r9          # 8-byte Reload
    movq    (%r9), %r10
    movq    208(%rsp), %r11         # 8-byte Reload
    movq    (%r11,%rdi,8), %rbx

修改后的代码是

    movq    192(%rsp), %rax         # 8-byte Reload
    movq    (%rax), %rcx
    movq    200(%rsp), %rdx         # 8-byte Reload
    movq    (%rdx), %rsi
    movq    %rcx, %rdi
    movq    24(%rsp), %r8           # 8-byte Reload
    addq    %r8, %rdi
    pushq   %rax
    pushq   %rsi
    pushq   %rdi
    movq    %rsi, %rax
    movl    $.LCdddd, %edi
    movl    $0, %eax
    call    printf
    popq    %rdi
    popq    %rsi
    popq    %rax
    movq    $0, (%rsi)
    movq    216(%rsp), %r9          # 8-byte Reload
    movq    (%r9), %r10
    movq    208(%rsp), %r11         # 8-byte Reload
    movq    (%r11,%rdi,8), %rbx

当我Ctrl + C在 gdb 中执行操作时卡住它显示它在

__lll_lock_wait_private () at ../nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S:93

任何帮助表示赞赏。

编辑:gdb 跟踪如下。在最后一行之后它只是等待

196     movq    %rsi, %rax
(gdb) 
197     movl    $.LCdddd, %edi
(gdb) 
198     movl    $0, %eax
(gdb) 
199     call    printf
(gdb) 
__printf (format=0x40969e "\nmeow %p\n") at printf.c:30
30  printf.c: No such file or directory.
(gdb) s
34  in printf.c
(gdb) s
30  in printf.c
(gdb) s
35  in printf.c
(gdb) s
34  in printf.c
(gdb) 
35  in printf.c
(gdb) 
_IO_vfprintf_internal (s=0x7ffff7ba8280 <_IO_2_1_stdout_>, format=0x40969e "\nmeow %p\n", ap=0x7fffffffdfc0) at vfprintf.c:246
246 vfprintf.c: No such file or directory.
(gdb) 
211 in vfprintf.c
(gdb) 
246 in vfprintf.c
(gdb) 
1298    in vfprintf.c
(gdb) 
1302    in vfprintf.c
(gdb) 
1313    in vfprintf.c
(gdb) 
1324    in vfprintf.c
(gdb) 
1335    in vfprintf.c
(gdb) 
__find_specmb (format=<optimized out>) at printf-parse.h:99
99  printf-parse.h: No such file or directory.
(gdb) 
_IO_vfprintf_internal (s=0x7ffff7ba8280 <_IO_2_1_stdout_>, format=0x40969e "\nmeow %p\n", ap=0x7fffffffdfc0) at vfprintf.c:1324
1324    vfprintf.c: No such file or directory.
(gdb) 
1335    in vfprintf.c
(gdb) 
__find_specmb (format=0x40969e "\nmeow %p\n") at printf-parse.h:99
99  printf-parse.h: No such file or directory.
(gdb) 
strchrnul () at ../sysdeps/x86_64/strchrnul.S:27
27  ../sysdeps/x86_64/strchrnul.S: No such file or directory.
(gdb) 
28  in ../sysdeps/x86_64/strchrnul.S
(gdb) 
29  in ../sysdeps/x86_64/strchrnul.S
(gdb) 
30  in ../sysdeps/x86_64/strchrnul.S
(gdb) 
31  in ../sysdeps/x86_64/strchrnul.S
(gdb) 
32  in ../sysdeps/x86_64/strchrnul.S
(gdb) 
33  in ../sysdeps/x86_64/strchrnul.S
(gdb) 
34  in ../sysdeps/x86_64/strchrnul.S
(gdb) 
35  in ../sysdeps/x86_64/strchrnul.S
(gdb) 
36  in ../sysdeps/x86_64/strchrnul.S
(gdb) 
37  in ../sysdeps/x86_64/strchrnul.S
(gdb) 
38  in ../sysdeps/x86_64/strchrnul.S
(gdb) 
39  in ../sysdeps/x86_64/strchrnul.S
(gdb) 
40  in ../sysdeps/x86_64/strchrnul.S
(gdb) 
41  in ../sysdeps/x86_64/strchrnul.S
(gdb) 
42  in ../sysdeps/x86_64/strchrnul.S
(gdb) 
43  in ../sysdeps/x86_64/strchrnul.S
(gdb) 
44  in ../sysdeps/x86_64/strchrnul.S
(gdb) 
45  in ../sysdeps/x86_64/strchrnul.S
(gdb) 
46  in ../sysdeps/x86_64/strchrnul.S
(gdb) 
48  in ../sysdeps/x86_64/strchrnul.S
(gdb) 
49  in ../sysdeps/x86_64/strchrnul.S
(gdb) 
50  in ../sysdeps/x86_64/strchrnul.S
(gdb) 
51  in ../sysdeps/x86_64/strchrnul.S
(gdb) 
52  in ../sysdeps/x86_64/strchrnul.S
(gdb) 
53  in ../sysdeps/x86_64/strchrnul.S
(gdb) 
54  in ../sysdeps/x86_64/strchrnul.S
(gdb) 
55  in ../sysdeps/x86_64/strchrnul.S
(gdb) 
56  in ../sysdeps/x86_64/strchrnul.S
(gdb) 
58  in ../sysdeps/x86_64/strchrnul.S
(gdb) 
59  in ../sysdeps/x86_64/strchrnul.S
(gdb) 
strchrnul () at ../sysdeps/x86_64/strchrnul.S:60
60  in ../sysdeps/x86_64/strchrnul.S
(gdb) 
_IO_vfprintf_internal (s=0x7ffff7ba8280 <_IO_2_1_stdout_>, format=0x40969e "\nmeow %p\n", ap=0x7fffffffdfc0) at vfprintf.c:1339
1339    vfprintf.c: No such file or directory.
(gdb) 
1335    in vfprintf.c
(gdb) 
__find_specmb (format=0x40969e "\nmeow %p\n") at printf-parse.h:99
99  printf-parse.h: No such file or directory.
(gdb) 
_IO_vfprintf_internal (s=0x7ffff7ba8280 <_IO_2_1_stdout_>, format=0x40969e "\nmeow %p\n", ap=0x7fffffffdfc0) at vfprintf.c:1339
1339    vfprintf.c: No such file or directory.
(gdb) 
_pthread_cleanup_push_defer (buffer=0x7fffffffde78, routine=0x7ffff784cf70 <__funlockfile>, arg=0x7ffff7ba8280 <_IO_2_1_stdout_>) at cleanup_defer_compat.c:31
31  cleanup_defer_compat.c: No such file or directory.
(gdb) 
32  in cleanup_defer_compat.c
(gdb) 
33  in cleanup_defer_compat.c
(gdb) 
35  in cleanup_defer_compat.c
(gdb) 
38  in cleanup_defer_compat.c
(gdb) 
55  in cleanup_defer_compat.c
(gdb) 
57  in cleanup_defer_compat.c
(gdb) 
58  in cleanup_defer_compat.c
(gdb) 
_IO_vfprintf_internal (s=0x7ffff7ba8280 <_IO_2_1_stdout_>, format=0x40969e "\nmeow %p\n", ap=0x7fffffffdfc0) at vfprintf.c:1340
1340    vfprintf.c: No such file or directory.
(gdb) 
0x00007ffff783d325 in _L_lock_927 () from /lib/x86_64-linux-gnu/libc.so.6
(gdb) 
Single stepping until exit from function _L_lock_927,
which has no line number information.
__lll_lock_wait_private () at ../nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S:77
77  ../nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S: No such file or directory.
(gdb) 
79  in ../nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S
(gdb) 
83  in ../nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S
(gdb) 
84  in ../nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S
(gdb) 
85  in ../nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S
(gdb) 
87  in ../nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S
(gdb) 
88  in ../nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S
(gdb) 
93  in ../nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S
(gdb) 
94  in ../nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S
(gdb) 
96  in ../nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S
(gdb) 
97  in ../nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S
(gdb) 
90  in ../nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S
4

2 回答 2

1

我认为您错过了堆栈保护。尝试 __printf_chk ,同时保存和恢复框架,例如:

pushq %rbp
movq  %rsp, %rbp
pushq   %rax
pushq   %rdx
pushq   %rsi
pushq   %rdi
xorl  %edx, %edx
movl  $.LCdddd, %esi
movl  $1, %edi
xorl  %eax, %eax
call  __printf_chk
popq   %rdi
popq   %rsi
popq   %rdx
popq   %rax
leave

__printf_chk 是非标准的,但必须在 libc 中。Vararg 函数有时很棘手。使用选中的 printf,您至少会收到警告。

movl  $1, %edi

是标志值(参见类似规范的内容),因此您可以尝试传递 2 或更大。由于这是非标准功能,很难说您会在系统上看到什么。

于 2013-02-01T12:09:07.043 回答
1

AFAIK,printf 有 CCALL 调用约定。因此,您可能必须在 printf 返回后手动从堆栈中删除推送的参数。

于 2013-02-01T11:23:29.267 回答