如何在GDB中自动打印每一行,直到到达给定的断点?

时间:2022-01-06 21:25:55

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".

我希望能够在GDB中设置一个断点,并让它运行到那个点——在这个过程中,打印出它已经“穿过”的行。

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):

要开始会话,我需要运行(r)程序,程序在第一个断点(main)处停止:

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

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

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:

此时-例如,我可以点击continue (c);这个过程将会运行,而不是输出任何东西,并在要求的行上中断:

(gdb) c
Continuing.

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

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

另一方面,不是继续,我可以逐行逐行,或者使用步骤(s)或next (n);例如:

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) 

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 :)

无论如何,我知道我可以继续输入,并且最后一个输入命令(步骤或下一个)会重复(在第二个例子中留一个长一点的会话,以显示“下一个”仍然在相同的级别上,在被调用的函数内的“步骤”步骤)。然而,正如我们所看到的,这取决于是走一步还是下一段路,可能需要一段时间才能达到结果——所以,我不想把手放在Enter按钮上坐上10分钟:

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?

因此,我的问题是——我是否可以指示gdb在没有进一步用户干预的情况下运行到“断点2”——同时打印它所经过的行,就像按了step(或next)一样?

4 个解决方案

#1


17  

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.

嗯,这并不容易,但我想我有点明白了:)我经历了很多失败的尝试(贴在这里);相关代码如下。

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 7.2-1ubuntu11(适用于Ubuntu 11.04)。结果是这样的:

  • 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)
  • 我首先发现了便利变量,并认为——考虑到有程序计数器之类的可用变量,必须有一些GDB便利变量来提供“断点”状态,并且可以直接在GDB脚本中使用。但是,在查看了一段时间的GDB引用索引之后,我根本找不到任何这样的变量(我的尝试是在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")
  • 在缺少这样的“断点状态”内部变量时,惟一要做的事情是将GDB(响应命令)的命令行输出捕获为字符串,并解析它(查找“断点”)
  • 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:
    • 因此,首先我尝试创建一个使用gdb的脚本(pygdb-nub.py,gdbwrap)。按照建议的方式执行;在这里失败——因为这个:Bug 627506 - python: gdb.execute([……, to_string=True)部分打印到stdout/stderr Bug 10808 -允许GDB/Python API捕获和存储GDB输出
    • Then, I thought I'd use a python script to subprocess.Popen the GDB program, while replacing its stdin and stdout; and then proceed controlling GDB from there (pygdb-sub.py) - that failed too... (apparently, because I didn't redirect stdin/out right)
    • 然后,我想我应该使用python脚本进行子进程。弹出GDB程序,同时替换它的stdin和stdout;然后从那里继续控制GDB (pygdb-sub.py)——这也失败了……(显然,因为我没有正确地重定向stdin/out)
    • Then, I thought I'd use python scripts to be called from GDB (via source) which would internally fork into a pty whenever gdb.execute should be called, so as to capture its output (pygdb-fork.gdb,pygdb-fork.py)... This almost worked - as there are strings returned; however GDB notices something ain't right: "[tcsetpgrp failed in terminal_inferior: Operation not permitted]", and the subsequent return strings don't seem to change.
    • 然后,我想我应该使用python脚本从GDB(通过源代码)调用,GDB会在GDB时在内部将其转换为pty。应该调用execute,以便捕获其输出(pygdb-fork.gdb、pygdb-fork.py)…这几乎是可行的——因为有返回的字符串;然而,GDB注意到有些事情是不对的:“tcsetpgrp在终止时失败了:操作不允许”,而随后的返回字符串似乎没有改变。
  • 然后,我发现了Python API到GDB,以及GDB。执行(“CMDSTR”,toString=True)命令——这似乎正是捕获输出所需要的:“默认情况下,命令生成的任何输出都被发送到gdb的标准输出。如果to_string参数为True,则gdb将收集输出。执行并作为字符串[1]返回!因此,首先我尝试创建一个使用gdb的脚本(pygdb-nub.py,gdbwrap)。按照建议的方式执行;在这里失败——因为这个:Bug 627506 - python: gdb.execute([……, to_string=True)部分输出到stdout/stderr Bug 10808 -允许GDB/Python API捕获和存储GDB输出,然后,我想我应该使用Python脚本进行子进程。弹出GDB程序,同时替换它的stdin和stdout;然后从那里继续控制GDB (pygdb-sub.py)——这也失败了……(显然,因为我没有正确地重定向stdin/out)然后,我想我应该使用python脚本从GDB(通过源代码)调用,GDB会在GDB时在内部将其插入到pty中。应该调用execute,以便捕获其输出(pygdb-fork.gdb、pygdb-fork.py)…这几乎是可行的——因为有返回的字符串;然而,GDB注意到有些事情是不对的:“tcsetpgrp在终止时失败了:操作不允许”,而随后的返回字符串似乎没有改变。

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.

最后,有效的方法是:临时重定向GDB输出。执行到RAM中的日志文件(Linux: /dev/shm);然后读取它,解析它并从python中打印它——python还处理一个简单的while循环,直到到达断点。

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 :)

具有讽刺意味的是,大多数这些错误,通过重定向logfile导致了这个解决方案,实际上是最近在SVN中修复的;这意味着这些将在不久的将来传播到发行版,并且人们将能够使用gdb。直接执行(“CMDSTR”,toString=True):/然而,由于我现在不能冒险从源代码构建GDB(并且可能会遇到新的不兼容),这对我来说也足够了:

 

 

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

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

pygdb-logg.gdb is:

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 is:

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

 

 

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:

基本上,pygdb-logg。gdb加载pygdb-logg。py python脚本,为nextUntilBreakpoint设置别名nub,并初始化会话——其他一切都由python脚本处理。这是一个关于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)

