google-code-prettify

2007-05-21

フレームポインタ無しで、スタックトレースをする方法

一応組込みエンジニアなので、たまには組込みっぽい話を。

通常、フレームポインタが無い場合には、スタックトレースをする事ができない。
なぜなら、関数からの戻りアドレスがスタックのどこに格納されているかを知る事ができないからである。

しかし、フレームポインタが無い場合でも、スタックトレースをする方法がある。
それは、
「プログラムの命令コードを追っていって、SPの増減をカウントする」
という方法である。

この方法が使える条件は、
・フレームポインタが無いアーキテクチャである
・SPの増減を行うオペコードが限られている
・あまり変態的な最適化が行われずに、素直なコードを出力するコンパイラである

私が今業務で使っているRenesasのSHCコンパイラが、ちょうど上記の条件を満たす。

SH4では、追わなくてはならないオペコードは以下の通り。
・RTS
・BRA
・MOV.L Rm, @-R15
・MOV.L @R15+, Rn
・ADD #imm, R15
・LDS.L @R15+, PR
・ADD Rm, R15

最後の ADD Rm, R15は関数からリターンする時にフレームをずらすために使用されるのだが、Rmの値がわからないと、R15に足すべき値がわからない。
まともRmの値を知ろうとすると大変なのだが、ありがたい事に、ADD Rm, R15の直前には、Rmに値をストアするためのMOV @(disp, PC), Rmが存在するので、容易にRmの値がわかる。


これにより、例外発生時にスタックトレースを表示する機能を作る事ができる。

0 件のコメント: