Как перейти к предыдущей строке в GDB?



возможно ли в gdb перейти к строке перед текущей исполняемой строкой.
например:




void my_fun( somePtrType** arr,int start,int end)
{
// arr is an array of pointers to somePtrType
//line a
... some assignments
swap(&arr[ind1] , &arr[ind2] ) ;
//line b (current line )
}


В настоящее время я нахожусь в строке b и могу изучить arr значения там, но я хочу вернуться к строке a и изучить содержимое arr в то время.



Я думаю,что это может быть невозможно, потому что отладчик может запускать код в замедленном режиме, но не может заставить его выполняться в обратном направлении.

Больше никаких озарений..

877   9  

9 ответов:

да! С новой версией 7.0 gdb, вы можете сделать именно это!

команда будет "reverse-step" или "reverse-next".

вы можете получить gdb-7.0 от ftp.gnu.org:/pub/gnu/gdb

если вы столкнетесь с ошибкой:Target child does not support this command. затем попробуйте добавить target record в начале выполнения, после запуска run.

Edit: начиная с GDB 7.6 target record устарело, используйте .

Да, это возможно, и просто, теперь, с реальным оборудованием (т. е. не только с виртуальной машиной). ГДБ-7.0 поддерживает обратная отладка с такими командами, как обратный шаг и обратного продолжения, на родных машинах Linux для архитектуры x86.

здесь есть учебник:http://www.sourceware.org/gdb/wiki/ProcessRecord/Tutorial

короткий ответ:: нет.

на решение читать ниже.

хотя в строке b невозможно определить значение в строке a, можно регистрировать значение arr в a и b и других местах только по одной точке останова.

  • используйте команду "display" ( display variable_name где variable_name должен быть заменен на arr, *arr, **arr в зависимости от того, что вы ищете) так что при достижении любой точки останова содержимое variable_name будет выведено на экран. Обратите внимание, что вы можете добавить в список отображения, когда variabe_name находится в области видимости, так что может потребоваться дождаться первой точки останова.
  • создание точек останова в различных местах кода, где вы заинтересованы, чтобы войти значение variable_name. Одна такая точка останова будет находиться в строке a.
  • для каждой точки останова, используйте команду (команда breakpoint_number) и проинструктируйте вашу точку останова не останавливать выполнение программы. Команда, которую вы должны использовать дальше следовал по конец. См. пример ниже.

(gdb) Команда 1

введите команды для момента достижения точки останова 1, по одной на строку. Конец с линией, говорящей просто "конец".

дальше

конец

  • поставить точка останова на линии b.

теперь, когда все другие точки останова журнала поражены, значение arr будет сброшено на экран, но точка останова не будет ждать взаимодействия с пользователем и будет автоматически продолжена. Когда вы нажмете точку останова в строке b, вы можете увидеть прошлые значения arr, которые будут зарегистрированы в самом gdb.

в зависимости от ситуации вы также можете сбрасывать (и отображать) много полезной информации. Например, вы также можете сбросить счетчик циклов (скажем, i) если вышеуказанная функция вызывается 10000 раз в цикле. Это действительно зависит от того, чего вы пытаетесь достичь.

согласно http://sourceware.org/gdb/current/onlinedocs/gdb.html#SEC51, и "если целевая среда поддерживает его", да.

Если ваша программа короткая, обычный трюк,

  1. поместите новую точку останова в предыдущей строке
    • пожар r для перезапуска отладки

GDB было сделано для этого!

Не gdb, но вы можете легко вернуться в историю, используя отладчик под названием qira. Вы можете использовать стрелки вверх и вниз, чтобы идти вперед и назад, он также подчеркивает, что регистры были изменены.

enter image description here

mozilla rr

https://github.com/mozilla/rr

встроенная запись и воспроизведение GDB имеет серьезные ограничения, например, нет поддержки инструкций AVX:обратная отладка gdb завершается с ошибкой "запись процесса не поддерживает инструкцию 0xf0d по адресу"

оборотные стороны rr:

  • гораздо надежнее в настоящее время
  • также предлагает интерфейс GDB с протоколом gdbserver, делая это отличная замена
  • небольшое падение производительности для многих программ

в следующем примере демонстрируются некоторые из его функций, в частности reverse-next,reverse-step и reverse-continue команды.

Установить Ubuntu 16.04:

sudo apt-get install rr linux-tools-common linux-tools-generic linux-cloud-tools-generic
sudo cpupower frequency-set -g performance

но также рассмотреть возможность компиляции из исходного кода, чтобы получить последние обновления, это не было трудно.

тестовая программа:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int f() {
    int i;
    i = 0;
    i = 1;
    i = 2;
    return i;
}

int main(void) {
    int i;

    i = 0;
    i = 1;
    i = 2;

    /* Local call. */
    f();

    printf("i = %d\n", i);

    /* Is randomness completely removed?
     * Recently fixed: https://github.com/mozilla/rr/issues/2088 */
    i = time(NULL);
    printf("time(NULL) = %d\n", i);

    return EXIT_SUCCESS;
}

компиляция и запуск:

gcc -O0 -ggdb3 -o reverse.out -std=c89 -Wextra reverse.c
rr record ./reverse.out
rr replay

теперь вы остались внутри сеанс GDB, и вы можете правильно отменить отладку:

(rr) break main
Breakpoint 1 at 0x55da250e96b0: file a.c, line 16.
(rr) continue
Continuing.

Breakpoint 1, main () at a.c:16
16          i = 0;
(rr) next
17          i = 1;
(rr) print i
 = 0
(rr) next
18          i = 2;
(rr) print i
 = 1
(rr) reverse-next
17          i = 1;
(rr) print i
 = 0
(rr) next
18          i = 2;
(rr) print i
 = 1
(rr) next
21          f();
(rr) step
f () at a.c:7
7           i = 0;
(rr) reverse-step
main () at a.c:21
21          f();
(rr) next
23          printf("i = %d\n", i);
(rr) next
i = 2
27          i = time(NULL);
(rr) reverse-next
23          printf("i = %d\n", i);
(rr) next
i = 2
27          i = time(NULL);
(rr) next
28          printf("time(NULL) = %d\n", i);
(rr) print i
 = 1509245372
(rr) reverse-next
27          i = time(NULL);
(rr) next
28          printf("time(NULL) = %d\n", i);
(rr) print i
 = 1509245372
(rr) reverse-continue
Continuing.

Breakpoint 1, main () at a.c:16
16          i = 0;

каждый желает для Всеведущего отладчика, как этот:http://www.lambdacs.com/debugger/, но они (в зависимости от языка/машины) трудно сделать и имеют много бухгалтерии, чтобы сделать.

на данный момент на реальном оборудовании, а не в виртуальной машине, это почти невозможно сделать.

Если ваш код настройки для arr находится чуть выше "строки a" (очень часто сценарий), вы можете сделать это следующим образом:

tbreak myfilename.c:123 (строка 123-начало кода настройки для arr) затем

jump 123

"tbreak" предотвращает gdb от продолжения (возобновления) программы после прыжка.

затем вы можете пройти через код настройки или просто установить точку останова в "строке a" и продолжить

Comments

    Ничего не найдено.