2011-07-03 19 views
6

私は、GDBのxコマンドを使用してメモリを印刷することができますが、私はprintfのを使用している場合、セグメンテーションフォールト:この行は私にセグメンテーションフォルトを引き起こしている

30    printf("st_name:\t%s\n", &p_str_tab[p->st_name]); 

私はGDBでそれを追跡しようとしました:

(gdb) p p_str_tab[p->st_name] 
$11 = 0 '\000' 
(gdb) p &p_str_tab[p->st_name] 
$12 = 0x2aaaaaab0000 "" 
(gdb) x/16s 0x2aaaaaab0000 
0x2aaaaaab0000: "" 
0x2aaaaaab0001: ".symtab" 
0x2aaaaaab0009: ".strtab" 
(gdb) call printf("st_name:\t%s\n", 0x2aaaaaab0000) 

Program received signal SIGSEGV, Segmentation fault. 
0x00000034f4042729 in vfprintf() from /lib64/libc.so.6 
The program being debugged was signaled while in a function called from GDB. 
GDB remains in the frame where the signal was received. 
To change this behavior use "set unwindonsignal on". 
Evaluation of the expression containing the function 

gdbのxコマンドでメモリを印刷できますが、printfを使用している場合は、セグメント化エラーです。

なぜですか?コメントに、必要に応じ

UPDATE:

(gdb) x/1i $rip 
0x34f4042729 <vfprintf+57>: mov 0xc0(%rdi),%eax 
(gdb) info reg 
rax   0x54 84 
rbx   0x34f3e1bbc0 227429956544 
rcx   0x0 0 
rdx   0xffffffffffffffb0 -80 
rsi   0x401b08 4201224 
rdi   0x600908 6293768 
rbp   0x7fffffffe6e0 0x7fffffffe6e0 
rsp   0x7fffffffe040 0x7fffffffe040 
r8    0x2aaaaaabf210 46912496202256 
r9    0x34f4351780 227435419520 
r10   0x1238 4664 
r11   0x648 1608 
r12   0x0 0 
r13   0x7fffffffe9c0 140737488349632 
r14   0x0 0 
r15   0x0 0 
rip   0x34f4042729 0x34f4042729 <vfprintf+57> 
eflags   0x10202 [ IF RF ] 
cs    0x33 51 
ss    0x2b 43 
ds    0x0 0 
es    0x0 0 
fs    0x0 0 
gs    0x0 0 
fctrl   0x37f 895 
fstat   0x0 0 
ftag   0xffff 65535 
---Type <return> to continue, or q <return> to quit--- 
fiseg   0x0 0 
fioff   0x0 0 
foseg   0x0 0 
fooff   0x0 0 
fop   0x0 0 
mxcsr   0x1f80 [ IM DM ZM OM UM PM ] 
+0

興味深いコード、特に '&p_str_tab [p-> st_name]'が何であるかを見るのに役立ちます。 gdb 'p' sは助けなければなりませんが、実際には何かが欠けているような、 xについては、gdbはプログラム自体がアクセスできるよりも多くのメモリを安全に読み取ることができますか? – ShinTakezou

+0

@ShinTakezouをチェックすると、 '&p_str_tab [p-> st_name]'は上記の '0x2aaaaaab0000'のシンボルテーブルを指しています。 –

+0

SEGVの後に 'x/1i $ rip'と' info reg'を実行できますか? – ninjalj

答えて

0

ポインタオーバーランの問題である必要があります、valgrindを試してください。

1

あなたがスタックをオーバーフローしているかどうかを確認したい場合があります。

+0

これを確認するには? –

+0

フォールト命令はスタックを参照しないため、スタックオーバーフローは問題とは関係ありません。 –

1

フォールティング命令mov 0xc0(%rdi),%eaxは、eax = rdi->memberのようになります。ここで、memberはオフセット0xc0です。より多くの分解を見ることなく、確かにそれが何であるかを知るのは難しいですが、それはstdoutまたはstdoutの中にある可能性が高いようです。障害のある命令が入力文字列の参照を外している可能性は低いです。

stdoutに珍しいことをしましたか?ブルートフォースのアプローチはどこにでもprintfを振りかけて(おそらくそれは問題ではない)、どこからクラッシュするかを見ることです。その前に、何かが壊れている場所です。

関連する問題