Reversible debugging in GDB
FSFのフリーソフトウェアの優先プロジェクトのリスト(http://www.fsf.org/campaigns/priority.html)に、"Reversible debugging in GDB"というのがあります。
説明からすると、次のことができそうです。
次のような関数呼び出しがあるプログラムをデバッグするとします。
a | +-b | +-c | +-d +-e
関数aがbとdを呼び出し、bとdがそれぞれcとeを呼んでいます。eの途中でブレークした時、関数cの処理にバグの原因がありそうだと予想して関数cの呼び出し時点に戻りたいことがあります。しかし、こういうことは普通できません。時々、できればいいなと夢想したことがありますが、そんなことは無理だと思っていました。
"Reversible debugging in GDB"でこれができそうです。
無理だと考えた理由は、これを実現するには、スタック領域、ヒープ領域、スタティックなデータ領域(bssおよび非bss)、これらをまとめてデータ領域と呼ぶとすると、ある時点のデータ領域全体の状態をどこかに記憶しておく必要があるからです。例えば、関数aが関数bを呼び出す直前のデータ領域全体の状態が記憶できれば、関数cの呼び出し時点に戻ることができます。しかし、これは全く現実的ではないと思っていました。言うなれば、ネイティブレベルの「継続」だからです(http://dev.ariel-networks.com/Members/inoue/continuations)。
概念上、fork(2)をすると、親プロセスの仮想メモリ全体の複製を行えます。普通のOSはcopy on writeのため、forkした時点でメモリの複製はしませんが、概念上はデータ領域全体の複製ができることになります。
関数aが関数bを呼び出す直前でforkして、その子プロセスを停止したまま、親(元)プロセスの実行を進めます。その後、関数aがbを呼ぶ直前に戻るためには、停止中の子プロセスからデータ領域をコピーして戻す必要があります。ユーザ空間だけで行うなら、なんらかのプロセス間通信により、データ領域をごっそり元に戻す必要があります。copy on writeしたページ分だけをコピーできれば効率的ですが、これをユーザ空間から知るシステムコールがあるかは寡聞にして知りません。その後、PCやSPなどのレジスタを戻せば、関数aがbを呼ぶ直前に戻れます。
理屈上はこれで動作しそうですが、どうでしょう。
- Category(s)
- カテゴリなし
- The URL to Trackback this entry is:
- http://dev.ariel-networks.com/Members/inoue/reversible-debug/tbping
Re:Reversible debugging in GDB
http://code.google.com/p/chronicle-recorder/