如何自动打印在GDB所有被执行直至达到一个给定的断点? [英] How to print every executed line in GDB automatically until a given breakpoint is reached?

查看:1615
本文介绍了如何自动打印在GDB所有被执行直至达到一个给定的断点?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望能够设置在GDB断点,并让它运行到这一点 - 在这个过程中,打印出它有行,通过加强

I would like to be able to set a breakpoint in GDB, and have it run to that point - and in the process, print out lines it has "stepped through".

下面是一个例子,基于这个简单的文件中的和功能,并为每个两个断点:

Here is an example, based on this simple file with a main and a function, and two breakpoints for each:

$ cat > test.c <<EOF
#include "stdio.h"

int count=0;

void doFunction(void) {
  // two steps forward
  count += 2;
  // one step back
  count--;
}

int main(void) {
  // some pointless init commands;
  count = 1;
  count += 2;
  count = 0;
  //main loop
  while(1) {
    doFunction();
    printf("%d\n", count);
  }
}
EOF

$ gcc -g -Wall test.c -o test.exe
$ chmod +x test.exe
$ gdb -se test.exe
...
Reading symbols from /path/to/test.exe...done.
(gdb) b main
Breakpoint 1 at 0x80483ec: file test.c, line 14.
(gdb) b doFunction
Breakpoint 2 at 0x80483c7: file test.c, line 7.

要启动会话,我需要运行(研究)的程序,然后将停止在第一个断点(

To start the session, I need to run (r) the program, which will then stop at first breakpoint (main):

(gdb) r
Starting program: /path/to/test.exe 

Breakpoint 1, main () at test.c:14
14    count = 1;
(gdb) 

在这一点 - 我可以,例如,继续打( C );这一过程将贯穿,没有任何允许输出,并在要求换行:

At this point - I can, for instance, hit continue (c); and the process will run through, not outputing anything, and break at the requested line:

(gdb) c
Continuing.

Breakpoint 2, doFunction () at test.c:7
7     count += 2;
(gdb)

在另一方面,而不是继续 - 我能,通过使用步骤(取值)或下( N <去逐行/ code>);例如:

On the other hand, instead of continue - I can go line by line, either by using step (s) or next (n); for instance:

14    count = 1;
(gdb) n
15    count += 2;
(gdb) s
16    count = 0;
(gdb) s
19      doFunction();
(gdb) s

Breakpoint 2, doFunction () at test.c:7
7     count += 2;
(gdb) s
9     count--;
(gdb) s
10  }
(gdb) s
main () at test.c:20
20      printf("%d\n", count);
(gdb) s
...
(gdb) s
_IO_vfprintf_internal (s=Cannot access memory at address 0xe5853361
) at vfprintf.c:210
210 vfprintf.c: No such file or directory.
    in vfprintf.c
(gdb) s
245 in vfprintf.c
(gdb) s
210 in vfprintf.c
(gdb) n
245 in vfprintf.c
...
(gdb) n
2006    in vfprintf.c
(gdb) n
__printf (format=0x80484f0 "%d\n") at printf.c:39
39  printf.c: No such file or directory.
    in printf.c
(gdb) n
main () at test.c:21
21    }
(gdb) n
19      doFunction();
(gdb) n

Breakpoint 2, doFunction () at test.c:7
7     count += 2;
(gdb) 

不管怎样,我知道我能保持<大骨节病>输入 pressed,最后输入的命令(步骤或下一个)将重复(在第二种情况下离开的时间长一点会,表明下一步保持在同一水平线上,在函数中一步的步骤被称为的)。但是,因为它可以看出,这取决于步或下次运行时,可能需要一段时间,直到达到一个结果 - 所以,我不想坐了10分钟,我的手停留在回车键:)

Anyways, I am aware that I can keep Enter pressed, and the last entered command (step or next) will repeat (left a bit longer session in the second case, to show that 'next' remains on same level, 'step' steps inside the functions being called). However, as it can be seen, depending on whether step or next runs, it may take a while until a result is reached - and so, I don't want to sit for 10 minutes with my hand stuck on the Enter button :)

所以,我的问题是 - 我能以某种方式指示<​​code> GDB 来运行断点2没有用户的进一步干预 - 在打印出来的线条它经历,仿佛步骤(或下一个)是pressed?

So, my question is - can I somehow instruct gdb to run to 'breakpoint 2' without further user intervention - while printing out the lines it goes through, as if step (or next) was pressed?

推荐答案

好了,这是不容易的 - 但我想我有点明白了:)我经历了一堆失败的尝试(发布的这里);有关code如下。

Well, this wasn't easy - but I think I somewhat got it :) I went through a bunch of failed attempts (posted here); relevant code is below.

