问题
I am modifying some assembly code to do a printf. The first time the printf is called, its working perfectly. But on the second time, it is getting suck at the call to printf. I am using gdb to debug.
The original partial code is
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
The modified code is
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
when I do a Ctrl + C in gdb when it getting stuck it is showing it is in
__lll_lock_wait_private () at ../nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S:93
Any help is appreciated.
EDIT: The gdb trace is as follows. After the last line it simply waiting
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
回答1:
AFAIK, printf has CCALL calling convention. So, you probably have to remove the pushed arguments manually from the stack, after printf returns.
回答2:
I think you missed stack protection. Try __printf_chk instead, along with saving your frame and restoring it, like:
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 is non-standard, but must be in libc. Vararg functions are sometimes tricky. With checked printf you will be at least warned.
movl $1, %edi
is flag value (see something like specification), so you may experiment with passing 2, or greater. Since this is non-standard feature, hard to say what will you see on your system.
来源:https://stackoverflow.com/questions/14644965/execution-stuck-at-printf-assembly