Closed TaiseiIto closed 2 years ago
一般保護例外発生 スタック不足というより,大きすぎてコンパイラがスタックに領域を確保していないような感じがする
終了に失敗している
拡大縮小できるようにする
ホイールは-1で拡大 1で縮小
一般保護例外発生
(gdb) backtrace
#0 0x00109a8f in ?? (general_protection_fault_handler)
#1 0x0011b78d in ?? (system_call_exit)
#2 0x0011b5c7 in ?? (system_call)
#3 0x0010ec66 in ?? (interrupt_handler0x80)
Backtrace stopped: previous frame inner to this frame (corrupt stack?)
(gdb) x/40i 0x0011b759
0x11b759: push %ebp
0x11b75a: mov %esp,%ebp
0x11b75c: sub $0x8,%esp
0x11b75f: call 0x10a16c
0x11b764: call 0x11b0cd
0x11b769: call 0x11b1a7
0x11b76e: call 0x11b264
0x11b773: call 0x11b31e
0x11b778: call 0x11d20e
0x11b77d: mov 0x4(%eax),%edx
0x11b780: mov 0x8(%ebp),%eax
0x11b783: sub $0x8,%esp
0x11b786: push %edx
0x11b787: push %eax
0x11b788: call 0x111723 (exit_application)
=> 0x11b78d: add $0x10,%esp
0x11b790: leave
0x11b791: ret
0x11b792: push %ebp
0x11b793: mov %esp,%ebp
0x11b795: push %ebx
0x11b796: sub $0x14,%esp
0x11b799: call 0x11d20e
0x11b79e: mov %eax,-0xc(%ebp)
0x11b7a1: mov 0x125ba4,%eax
0x11b7a6: test %eax,%eax
0x11b7a8: je 0x11b84a
0x11b7ae: mov 0x125ba4,%eax
0x11b7b3: mov %eax,-0x10(%ebp)
0x11b7b6: mov -0x10(%ebp),%eax
0x11b7b9: mov (%eax),%eax
0x11b7bb: sub $0x8,%esp
0x11b7be: push 0x8(%ebp)
0x11b7c1: push %eax
0x11b7c2: call 0x11af9c
0x11b7c7: add $0x10,%esp
0x11b7ca: test %eax,%eax
0x11b7cc: jne 0x11b7f2
0x11b7ce: mov -0x10(%ebp),%eax
0x11b7d1: mov 0x4(%eax),%eax
exit_applicationで正常にアプリを終了できなかった結果,0x11b78dという番地に到達してしまった. 一般保護例外ハンドラでもexit_applicationを試みて失敗するため,一般保護例外の連鎖が発生する. 大きな領域を確保したためにスタックが壊れている可能性がある. マンデルブロ集合の画面の一部が乱れているのも,これが原因である可能性が高い
cとzの容量を2倍にしてみたら一般保護例外は起きなくなった なぜだ?
アプリケーション自体のスタックの確保は問題なさそう
一般保護例外のエラーコードが-1になってるけどちゃんとエラーコードを拾えているのかどうかわからん
int0x0d発生直後にブレークポイントを置いてみた
(gdb) x/4w $esp
0x14dcb483: 0x0000e7c0 0x0011174f 0x00000010 0x00000206
key | value |
---|---|
error code | 0x0000e7c0 |
EIP | 0x0011174f |
CS | 0x00000010 |
EFLAGS | 0x00000206 |
一般保護例外が起きている箇所(kernel.binのexit_application)
(gdb) x/40i 0x0011174f
0x11174f: pop %fs
0x111751: pop %ds
0x111752: pop %es
0x111753: popf
0x111754: popa
0x111755: pop %eax
0x111756: leave
0x111757: ret
gsに無効なセグメントセレクタをポップしたことで一般保護例外が発生している
call_applicationとexit_applicationでスタックの対応を確認してみよう
call_application呼び出し直後
(gdb) info register
eax 0x20 32
ecx 0x4f3aece 83078862
edx 0x10005486 268457094
ebx 0x7 7
esp 0x4f5af32 0x4f5af32
ebp 0x4f5afee 0x4f5afee
esi 0x7 7
edi 0x7 7
eip 0x1116b5 0x1116b5
eflags 0x216 [ IOPL=0 IF AF PF ]
cs 0x10 16
ss 0x8 8
ds 0x8 8
es 0x8 8
fs 0x8 8
gs 0x8 8
call_applicationの3つ目の命令
subl 0x00000004,%esp
が実行されたとたんにespの値がおかしくなっている
どうやらQEMUでのみ現れるバグっぽいが原因を探っておこう
printfデバッグすると再現できなくなるハイゼンバグなので,gdbでデバッグする
どうやらcreate_window(0x001214ec)でぽしゃるっぽいことはわかっているので,そこにブレークポイントを置いてやってみよう
結論 動作が無茶苦茶遅いだけでした
実機はマウスホイールが使えないから拡大できなくなってる(完了) ドラッグで移動できるようにしたい(完了) コマンドライン引数で座標と大きさを指定できるようにしたい
コマンドライン引数で座標と大きさを指定できるようにしたい
とりあえずatof関数を実装しよう
マンデルブロ集合描画アプリを作ってみよう