2013-02-01 2 views
1

printf를 수행하기 위해 일부 어셈블리 코드를 수정합니다. printf가 처음으로 호출되었을 때 완벽하게 작동합니다. 하지만 두 번째로 printf를 호출하면 문제가 생길 것입니다. gdb를 사용하여 디버깅하고 있습니다.printf에서 실행이 중단되었습니다 - 어셈블리

원래의 부분적인 코드는 내가 GDB에 Ctrl + C을 수행 할 때 그것이 보여주는 갇히지 때 수정 된 코드는

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 

입니다

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 

입니다

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

도움을 주시면 감사하겠습니다.

EDIT : 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 어셈블리라고 가정하고, 따라서 System V ABI를 따르기 때문에, 인수는'rdi','rsi','rdx','rcx','r8','r9'에 있지 않습니다. 스택에. – nrz

+0

예,하지만 AFAIK, printf는 가변 개수의 인수를 지원합니다. 그들 중 일부 (또는 그들 모두, 나는 잘 모르겠다 - 그것은 C 컴파일러에 의존한다)는 스택을 통과해야한다. – johnfound

+0

이 함수는 처음 호출 할 때 제대로 작동하므로 인수가 문제라고 생각하지 않습니다. 내가 틀렸다면 나를 바로 잡으십시오. – simpleuser

1

스택 보호 기능을 놓친 것 같습니다.

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의에 있어야합니다 : 당신의 프레임을 저장하고처럼, 그것을 복원과 함께, 대신 __printf_chk보십시오. Vararg 함수는 때로는 까다 롭습니다. 확인 된 printf를 사용하면 최소한 경고를받습니다.

movl $1, %edi 

는 플래그 값 (something like specification 참조), 그래서 당신은 2 이상을 통과 실험을 할 수있다. 이것은 비표준 기능이기 때문에 시스템에서 무엇을 보게 될지 말하기가 어렵습니다.

+0

지금은 0 값을 출력하고 있습니다. 하지만 두 번째 실행에서는 일부 오류가 발생합니다 – simpleuser

+0

왜 rbp가 끝에 팝되지 않습니까? – simpleuser

+0

valgrind에서 실행할 수 있습니까? 내 말은, __printf_chk가 스택을 손상 시키더라도 프레임을 반환한다는 것입니다. 스택이 다른 곳에서 손상되었을 수 있습니까? –

관련 문제