... 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 :) EDIT: version of avr-gdb in Ubuntu 11.04 is currently 6.4, which doesn't recognize the python command :()

…正如我想要的:P只是不知道它有多可靠(以及是否有可能在avr-gdb中使用,这正是我需要的:)

 

 

Well, hope this helps someone,
Cheers!

希望这能帮到别人,干杯!

 

 

Here some references:

这里一些参考:

#2


3  

Based on the link in @sdaau's answer (http://www.mail-archive.com/gdb@gnu.org/msg00031.html), I created my own script to simply keep sending 's' and reading the output of gdb continuously, while printing output to textfile and terminal, of course, my script can be modified to fit anyone else's needs, however, I hope that the modification I made should fit most people needs.

基于链接@sdaau的回答(http://www.mail-archive.com/gdb@gnu.org/msg00031.html),我创建了自己的脚本将发送“s”保存和阅读gdb不断的输出,同时打印输出文本文件和终端,当然,我的脚本可以修改以适应别人的需求,然而,我希望我做的修改应该符合大多数人的需要。

http://www.codeground.net/coding/gdb-step-into-all-lines-to-get-full-application-flow/

http://www.codeground.net/coding/gdb-step-into-all-lines-to-get-full-application-flow/

wget http://www.codeground.net/downloads/gdbwalkthrough.c
gcc gdbwalkthrough.c -o gdbwalkthrough
./gdbwalkthrough <application full path> [application arguments]

#3


3  

What about doing it like this in gdb, using a command file. Change file argument, and loop count as required.

如何使用命令文件在gdb中这样做呢?更改文件参数,并按需要循环计数。

gdb -x run.gdb

run.gdb:

run.gdb:

set pagination off
set logging file gdb.log
set logging on
set $i = 0
file main
break main
break WriteData
# sadly, commands not getting executed on reaching breakpoint 2
commands 2
  set $i=1000
  print "commands 2 : %d",$i
end
run
while ( $i < 1000 )
  step
  # next
  # continue
  set $i = $i + 1
end

#4


1  

As a new answer, since the previous is already hogged :) Basically, if the point is to observe execution of source (and/or assembly) code lines as the program as running - as the motivation is often for me when looking into "automatic printout" -- then, basically, a very quick way is to use GDB TUI mode; I quote:

作为一个新回答,因为前面已经占据:)基本上,如果问题是观察执行源(和/或装配)代码行程序一样运行,动机常常为我当调查“自动打印输出”——然后,基本上,一个非常快速的方法是使用GDB TUI模式;我引用:

c - gdb behavior : value optimized out - Stack Overflow #1354762

c - gdb行为:值优化出-堆栈溢出#1354762。

Use the GDB TUI mode. My copy of GDB enables it when I type the minus and Enter. Then type C-x 2 (that is hold down Control and press X, release both and then press 2). That will put it into split source and disassembly display. Then use stepi and nexti to move one machine instruction at a time. Use C-x o to switch between the TUI windows.

使用GDB TUI模式。我的拷贝的GDB使它当我输入-和进入。然后输入C-x 2(按住Control键,按X键,同时释放,然后按2),这将把它放入分割源和拆卸显示中。然后使用stepi和nexti一次移动一个机器指令。使用C-x o在TUI窗口之间切换。

