这一次很快.
是否有可能(除了永远按下输入)gdb不断next通过程序逐行查找错误发生的位置?
编辑:continue不是我想要的; 我想有效地看到完整的程序执行,一行一行,就像你next一遍又一遍地得到的那样.
这是一个如此黑客的东西我发布它有点尴尬.但是,如果你只需要一次性,它可能会让你获得你想要的信息.确实应该有更好的方法.
您可以定义一个执行step或next命令一定次数的愚蠢的小gdb脚本:
# file: step_mult.gdb
define step_mult
set $step_mult_max = 1000
if $argc >= 1
set $step_mult_max = $arg0
end
set $step_mult_count = 0
while ($step_mult_count < $step_mult_max)
set $step_mult_count = $step_mult_count + 1
printf "step #%d\n", $step_mult_count
step
end
end
Run Code Online (Sandbox Code Playgroud)
(我使用步骤而不是next没有特别好的理由;只需将其更改为您需要的任何内容.)
然后你可以运行该命令(带有一个可选的计数),它会显示每个step或next很好.
这是一个示例程序,它在尝试取消引用NULL指针时会崩溃:
#include<stdio.h>
int x[] = {
0, 1, 2, 3, 4, 5, 6, 7, 8,9, 10
};
int* p[11];
int main()
{
int i;
for (i = 0; i < 11; ++i) {
p[i] = &x[i];
}
p[5] = 0;
for (i = 0; i < 11; ++i) {
printf( "*p[%d] == %d\n", i, *p[i]);
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这是一个gdb会话(在Windows上)调试该程序并使用step_mult脚本:
C:\temp>gdb test.exe
GNU gdb (GDB) 7.2
...
Reading symbols from C:\temp/test.exe...done.
(gdb) source c:/temp/step_mult.gdb
(gdb) start
Temporary breakpoint 1 at 0x401385: file C:\temp\test.c, line 23.
Starting program: C:\temp/test.exe
[New Thread 5396.0x1638]
Temporary breakpoint 1, main () at C:\temp\test.c:23
23 for (i = 0; i < 11; ++i) {
(gdb) step_mult 70
step #1
24 p[i] = &x[i];
step #2
23 for (i = 0; i < 11; ++i) {
step #3
24 p[i] = &x[i];
step #4
23 for (i = 0; i < 11; ++i) {
step #5
24 p[i] = &x[i];
step #6
23 for (i = 0; i < 11; ++i) {
step #7
24 p[i] = &x[i];
step #8
23 for (i = 0; i < 11; ++i) {
step #9
24 p[i] = &x[i];
step #10
23 for (i = 0; i < 11; ++i) {
step #11
24 p[i] = &x[i];
step #12
23 for (i = 0; i < 11; ++i) {
step #13
24 p[i] = &x[i];
step #14
23 for (i = 0; i < 11; ++i) {
step #15
24 p[i] = &x[i];
step #16
23 for (i = 0; i < 11; ++i) {
step #17
24 p[i] = &x[i];
step #18
23 for (i = 0; i < 11; ++i) {
step #19
24 p[i] = &x[i];
step #20
23 for (i = 0; i < 11; ++i) {
step #21
24 p[i] = &x[i];
step #22
23 for (i = 0; i < 11; ++i) {
step #23
27 p[5] = 0;
step #24
29 for (i = 0; i < 11; ++i) {
step #25
30 printf( "*p[%d] == %d\n", i, *p[i]);
step #26
*p[0] == 0
29 for (i = 0; i < 11; ++i) {
step #27
30 printf( "*p[%d] == %d\n", i, *p[i]);
step #28
*p[1] == 1
29 for (i = 0; i < 11; ++i) {
step #29
30 printf( "*p[%d] == %d\n", i, *p[i]);
step #30
*p[2] == 2
29 for (i = 0; i < 11; ++i) {
step #31
30 printf( "*p[%d] == %d\n", i, *p[i]);
step #32
*p[3] == 3
29 for (i = 0; i < 11; ++i) {
step #33
30 printf( "*p[%d] == %d\n", i, *p[i]);
step #34
*p[4] == 4
29 for (i = 0; i < 11; ++i) {
step #35
30 printf( "*p[%d] == %d\n", i, *p[i]);
step #36
Program received signal SIGSEGV, Segmentation fault.
0x004013d2 in main () at C:\temp\test.c:30
30 printf( "*p[%d] == %d\n", i, *p[i]);
step #37
Program received signal SIGSEGV, Segmentation fault.
0x004013d2 in main () at C:\temp\test.c:30
30 printf( "*p[%d] == %d\n", i, *p[i]);
step #38
Program exited with code 030000000005.
step #39
The program is not being run.
(gdb)
Run Code Online (Sandbox Code Playgroud)
不幸的是,由于在发生段错误时脚本没有停止,gdb决定只是停止调试程序,所以你不能进行任何进一步有用的查询.但是日志可能仍然有用.
我确信有很多方法可以使脚本更加智能化.不幸的是,我不知道如何做到这一点,GDB的用户级文档似乎对这些细节没有太大帮助.最好的方法是,如果脚本可以检测到段错误或信号发生,然后停止,而不是依赖于某些任意计数.我想gdb/MI接口,甚至可能是Python脚本接口可能都有一个很好的机制,但我对这些并不了解.
第一次运行后,您可以使用显示的计数(在我的示例中为37)并重新启动程序,并给出一个只是在之前崩溃的地方并且手动控制的计数.
就像我说的那样,它并不是特别漂亮 - 但它可能会让你在那里.
| 归档时间: |
|
| 查看次数: |
2741 次 |
| 最近记录: |