【问题标题】:In gdb how to set breakpoint on any line that has a particular word?在 gdb 中,如何在具有特定单词的任何行上设置断点?
【发布时间】:2015-12-30 05:51:58
【问题描述】:

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

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

那么有可能吗?

【问题讨论】:

    标签: c gdb breakpoints


    【解决方案1】:

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

    计划

    • grep 覆盖用户定义模式的源(例如,擦除、删除)
    • 根据以上行号生成break语句,写入文件
    • 使用 -x 标志调用 gdb 并使用 break 语句指向生成的文件

    ma​​n 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 语句)
    • 也可以在 gdb 中使用 forward-search 和 b 进行此操作

    【讨论】:

      【解决方案2】:

      有可能吗?

      没有。

      GDB 根本不会查看您的源代码。它只是在某些位置插入断点,然后全速运行程序,直到命中其中一个断点。

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

      【讨论】:

        【解决方案3】:

        根据@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 一次解析一个文件(否则行号将是错误的,因为它会将其视为一个巨大的球体)。 P4 允许 awk 一次运行 4 个进程(为了速度——可选)。 -v wd=$(pwd) 将工作目录传递给 awk,因为 wdFILENAMENR 是 awk 内置函数。

        【讨论】:

          猜你喜欢
          • 2021-04-01
          • 2018-12-15
          • 1970-01-01
          • 1970-01-01
          • 2020-02-25
          • 1970-01-01
          • 2022-01-21
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多