有没有办法在gdb中设置一个断点,该断点是以调用堆栈为条件的? 我在Linux上调试GDB 7.1中的C++。

有没有办法在gdb中设置一个断点,该断点是以调用堆栈为条件的? 我在Linux上调试GDB 7.1中的C++。,c++,gdb,breakpoints,callstack,C++,Gdb,Breakpoints,Callstack,我有一个函数a()。我想在其中设置一个断点,但前提是它是从b()调用的。有什么办法吗 只有在从c()调用b()时,才能无限期地执行此操作吗?不知道gdb如何执行此操作。 但您可以声明全局变量,如: bool call_a = false; 当b打电话给a时 call_a = true; a(); 当其他函数调用a()或在断点之后调用时,将call_a设置为false 然后使用条件断点 break [line-number] if call_a == true 不知道gdb如何做。 但

我有一个函数
a()。我想在其中设置一个断点,但前提是它是从
b()
调用的。有什么办法吗


只有在从
c()
调用
b()
时,才能无限期地执行此操作吗?

不知道gdb如何执行此操作。
但您可以声明全局变量,如:

bool call_a = false;
当b打电话给a时

call_a = true;   
a();
当其他函数调用a()或在断点之后调用时,将call_a设置为false

然后使用条件断点

break [line-number] if call_a == true

不知道gdb如何做。
但您可以声明全局变量,如:

bool call_a = false;
当b打电话给a时

call_a = true;   
a();
当其他函数调用a()或在断点之后调用时,将call_a设置为false

然后使用条件断点

break [line-number] if call_a == true

更新:这个问题现在有一个解决方案:使用GDB
\u is\u调用者
便利功能

您描述的需求经常出现,通常是在
some\u utility\u fn
经常被调用的情况下,但您只对来自
some\u other\u fn
的调用感兴趣

您可能可以从CVS主干使用GDB中新的嵌入式Python支持来编写整个交互脚本

没有Python,您只能做有限的事情,但通常的技术是在
a()
上有一个禁用的断点,并通过附加到
b()
上的断点的命令启用它

以下是一个例子:

int a(int x)
{
  return x + 1;
}

int b()
{
  return a(1);
}

int call_a_lots()
{
  int i, sum = 0;
  for (i = 0; i < 100; i++)
    sum += a(i);
}

int main()
{
  call_a_lots();
  return b();
}

gcc -g t.c
gdb -q ./a.out
Reading symbols from /tmp/a.out...done.
(gdb) break a
Breakpoint 1 at 0x4004cb: file t.c, line 3.
(gdb) disable 1
(gdb) break b
Breakpoint 2 at 0x4004d7: file t.c, line 8.
(gdb) command 2
>silent
>enable 1
>continue
>end
(gdb) run

Breakpoint 1, a (x=1) at t.c:3
3     return x + 1;
(gdb) bt
#0  a (x=1) at t.c:3
#1  0x00000000004004e1 in b () at t.c:8
#2  0x000000000040052c in main () at t.c:21
(gdb) q
inta(intx)
{
返回x+1;
}
int b()
{
返回a(1);
}
int call_a_lots()
{
int i,和=0;
对于(i=0;i<100;i++)
总和+=a(i);
}
int main()
{
称为a_lots();
返回b();
}
gcc-g t.c
gdb-q./a.out
从/tmp/a.out读取符号…完成。
(gdb)中断a
0x4004cb处的断点1:文件t.c,第3行。
(gdb)禁用1
(gdb)中断b
0x4004d7处的断点2:文件t.c,第8行。
(gdb)命令2
>沉默的
>启用1
>继续
>结束
(gdb)运行
断点1,t.c:3处的a(x=1)
3返回x+1;
(gdb)英国电信
#t.c:3时的0 a(x=1)
#t.c:8处b()中的1 0x00000000004E1
#在t.c:21处,主管道中有2 0x000000000040052c()
(gdb)q

瞧:我们停止了从
b()
调用
a()
,忽略了之前对
a()
的100个调用更新:现在这个问题有一个答案:使用GDB
\u is\u调用者
便利函数

您描述的需求经常出现,通常是在
some\u utility\u fn
经常被调用的情况下,但您只对来自
some\u other\u fn
的调用感兴趣

您可能可以从CVS主干使用GDB中新的嵌入式Python支持来编写整个交互脚本

没有Python,您只能做有限的事情,但通常的技术是在
a()
上有一个禁用的断点,并通过附加到
b()
上的断点的命令启用它

以下是一个例子:

int a(int x)
{
  return x + 1;
}

int b()
{
  return a(1);
}

int call_a_lots()
{
  int i, sum = 0;
  for (i = 0; i < 100; i++)
    sum += a(i);
}

int main()
{
  call_a_lots();
  return b();
}

gcc -g t.c
gdb -q ./a.out
Reading symbols from /tmp/a.out...done.
(gdb) break a
Breakpoint 1 at 0x4004cb: file t.c, line 3.
(gdb) disable 1
(gdb) break b
Breakpoint 2 at 0x4004d7: file t.c, line 8.
(gdb) command 2
>silent
>enable 1
>continue
>end
(gdb) run