The trick here is that, even if you hit continue - this time source will be shown and indicated on the TUI; and followed as the program runs:

这里的诀窍是,即使你点击了继续-这个时间源将会在TUI中显示和显示;然后随着程序运行:

如何在GDB中自动打印每一行,直到到达给定的断点?

... and this for me avoids many situations where I'd have to script the breakpoints in "auto-stepping context" (although there are still such situations).. Docs about TUI: TUI - Debugging with GDB

…对于我来说,这避免了很多情况,我必须在“自动步进上下文”中编写断点(尽管仍然存在这种情况)。关于TUI的文档:TUI -与GDB的调试

Cheers!

干杯!

#1


17  

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.

嗯,这并不容易,但我想我有点明白了:)我经历了很多失败的尝试(贴在这里);相关代码如下。

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 7.2-1ubuntu11(适用于Ubuntu 11.04)。结果是这样的:

  • 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)
  • 我首先发现了便利变量,并认为——考虑到有程序计数器之类的可用变量,必须有一些GDB便利变量来提供“断点”状态,并且可以直接在GDB脚本中使用。但是,在查看了一段时间的GDB引用索引之后,我根本找不到任何这样的变量(我的尝试是在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")
  • 在缺少这样的“断点状态”内部变量时,惟一要做的事情是将GDB(响应命令)的命令行输出捕获为字符串,并解析它(查找“断点”)
  • 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:
    • 因此,首先我尝试创建一个使用gdb的脚本(pygdb-nub.py,gdbwrap)。按照建议的方式执行;在这里失败——因为这个:Bug 627506 - python: gdb.execute([……, to_string=True)部分打印到stdout/stderr Bug 10808 -允许GDB/Python API捕获和存储GDB输出
    • Then, I thought I'd use a python script to subprocess.Popen the GDB program, while replacing its stdin and stdout; and then proceed controlling GDB from there (pygdb-sub.py) - that failed too... (apparently, because I didn't redirect stdin/out right)
    • 然后,我想我应该使用python脚本进行子进程。弹出GDB程序,同时替换它的stdin和stdout;然后从那里继续控制GDB (pygdb-sub.py)——这也失败了……(显然,因为我没有正确地重定向stdin/out)
    • Then, I thought I'd use python scripts to be called from GDB (via source) which would internally fork into a pty whenever gdb.execute should be called, so as to capture its output (pygdb-fork.gdb,pygdb-fork.py)... This almost worked - as there are strings returned; however GDB notices something ain't right: "[tcsetpgrp failed in terminal_inferior: Operation not permitted]", and the subsequent return strings don't seem to change.
    • 然后,我想我应该使用python脚本从GDB(通过源代码)调用,GDB会在GDB时在内部将其转换为pty。应该调用execute,以便捕获其输出(pygdb-fork.gdb、pygdb-fork.py)…这几乎是可行的——因为有返回的字符串;然而,GDB注意到有些事情是不对的:“tcsetpgrp在终止时失败了:操作不允许”,而随后的返回字符串似乎没有改变。
  • 然后,我发现了Python API到GDB,以及GDB。执行(“CMDSTR”,toString=True)命令——这似乎正是捕获输出所需要的:“默认情况下,命令生成的任何输出都被发送到gdb的标准输出。如果to_string参数为True,则gdb将收集输出。执行并作为字符串[1]返回!因此,首先我尝试创建一个使用gdb的脚本(pygdb-nub.py,gdbwrap)。按照建议的方式执行;在这里失败——因为这个:Bug 627506 - python: gdb.execute([……, to_string=True)部分输出到stdout/stderr Bug 10808 -允许GDB/Python API捕获和存储GDB输出,然后,我想我应该使用Python脚本进行子进程。弹出GDB程序,同时替换它的stdin和stdout;然后从那里继续控制GDB (pygdb-sub.py)——这也失败了……(显然,因为我没有正确地重定向stdin/out)然后,我想我应该使用python脚本从GDB(通过源代码)调用,GDB会在GDB时在内部将其插入到pty中。应该调用execute,以便捕获其输出(pygdb-fork.gdb、pygdb-fork.py)…这几乎是可行的——因为有返回的字符串;然而,GDB注意到有些事情是不对的:“tcsetpgrp在终止时失败了:操作不允许”,而随后的返回字符串似乎没有改变。

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.

最后,有效的方法是:临时重定向GDB输出。执行到RAM中的日志文件(Linux: /dev/shm);然后读取它,解析它并从python中打印它——python还处理一个简单的while循环,直到到达断点。

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 :)

具有讽刺意味的是,大多数这些错误,通过重定向logfile导致了这个解决方案,实际上是最近在SVN中修复的;这意味着这些将在不久的将来传播到发行版,并且人们将能够使用gdb。直接执行(“CMDSTR”,toString=True):/然而,由于我现在不能冒险从源代码构建GDB(并且可能会遇到新的不兼容),这对我来说也足够了:

 

 

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

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

pygdb-logg.gdb is:

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 is:

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

 

 

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:

基本上,pygdb-logg。gdb加载pygdb-logg。py python脚本,为nextUntilBreakpoint设置别名nub,并初始化会话——其他一切都由python脚本处理。这是一个关于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)

