在gdb中如何在任何具有特定单词的行上设置断点?

时间:2015-12-30 05:51:59

标签: c gdb breakpoints

我希望我的程序在gdb下执行,
在执行任何代码行之前,检查行是否有特定的单词示例宏名称或变量名称或任何特定单词,如果有,则停止执行。
如果可以使用正则表达式完成,那就更好了。

我知道有一个命令rbreakrb但是在匹配的函数名称上设置了断点,这不是我想要的。

有可能吗?

3 个答案:

答案 0 :(得分:5)

在gdb之外,您可以先搜索源并列出断点,然后使用-x标志调用gdb来设置这些断点。

<强>计划

  
      
  • grep over source for user-defined patterns(例如,erase,delete)
  •   
  • 根据以上行号生成break语句,将这些语句写入文件
  •   
  • 使用-x标志调用gdb并使用break语句指向生成的文件
  •   

man gdb

   ...
   -x file
       Execute GDB commands from file file.
   ...

<强> write_breakpoints.sh

#!/bin/bash

sourcename="$1";
patterns="$2";
outbreaks="$3";

grep -En "$2" "$1" | \
  cut -d: -f1 | \
  sed "s/^\(.\+\)$/break $1:\1/g" 1>>"$3";

<强> example.c

#include <stdio.h> 

void delete()
{
  printf("!! data is being deleted..\n");
}

void erase()
{
  printf("!! data is being erased..\n");
}

int main(void)
{
  printf("this line is safe..\n");
  erase();
  delete();
  return 0;
}

<强>使用

$ gcc -g example.c -o example
$ ./write_breakpoints.sh example.c "(delete|erase)" "breakpoints.txt"

$ gdb -x breakpoints.txt example
GNU gdb (Ubuntu 7.7.1-0ubuntu5~14.04.2) 7.7.1
Copyright (C) 2014 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from example...done.
Breakpoint 1 at 0x400531: file example.c, line 3.
Breakpoint 2 at 0x400531: file example.c, line 5.
Breakpoint 3 at 0x400541: file example.c, line 8.
Breakpoint 4 at 0x400541: file example.c, line 10.
Breakpoint 5 at 0x40055b: file example.c, line 16.
Breakpoint 6 at 0x400565: file example.c, line 17.
(gdb) run
Starting program: /path/to/example 
this line is safe..

Breakpoint 5, main () at example.c:16
16    erase();
(gdb) c
Continuing.

Breakpoint 3, erase () at example.c:10
10    printf("!! data is being erased..\n");
(gdb) c
Continuing.
!! data is being erased..

Breakpoint 6, main () at example.c:17
17    delete();
(gdb) c
Continuing.

Breakpoint 1, delete () at example.c:5
5     printf("!! data is being deleted..\n");
(gdb) c
Continuing.
!! data is being deleted..
[Inferior 1 (process 26130) exited normally]
(gdb) quit

备注

  • 可以使用多个源文件调用write_breakpoints(因为它附加了break语句)
  • 也可以使用forward-search和b
  • 在gdb中执行此操作

答案 1 :(得分:0)

  

有可能吗?

没有

GDB在所有的 。它只是在某些位置插入断点,然后全速运行程序,直到其中一个断点被击中。

您要求的是GDB重复执行next命令,然后如果您所在的行与正则表达式不匹配则有条件地继续。我不确定它是否可以编写脚本,但即使是这样,对于任何非平凡的程序来说,这将是不切实际的慢

答案 2 :(得分:0)

基于@ amdixon的回答,我写了一个对git repos友好的单行(并且不会很难修改svn,merc等)它可以是从repo根目录或任何子目录运行。

git ls-files '*.cpp' -z | xargs -n1 -P4 -0 awk -v wd=$(pwd) '/[REGEX]/ {print "break \"" wd "/" FILENAME ":" NR "\""}' >outbreak

[REGEX]是你的正则表达式。该文件可以从任何目录运行,所以在我的情况下:

mv outbreak /pathToExecutable
cd !$
cgdb -x outbreak executable

<强>解释

-z-0\"都是处理路径中的空格/ eols。 -n1导致awk一次解析一个文件(否则行号将是错误的,因为它会像巨型glob一样对待它)。 P4允许awk一次运行4个进程(速度 - 可选)。 -v wd=$(pwd)将工作目录传递给awk,wdFILENAMENR是awk内置。