Breakpoint 1, a (x=1) at t.c:3
3     return x + 1;
(gdb) bt
#0  a (x=1) at t.c:3
#1  0x00000000004004e1 in b () at t.c:8
#2  0x000000000040052c in main () at t.c:21
(gdb) q
inta(intx)
{
返回x+1;
}
int b()
{
返回a(1);
}
int call_a_lots()
{
int i,和=0;
对于(i=0;i<100;i++)
总和+=a(i);
}
int main()
{
称为a_lots();
返回b();
}
gcc-g t.c
gdb-q./a.out
从/tmp/a.out读取符号…完成。
(gdb)中断a
0x4004cb处的断点1:文件t.c,第3行。
(gdb)禁用1
(gdb)中断b
0x4004d7处的断点2:文件t.c,第8行。
(gdb)命令2
>沉默的
>启用1
>继续
>结束
(gdb)运行
断点1,t.c:3处的a(x=1)
3返回x+1;
(gdb)英国电信
#t.c:3时的0 a(x=1)
#t.c:8处b()中的1 0x00000000004E1
#在t.c:21处,主管道中有2 0x000000000040052c()
(gdb)q

瞧:我们已经停止了从
b()
调用
a()
,忽略了之前对
a()

的100个调用。我已经在已经可用的gdb 7.6上测试了这一点,但它在gdb 7.2上不起作用,可能在gdb 7.1上也不起作用:

这就是main.cpp:

int a()
{
  int p = 0;
  p = p +1;
  return  p;
}

int b()
{
  return a();
}

int c()
{
  return a();
}

int main()
{
  c();
  b();
  a();
  return 0;
}
然后是g++-g main.cpp

这是我的支票:

class MyBreakpoint (gdb.Breakpoint):
    def stop (self):
        if gdb.selected_frame().older().name()=="b":
          gdb.execute("bt")
          return True
        else:
          return False

MyBreakpoint("a")
这就是它的工作原理:

4>gdb -q -x my_check.py ./a.out
Reading symbols from /home/a.out...done.
Breakpoint 1 at 0x400540: file main.cpp, line 3.
(gdb) r
Starting program: /home/a.out
#0  a () at main.cpp:3
#1  0x0000000000400559 in b () at main.cpp:10
#2  0x0000000000400574 in main () at main.cpp:21

Breakpoint 1, a () at main.cpp:3
3         int p = 0;
(gdb) c
Continuing.
[Inferior 1 (process 16739) exited normally]
(gdb) quit

我已经在已经可用的gdb 7.6上对此进行了测试,但它在gdb 7.2上不起作用,可能在gdb 7.1上也不起作用:

这就是main.cpp:

int a()
{
  int p = 0;
  p = p +1;
  return  p;
}

int b()
{
  return a();
}

int c()
{
  return a();
}

int main()
{
  c();
  b();
  a();
  return 0;
}
然后是g++-g main.cpp

这是我的支票:

class MyBreakpoint (gdb.Breakpoint):
    def stop (self):
        if gdb.selected_frame().older().name()=="b":
          gdb.execute("bt")
          return True
        else:
          return False

MyBreakpoint("a")
这就是它的工作原理:

4>gdb -q -x my_check.py ./a.out
Reading symbols from /home/a.out...done.
Breakpoint 1 at 0x400540: file main.cpp, line 3.
(gdb) r
Starting program: /home/a.out
#0  a () at main.cpp:3
#1  0x0000000000400559 in b () at main.cpp:10
#2  0x0000000000400574 in main () at main.cpp:21

Breakpoint 1, a () at main.cpp:3
3         int p = 0;
(gdb) c
Continuing.
[Inferior 1 (process 16739) exited normally]
(gdb) quit

arm的一个简单方法是:

在您感兴趣的函数中设置断点

break a
将gdb命令附加到该断点

command 1
 up 1
 if $lr == 0x12345678
  echo match \n
  down 1
 else
  echo no match \n
  echo $lr \n
  down 1
  cont 
 end 
end 
当您到达函数a()时,该命令会临时弹出一个堆栈帧,从而更新链接寄存器。当调用方不是执行方时,可以继续使用调用方链接寄存器值 你需要的路径


享受。

手臂的一个简单方法是:

在您感兴趣的函数中设置断点

break a
将gdb命令附加到该断点

command 1
 up 1
 if $lr == 0x12345678
  echo match \n
  down 1
 else
  echo no match \n
  echo $lr \n
  down 1
  cont 
 end 
end 
当您到达函数a()时,该命令会临时弹出一个堆栈帧,从而更新链接寄存器。当调用方不是执行方时,可以继续使用调用方链接寄存器值 你需要的路径


享受。

比Python脚本更简单的解决方案是使用

看起来是这样的:

b ParentFunction
command 1
  tb FunctionImInterestedIn
  c
end
每次闯入
ParentFunction
,您都会在您真正感兴趣的函数上设置一个一次性断点,然后继续运行(大概直到达到该断点为止)


由于在
FunctionImInterestedIn
上只中断一次,因此,如果在
ParentFunction
的上下文中多次调用
FunctionImInterestedIn
,并且希望在每次调用时中断,这将不起作用。

比Python脚本更简单的解决方案是使用

看起来是这样的:

b ParentFunction
command 1
  tb FunctionImInterestedIn
  c
end
每次闯入
ParentFunction
,您都会在您真正感兴趣的函数上设置一个一次性断点,然后继续运行(大概直到达到该断点为止)

由于在
函数iminterested中只中断一次,因此