基本上,一个下一个/步骤,直到断点的问题是如何判断你是否是关于断点与否,如果调试器停止(在步骤)。还要注意我用GDB 7.2-1ubuntu11(目前为Ubuntu 11.04)。因此,它是这样的:

Basically, the problem in a "next/step until breakpoint" is how to determine whether you're "on" a breakpoint or not, if the debugger is stopped (at a step). Note also I use GDB 7.2-1ubuntu11 (current for Ubuntu 11.04). So, it went like this:


  • 我第一次发现了大约便利的变量,并认为 - 鉴于有程序计数器和这样的可用的,必须有一些方便GDB变量给出了断点状态,并且可以在一个GDB脚本可直接使用。通过 GDB的参考指标找了一会儿,不过,我根本无法找到任何这样的变量(我尝试在 nub.gdb

  • 在缺少这样一个断点状态内部变量的 - 唯一剩下要做的,是捕获(响应命令)作为字符串(标准输出)的命令行GDB的输出,并解析它(寻找断点)

  • 然后,我发现了的Python API 以GDB,和 gdb.execute(CMDSTR的toString = TRUE)命令 - 这似乎是究竟什么是需要捕捉的输出:默认情况下,任何输出通过命令生成发送到GDB的标准输出。如果to_string参数为True,则输出将被gdb.execute收集并返回一个字符串[<一个href=\"http://sourceware.org/gdb/onlinedocs/gdb/Basic-Python.html#index-gdb_002eexecute-1597\">1]\"!

    • 所以,首先我试图让一个脚本( pygdb-nub.py gdbwrap ),将利用 gdb.execute 在推荐的方式;在这里失败 - 因为这样:
      • I first found about Convenience Variables, and thought - given there are program counters and such available, there must be some GDB convenience variable that gives the "breakpoint" status, and can be used directly in a GDB script. After looking through GDB reference Index for a while, however, I simply cannot find any such variables (my attempts are in nub.gdb)
      • In lack of such a "breakpoint status" internal variable - the only thing left to do, is to capture the ('stdout') command line output of GDB (in response to commands) as a string, and parse it (looking for "Breakpoint")
      • Then, I found out about Python API to GDB, and the gdb.execute("CMDSTR", toString=True) command - which is seemingly exactly what is needed to capture the output: "By default, any output produced by command is sent to gdb's standard output. If the to_string parameter is True, then output will be collected by gdb.execute and returned as a string[1]"!
        • So, first I tried to make a script (pygdb-nub.py,gdbwrap) that would utilize gdb.execute in the recommended manner; failed here - because of this:
          • Bug 627506 – python: gdb.execute([...], to_string=True) partly prints to stdout/stderr
          • Bug 10808 – Allow GDB/Python API to capture and store GDB output

          最后,这是工作的办法:从 gdb.execute 输出GDB暂时重定向到一个日志文件中的RAM(Linux的: /开发/ SHM );然后回读,解析它并从蟒蛇打印出来 - 蟒蛇也能处理一个简单的while循环步骤,直到到达断点

          And finally, the approach that worked is: temporarily redirecting the GDB output from a gdb.execute to a logfile in RAM (Linux: /dev/shm); and then reading it back, parsing it and printing it from python - python also handles a simple while loop that steps until a breakpoint is reached.

          具有讽刺意味的​​是 - 大多数这些错误,即通过重定向日志文件,实际上是最近固定SVN导致此解决方案;这意味着那些会传播到发行版在不久的将来,一个将能够使用 gdb.execute(CMDSTR的toString = TRUE)直接:/然而,正如我不能冒险从源代码构建GDB现在(和可能碰到可能的新的兼容性能),这是我不够好,也:)

          The irony is - most of these bugs, that caused this solution via redirecting the logfile, are actually recently fixed in SVN; meaning those will propagate to the distros in the near future, and one will be able to use gdb.execute("CMDSTR", toString=True) directly :/ Yet, as I cannot risk building GDB from source right now (and possibly bumping into possible new incompatibilites), this is good enough for me also :)

          &NBSP;

          下面是相关文件(部分也是在 pygdb-fork.gdb pygdb-fork.py ):

          Here are the relevant files (partially also in pygdb-fork.gdb,pygdb-fork.py):

          pygdb-logg.gdb 是:

          # gdb script: pygdb-logg.gdb
          # easier interface for pygdb-logg.py stuff
          # from within gdb: (gdb) source -v pygdb-logg.gdb
          # from cdmline: gdb -x pygdb-logg.gdb -se test.exe
          
          # first, "include" the python file:
          source -v pygdb-logg.py
          
          # define shorthand for nextUntilBreakpoint():
          define nub
            python nextUntilBreakpoint()
          end
          
          # set up breakpoints for test.exe:
          b main
          b doFunction
          
          # go to main breakpoint
          run
          

          pygdb-logg.py 是:

          # gdb will 'recognize' this as python
          #  upon 'source pygdb-logg.py'
          # however, from gdb functions still have
          #  to be called like:
          #  (gdb) python print logExecCapture("bt")
          
          import sys
          import gdb
          import os
          
          def logExecCapture(instr):
            # /dev/shm - save file in RAM
            ltxname="/dev/shm/c.log"
          
            gdb.execute("set logging file "+ltxname) # lpfname
            gdb.execute("set logging redirect on")
            gdb.execute("set logging overwrite on")
            gdb.execute("set logging on")
            gdb.execute(instr)
            gdb.execute("set logging off")
          
            replyContents = open(ltxname, 'r').read() # read entire file
            return replyContents
          
          # next until breakpoint
          def nextUntilBreakpoint():
            isInBreakpoint = -1;
            # as long as we don't find "Breakpoint" in report:
            while isInBreakpoint == -1:
              REP=logExecCapture("n")
              isInBreakpoint = REP.find("Breakpoint")
              print "LOOP:: ", isInBreakpoint, "\n", REP
          

          &NBSP;

          基本上, pygdb-logg.gdb 加载 pygdb-logg.py python脚本,设置别名要点 nextUntilBreakpoint ,并初始化会话 - 一切由python脚本处理。这里是一个示例会话 - 相对于在OP测试源:

          Basically, pygdb-logg.gdb loads the pygdb-logg.py python script, sets up the alias nub for nextUntilBreakpoint, and initializes the session - everything else is handled by the python script. And here is a sample session - in respect to the test source in OP:

          $ gdb -x pygdb-logg.gdb -se test.exe
          ...
          Reading symbols from /path/to/test.exe...done.
          Breakpoint 1 at 0x80483ec: file test.c, line 14.
          Breakpoint 2 at 0x80483c7: file test.c, line 7.
          
          Breakpoint 1, main () at test.c:14
          14    count = 1;
          (gdb) nub
          LOOP::  -1
          15    count += 2;
          
          LOOP::  -1
          16    count = 0;
          
          LOOP::  -1
          19      doFunction();
          
          LOOP::  1
          
          Breakpoint 2, doFunction () at test.c:7
          7     count += 2;
          
          (gdb) nub
          LOOP::  -1
          9     count--;
          
          LOOP::  -1
          10  }
          
          LOOP::  -1
          main () at test.c:20
          20      printf("%d\n", count);
          
          1
          LOOP::  -1
          21    }
          
          LOOP::  -1
          19      doFunction();
          
          LOOP::  1
          
          Breakpoint 2, doFunction () at test.c:7
          7     count += 2;
          
          (gdb)
          

          ...就像我想它:P​​只是不知道它是多么可靠(,以及是否将有可能在 AVR-GDB ,这正是我需要这个:)编辑:AVR-GDB的在Ubuntu 11.04版本目前6.4,不承认python命令:(的)

          ... just as I wanted it :P Just don't know how reliable it is (and whether it will be possible to use in avr-gdb, which is what I need this for :) version of avr-gdb in Ubuntu 11.04 is currently 6.4, which doesn't recognize the python command :()

          &NBSP;

          好了,希望这可以帮助别人,结果
          干杯!

          Well, hope this helps someone,
          Cheers!

          &NBSP;

          下面一些参考:

          • GDB: error detected on stdin
          • GDB has problems with getting commands piped to STDIN
          • Re: [Gdb] How do i use GDB other input?
          • gdb doesn't accept input on stdin
          • Using gdb in an IDE - comp.os.linux.development.apps | Google Groups
          • rmathew: Terminal Sickness
          • [TUTORIAL] Calling an external program in C (Linux) - GIDForums
          • shell - how to use multiple arguments with a shebang (i.e. #!)? - Stack Overflow
          • Redirecting/storing output of shell into GDB variable? - Stack Overflow
          • Corey Goldberg: Python - Redirect or Turn Off STDOUT and STDERR
          • The Cliffs of Inanity › 9. Scripting gdb
          • gdb python scripting: where has parse_and_eval gone? - Stack Overflow
          • shell - Invoke gdb to automatically pass arguments to the program being debugged - Stack Overflow
          • Storing Files/Directories In Memory With tmpfs | HowtoForge - Linux Howtos and Tutorials
          • simple way to touch a file if it does not exist | Python | Python
          • os.fork() different in cgi-script? - Python
          • java - Writing tests that use GDB - how to capture output? - Stack Overflow
          • Debugging with GDB: How to create GDB Commands in Python - Wiki
          • GDB reference card

          这篇关于如何自动打印在GDB所有被执行直至达到一个给定的断点?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