1

printfを実行するためにいくつかのアセンブリコードを変更しています。printfが初めて呼び出されたときは、完全に機能しています。しかし、2回目は、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 + Cgdbでスタックしているときに実行すると、

__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にはCCALL呼び出し規約があります。そのため、おそらく、printf が戻った後に、プッシュされた引数をスタックから手動で削除する必要があります。

于 2013-02-01T11:23:29.267 に答える
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 に含まれている必要があります。可変引数関数は、扱いにくい場合があります。チェックされた printf を使用すると、少なくとも警告が表示されます。

movl  $1, %edi

フラグ値 (仕様のようなものを参照) であるため、2 以上を渡して試すことができます。これは非標準の機能であるため、システムで何が表示されるかはわかりません。

于 2013-02-01T12:09:07.043 に答える