Saturday, 7 April 2018

x.v6 読み会

新しい4年次も来たので、x.v6 を読み直し。GCC 版でも clang 版でも動くし、もう何回も読んだので楽勝だ。

なんだけど、新しい clang 版だけ ls の出力がおかしい。えーと、

  x.v6 ってユーザプログラムのデバッグってどうやるの?

kernel は trace できるんですけど、ユーザプログラムが停められるのは fork / exec からだし。で、fork 読んだのですが、

  page table を copy して、proc を複製するだけ

あぁ、まぁ、そうだよな。exec 読まないと。exec は、

  プログラム load して、page table を作って切り替えるだけ

あれ? あ、そうか。kernel から user space に戻るところを読まないと。trapret ですね。ARM では SVC mode (supervisor mode) から抜けて return するだけらしい。

ということは、

(1) ユーザプログラムが最初に呼ぶ system call にbreak point をかける

(2) 走らせて、shell からユーザプログラムを起動すると、gdb でそのsystem callが捕まる

(3) trapret に break point をかけて、continue

(4) trapret で、p *proc して、ターゲットのユーザプログラムかどうかをチェックする

(5) そこから stepi していくと、ユーザプログラムに到達

(6) この時点でユーザプログラムに break point がかけられるようになる

これで,良いらしい。ただし、ソースコードデバッグはできませんが。アセンブラ読めるから大丈夫。

いろいろ調べた所、printf が動いてないらしい。読んでみると「引数のアドレスを取って、それをincrementして」とかやってる。

なんと、それでgcc と古いclangは動くのですが、新しいclangでは動かない。いや、clang で arm で動く方がおかしいだろ。そういうの尊重していたのか。 結局、stdarg ( va_arg とか使う奴) に書き換えたら治りました。なるほどね。

No comments: