2013-02-01 41 views
1

我修改了一些彙編代碼做一個printf。 printf第一次被調用時,它的工作很完美。但是第二次,它在printf調用中變得很糟糕。我正在使用gdb進行調試。執行停留在printf的 - 裝配

原始部分碼是

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 

回答

1

AFAIK,printf有CCALL調用約定。所以,在printf返回之後,你可能不得不從棧中手動刪除推入的參數。

+0

我假設這是Linux的x86-64的組件,因此如下系統V ABI,所以參數在寄存器'rdi','rsi','rdx','rcx','r8','r9',不在堆棧中。 – nrz

+0

是的,但AFAIK,printf支持變量計數的參數。其中一些(或者所有這些,我不確定 - 這取決於C編譯器)必須通過堆棧。 – johnfound

+0

函數在第一次調用時正常工作,所以我不認爲這是參數問題。糾正我,如果我錯了 – simpleuser

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或更大的實驗。由於這是非標準功能,很難說您將在系統上看到什麼。

+0

現在它的工作和打印0值。但是在第二次運行中,它會導致一些seg故障 – simpleuser

+0

也是爲什麼rbp不會在最後被佔用? – simpleuser

+0

你可以在valgrind下運行嗎?我的意思是,即使__printf_chk破壞堆棧,我們正在返回幀。可能是堆棧損壞了別的地方? –