是否有可能在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 )
}
Run Code Online (Sandbox Code Playgroud)
我现在在b行,可以检查arr
那里的值,但我想回到第一行并检查arr
那时的内容.
我认为这可能是不可能的,因为调试器可以以慢动作运行代码,但不能使其向后执行.
更多见解..
Mic*_*der 99
是! 使用新版本7.0 gdb,您可以做到这一点!
命令将是" reverse-step
"或" reverse-next
".
你可以从ftp.gnu.org:/pub/gnu/gdb获得gdb-7.0
如果您遇到错误:Target child does not support this command.
然后尝试target record
在开始执行之后添加run
.
编辑:由于target record
不推荐使用GDB 7.6 ,请target record-full
改用.
Mic*_*der 12
是的,现在,使用真实硬件(即不仅仅是VM),这是可能的,而且直截了当.GDB-7.0支持在本机linux x86机器上使用反向步骤和反向继续等命令进行反向调试.
这里有一个教程:http://www.sourceware.org/gdb/wiki/ProcessRecord/Tutorial
Mozilla rr
GDB的内置记录和重播具有严格的限制,例如,不支持AVX指令:gdb反向调试失败,显示“过程记录不支持地址处的指令0xf0d”
rr的优点:
下面的例子展示了它的某些功能,尤其是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
Run Code Online (Sandbox Code Playgroud)
但也可以考虑从源代码进行编译以获取最新更新,这并不难。
反向
#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;
}
Run Code Online (Sandbox Code Playgroud)
编译并运行:
gcc -O0 -ggdb3 -o reverse.out -std=c89 -Wextra reverse.c
rr record ./reverse.out
rr replay
Run Code Online (Sandbox Code Playgroud)
现在您就处于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
$1 = 0
(rr) next
18 i = 2;
(rr) print i
$2 = 1
(rr) reverse-next
17 i = 1;
(rr) print i
$3 = 0
(rr) next
18 i = 2;
(rr) print i
$4 = 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
$5 = 1509245372
(rr) reverse-next
27 i = time(NULL);
(rr) next
28 printf("time(NULL) = %d\n", i);
(rr) print i
$6 = 1509245372
(rr) reverse-continue
Continuing.
Breakpoint 1, main () at a.c:16
16 i = 0;
Run Code Online (Sandbox Code Playgroud)
简短答案:否。
有关解决方法,请阅读以下内容。
尽管在b行无法确定a处的值,但可以通过仅击中一个断点来记录a和b以及其他位置处的arr值。
(gdb)命令1
输入命中断点1的命令,每行一个。结束时说“结束”。
继续
结束
现在,当所有其他日志记录断点都被命中时,arr的值将被转储到屏幕上,但是断点将不等待用户交互并且将自动继续。当您在b行达到断点时,您可以看到arr的过去值,该值将记录在gdb本身中。
根据情况,您还可以转储(和显示)许多有用的信息。例如,如果在循环中调用了10000次以上函数,则可能还需要转储循环计数器(例如i)。这确实取决于您要实现的目标。
归档时间: |
|
查看次数: |
55616 次 |
最近记录: |