Как мне следить за распространением значений через вызовы функций с помощью обратной отладки GDB?
Я пытаюсь найти способ проследить распространение значений через вызовы функций и копии переменных в программе, используя обратную отладку 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
в 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-фу в сочетании с человеческой интуицией, но я стараюсь сделать этот процесс максимально автоматизированным. В конце концов я хочу попробовать это в более сложном программном обеспечении, где использование человеческой интуиции и GDB-fu было бы довольно утомительным.
Есть ли удобный способ сделать это в GDB с помощью обратной отладки? Способна ли GDB автоматически вычислять и отслеживать эти значения распространения?
PS: Если быть точным, я на самом деле использую GDB с rr. rr - это просто оболочка вокруг GDB, позволяющая создавать детерминированные и воспроизводимые контексты выполнения. Я думаю / надеюсь, что основной вопрос остается неизменным, независимо от того, использую ли я gdb с или без rr.