GDBリバースデバッグを使用して、プログラム内の関数呼び出しと変数コピーによる値の伝播を追跡する方法を見つけようとしています。私は過去に GDB をよく使用していましたが、リバース デバッグは比較的初めてです。
例を挙げて質問を組み立てるのが最も簡単だと思います。このプログラムを見てください。
void FnA(int x) {
printf("x=%d\n", x)
}
void FnB(int y) {
int y_copy = y;
FnA(y_copy);
}
void FnC(int z) {
FnB(z);
}
int main() {
int i;
i = 5;
FnC(i);
}
プログラムをコンパイルし、リバース デバッグを使用して GDB を起動し、コンパイル済みの実行可能ファイルを実行します。printf
inにブレークポイントを設定しFnA
、プログラムの実行を開始すると、そのブレークポイントに到達します。x
ここからは、「最後に書かれたのはどこですか?」という質問に答えたいと思います。私はすることができたしwatch -l x
、その後reverse-continue
。ただし、スタック上での有効期間が始まったFnA
場所であるため、それはの最初に移動するだけです。x
私が本当に興味を持っているのは、の値がどこから来たかということですi = 5
。その時から、本当にmain
x
i = 5
x
次のように、関数パラメーターと変数のコピーを介して伝播されましたmain:i -> FnC:z -> FnB:y -> FnB:y_copy -> FnA:x
。
明らかに、GDB-fu と人間の直感を組み合わせることでこれを理解できますが、このプロセスを可能な限り自動化しようとしています。最終的には、人間の直感と GDB-fu を使用するのはかなり面倒な、より複雑なソフトウェアでこれを試してみたいと思います。
リバースデバッグを使用して GDB でこれを達成する便利な方法はありますか? GDB は、これらの値の伝播を自動的に把握して追跡することができますか?
PS: 具体的には、実際にrrで GDB を使用しています。rr は、確定的で再現可能な実行コンテキストを可能にする gdb の単なるラッパーです。rr の有無にかかわらず、gdb を使用しているかどうかに関係なく、コアの質問は同じままであると思います/願っています。