有没有办法在程序达到一定帧数后中断程序?
Is there a way to break a program after it reaches a certain number of frames?
我正在尝试实现一个递归树函数,但出现段错误,因为该函数会自行调用,我想看看我的程序最后处于什么状态。
I would like to see what state my program is at the end.
运行 GDB下的程序,它会停止(当你的程序耗尽它的堆栈时)并且显示你最后的状态。
示例:
void fn(int j)
{
char buf[1024]; // consume some stack space.
buf[0] = 'a';
fn(j - buf[0]); // bad recursion -- should have checked for j - 'a' > 0
}
int main()
{
fn(10000);
return 0;
}
gcc -g t.c && gdb -q ./a.out
(gdb) run
Starting program: /tmp/a.out
Program received signal SIGSEGV, Segmentation fault.
0x0000555555555130 in fn (j=<error reading variable: Cannot access memory at address 0x7fffff7fef8c>) at t.c:2
2 {
(gdb) bt 10
#0 0x0000555555555130 in fn (j=<error reading variable: Cannot access memory at address 0x7fffff7fef8c>) at t.c:2
#1 0x0000555555555158 in fn (j=-759889) at t.c:5
#2 0x0000555555555158 in fn (j=-759792) at t.c:5
#3 0x0000555555555158 in fn (j=-759695) at t.c:5
#4 0x0000555555555158 in fn (j=-759598) at t.c:5
#5 0x0000555555555158 in fn (j=-759501) at t.c:5
#6 0x0000555555555158 in fn (j=-759404) at t.c:5
#7 0x0000555555555158 in fn (j=-759307) at t.c:5
#8 0x0000555555555158 in fn (j=-759210) at t.c:5
#9 0x0000555555555158 in fn (j=-759113) at t.c:5
(More stack frames follow...)
你在这里看到的是程序最后的状态,即完全你在[=43]中要求的=],但不在标题中(在 body 和标题中提出 不同的 问题是一种不好的形式)。
Is there a way to break a program after it reaches a certain number of frames?
没有,但有各种近似值。
对于上面的测试程序,答案是微不足道的。由于 fn
不断调用自身,您可以在第 N 次调用时停止。例如。如果您想在递归达到 100 帧时停止,请执行以下操作:
(gdb) b fn
Breakpoint 1 at 0x1136: file t.c, line 4.
(gdb) ign 1 100
Will ignore next 100 crossings of breakpoint 1.
(gdb) run
Starting program: /tmp/a.out
Breakpoint 1, fn (j=300) at t.c:4
4 buf[0] = 'a';
(gdb) bt
#0 fn (j=300) at t.c:4
#1 0x0000555555555158 in fn (j=397) at t.c:5
#2 0x0000555555555158 in fn (j=494) at t.c:5
#3 0x0000555555555158 in fn (j=591) at t.c:5
#4 0x0000555555555158 in fn (j=688) at t.c:5
...
#99 0x0000555555555158 in fn (j=9903) at t.c:5
#100 0x0000555555555158 in fn (j=10000) at t.c:5
#101 0x0000555555555169 in main () at t.c:10
当fn
间接调用自身时,事情会变得更复杂(但如果循环的长度是固定的K,那么只需将N除以K)。
如果循环的长度不是固定的,或者如果某些调用 return(即不是每个调用都重复出现),那么达到 N 级深度会稍微复杂一些。最简单的方法是修改程序以在全局范围内保持递归计数。然后你可以简单地设置一个条件观察点。示例:
int recursion_count;
void fn(int j)
{
char buf[1024]; // consume some stack space.
recursion_count += 1;
buf[0] = 'a';
fn(j - buf[0]); // bad recursion -- should have checked for j - 'a' > 0
recursion_count -= 1;
}
int main()
{
fn(10000);
return 0;
}
gcc -g t.c && gdb -q ./a.out
(gdb) start
Temporary breakpoint 1 at 0x55555555517d: file t.c, line 15.
Starting program: /tmp/a.out
Temporary breakpoint 1, main () at t.c:15
15 fn(10000);
(gdb) p recursion_count
= 0
(gdb) watch recursion_count
Hardware watchpoint 2: recursion_count
(gdb) cond 2 recursion_count == 100
(gdb) c
Continuing.
Hardware watchpoint 2: recursion_count
Old value = 99
New value = 100
fn (j=397) at t.c:8
8 buf[0] = 'a';
(gdb) bt
#0 fn (j=397) at t.c:8
#1 0x0000555555555167 in fn (j=494) at t.c:9
#2 0x0000555555555167 in fn (j=591) at t.c:9
#3 0x0000555555555167 in fn (j=688) at t.c:9
...
#97 0x0000555555555167 in fn (j=9806) at t.c:9
#98 0x0000555555555167 in fn (j=9903) at t.c:9
#99 0x0000555555555167 in fn (j=10000) at t.c:9
#100 0x0000555555555187 in main () at t.c:15
瞧。
我正在尝试实现一个递归树函数,但出现段错误,因为该函数会自行调用,我想看看我的程序最后处于什么状态。
I would like to see what state my program is at the end.
运行 GDB下的程序,它会停止(当你的程序耗尽它的堆栈时)并且显示你最后的状态。
示例:
void fn(int j)
{
char buf[1024]; // consume some stack space.
buf[0] = 'a';
fn(j - buf[0]); // bad recursion -- should have checked for j - 'a' > 0
}
int main()
{
fn(10000);
return 0;
}
gcc -g t.c && gdb -q ./a.out
(gdb) run
Starting program: /tmp/a.out
Program received signal SIGSEGV, Segmentation fault.
0x0000555555555130 in fn (j=<error reading variable: Cannot access memory at address 0x7fffff7fef8c>) at t.c:2
2 {
(gdb) bt 10
#0 0x0000555555555130 in fn (j=<error reading variable: Cannot access memory at address 0x7fffff7fef8c>) at t.c:2
#1 0x0000555555555158 in fn (j=-759889) at t.c:5
#2 0x0000555555555158 in fn (j=-759792) at t.c:5
#3 0x0000555555555158 in fn (j=-759695) at t.c:5
#4 0x0000555555555158 in fn (j=-759598) at t.c:5
#5 0x0000555555555158 in fn (j=-759501) at t.c:5
#6 0x0000555555555158 in fn (j=-759404) at t.c:5
#7 0x0000555555555158 in fn (j=-759307) at t.c:5
#8 0x0000555555555158 in fn (j=-759210) at t.c:5
#9 0x0000555555555158 in fn (j=-759113) at t.c:5
(More stack frames follow...)
你在这里看到的是程序最后的状态,即完全你在[=43]中要求的=],但不在标题中(在 body 和标题中提出 不同的 问题是一种不好的形式)。
Is there a way to break a program after it reaches a certain number of frames?
没有,但有各种近似值。
对于上面的测试程序,答案是微不足道的。由于 fn
不断调用自身,您可以在第 N 次调用时停止。例如。如果您想在递归达到 100 帧时停止,请执行以下操作:
(gdb) b fn
Breakpoint 1 at 0x1136: file t.c, line 4.
(gdb) ign 1 100
Will ignore next 100 crossings of breakpoint 1.
(gdb) run
Starting program: /tmp/a.out
Breakpoint 1, fn (j=300) at t.c:4
4 buf[0] = 'a';
(gdb) bt
#0 fn (j=300) at t.c:4
#1 0x0000555555555158 in fn (j=397) at t.c:5
#2 0x0000555555555158 in fn (j=494) at t.c:5
#3 0x0000555555555158 in fn (j=591) at t.c:5
#4 0x0000555555555158 in fn (j=688) at t.c:5
...
#99 0x0000555555555158 in fn (j=9903) at t.c:5
#100 0x0000555555555158 in fn (j=10000) at t.c:5
#101 0x0000555555555169 in main () at t.c:10
当fn
间接调用自身时,事情会变得更复杂(但如果循环的长度是固定的K,那么只需将N除以K)。
如果循环的长度不是固定的,或者如果某些调用 return(即不是每个调用都重复出现),那么达到 N 级深度会稍微复杂一些。最简单的方法是修改程序以在全局范围内保持递归计数。然后你可以简单地设置一个条件观察点。示例:
int recursion_count;
void fn(int j)
{
char buf[1024]; // consume some stack space.
recursion_count += 1;
buf[0] = 'a';
fn(j - buf[0]); // bad recursion -- should have checked for j - 'a' > 0
recursion_count -= 1;
}
int main()
{
fn(10000);
return 0;
}
gcc -g t.c && gdb -q ./a.out
(gdb) start
Temporary breakpoint 1 at 0x55555555517d: file t.c, line 15.
Starting program: /tmp/a.out
Temporary breakpoint 1, main () at t.c:15
15 fn(10000);
(gdb) p recursion_count
= 0
(gdb) watch recursion_count
Hardware watchpoint 2: recursion_count
(gdb) cond 2 recursion_count == 100
(gdb) c
Continuing.
Hardware watchpoint 2: recursion_count
Old value = 99
New value = 100
fn (j=397) at t.c:8
8 buf[0] = 'a';
(gdb) bt
#0 fn (j=397) at t.c:8
#1 0x0000555555555167 in fn (j=494) at t.c:9
#2 0x0000555555555167 in fn (j=591) at t.c:9
#3 0x0000555555555167 in fn (j=688) at t.c:9
...
#97 0x0000555555555167 in fn (j=9806) at t.c:9
#98 0x0000555555555167 in fn (j=9903) at t.c:9
#99 0x0000555555555167 in fn (j=10000) at t.c:9
#100 0x0000555555555187 in main () at t.c:15
瞧。