执行停留在printf - assembly

时间:2013-02-01 11:07:53

标签: gcc assembly gdb x86-64

我正在修改一些汇编代码来执行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

当我在gdb中遇到Ctrl + C时,它会显示在

__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

2 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分: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

是标记值(请参阅something like specification),因此您可以尝试传递2或更高版本。由于这是非标准功能,很难说你会在系统上看到什么。