... 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 :) EDIT: version of avr-gdb in Ubuntu 11.04 is currently 6.4, which doesn't recognize the python command :()

…正如我想要的:P只是不知道它有多可靠(以及是否有可能在avr-gdb中使用,这正是我需要的:)

 

 

Well, hope this helps someone,
Cheers!

希望这能帮到别人,干杯!

 

 

Here some references:

这里一些参考:

#2


3  

Based on the link in @sdaau's answer (http://www.mail-archive.com/gdb@gnu.org/msg00031.html), I created my own script to simply keep sending 's' and reading the output of gdb continuously, while printing output to textfile and terminal, of course, my script can be modified to fit anyone else's needs, however, I hope that the modification I made should fit most people needs.

基于链接@sdaau的回答(http://www.mail-archive.com/gdb@gnu.org/msg00031.html),我创建了自己的脚本将发送“s”保存和阅读gdb不断的输出,同时打印输出文本文件和终端,当然,我的脚本可以修改以适应别人的需求,然而,我希望我做的修改应该符合大多数人的需要。

http://www.codeground.net/coding/gdb-step-into-all-lines-to-get-full-application-flow/

http://www.codeground.net/coding/gdb-step-into-all-lines-to-get-full-application-flow/

wget http://www.codeground.net/downloads/gdbwalkthrough.c
gcc gdbwalkthrough.c -o gdbwalkthrough
./gdbwalkthrough <application full path> [application arguments]

#3


3  

What about doing it like this in gdb, using a command file. Change file argument, and loop count as required.

如何使用命令文件在gdb中这样做呢?更改文件参数,并按需要循环计数。

gdb -x run.gdb

run.gdb:

run.gdb:

set pagination off
set logging file gdb.log
set logging on
set $i = 0
file main
break main
break WriteData
# sadly, commands not getting executed on reaching breakpoint 2
commands 2
  set $i=1000
  print "commands 2 : %d",$i
end
run
while ( $i < 1000 )
  step
  # next
  # continue
  set $i = $i + 1
end

#4


1  

As a new answer, since the previous is already hogged :) Basically, if the point is to observe execution of source (and/or assembly) code lines as the program as running - as the motivation is often for me when looking into "automatic printout" -- then, basically, a very quick way is to use GDB TUI mode; I quote:

作为一个新回答,因为前面已经占据:)基本上,如果问题是观察执行源(和/或装配)代码行程序一样运行,动机常常为我当调查“自动打印输出”——然后,基本上,一个非常快速的方法是使用GDB TUI模式;我引用:

c - gdb behavior : value optimized out - Stack Overflow #1354762

c - gdb行为:值优化出-堆栈溢出#1354762。

Use the GDB TUI mode. My copy of GDB enables it when I type the minus and Enter. Then type C-x 2 (that is hold down Control and press X, release both and then press 2). That will put it into split source and disassembly display. Then use stepi and nexti to move one machine instruction at a time. Use C-x o to switch between the TUI windows.

使用GDB TUI模式。我的拷贝的GDB使它当我输入-和进入。然后输入C-x 2(按住Control键,按X键,同时释放,然后按2),这将把它放入分割源和拆卸显示中。然后使用stepi和nexti一次移动一个机器指令。使用C-x o在TUI窗口之间切换。

The trick here is that, even if you hit continue - this time source will be shown and indicated on the TUI; and followed as the program runs:

这里的诀窍是,即使你点击了继续-这个时间源将会在TUI中显示和显示;然后随着程序运行:

如何在GDB中自动打印每一行,直到到达给定的断点?

... and this for me avoids many situations where I'd have to script the breakpoints in "auto-stepping context" (although there are still such situations).. Docs about TUI: TUI - Debugging with GDB

…对于我来说,这避免了很多情况,我必须在“自动步进上下文”中编写断点(尽管仍然存在这种情况)。关于TUI的文档:TUI -与GDB的调试

Cheers!

干杯!