如何在GDB中的断点处打印源的当前行而不打印其他内容?

如何在GDB中的断点处打印源的当前行而不打印其他内容?,gdb,Gdb,我想在gdb中设置一个“滚动”断点;这里只需打印当前源行和一些信息;然后继续。我从以下内容开始: break doSomething commands continue end 它自己打印出: Breakpoint 1, doSomething () at myprog.c:55 55 void doSomething() { 我想删除“Breakpoint X…at…”消息,这可以通过静默-完成,然后只打印出源代码行;所以我试着: break doSomething commands

我想在
gdb
中设置一个“滚动”断点;这里只需打印当前源行和一些信息;然后继续。我从以下内容开始:

break doSomething
commands
  continue
end
它自己打印出:

Breakpoint 1, doSomething () at myprog.c:55
55  void doSomething() {
我想删除“Breakpoint X…at…”消息,这可以通过
静默
-完成,然后只打印出源代码行;所以我试着:

break doSomething
commands
  silent
  list 
  continue
end
这将产生10行清单,如下所示

50  // some comments
...
55  void doSomething() {
...
59  // other comments
问题是,说
列表1
将再次给出10行,仅从第一行开始;当执行
list+0时,+0实际上只提供一行源代码-但行错误(在我的例子中,它给出了第50行)

因此,我意识到可以使用程序计数器
$pc
,获取并打印当前程序地址,并且可以在程序地址周围列出,因此我尝试了以下方法:

break doSomething
commands
  silent
  #print $pc
  list *$pc,+0
  continue
end
这会产生正确的源代码行-但出于某种原因,再次显示一条额外的消息,这一次是“ADDR在X中…”:

有没有办法只打印源代码行


作为一个子问题-是否可以以某种方式捕获
list
命令的输出,并将其用作gdb脚本方言中
printf
的参数?(我非常确定捕获
gdb
命令输出可以通过python-gdb脚本完成)

好吧,我想我用gdb的python做得更好了;现在我可以得到如下输出(使用gdb 7.3.50.20110806-cvs):

在大多数情况下,我试图用它来解决这个问题(结果也有一个关于这个的问题:)

但是,由于某种原因,当我使用“指示此对象的当前行号”的
Symtab\u和\u line.line
时,它似乎没有改变?在上面的示例中,它是方括号中的第一个数字,并且始终位于56(在这两种情况下都是错误的)。人们希望API能够涵盖所有这些内容;虽然行号在那里(尽管是错的?),但作为对象属性,我在任何地方都找不到相应源代码行的字符串内容。另一方面,当我使用
gdb.execute(“list*$pc,+0”)
根据OP直接查询
gdb
当前行时,我得到了正确的行号-但随后,我必须在Python中额外拆分和解析字符串
:/

不过,总比没有好——下面是(嵌入gdb脚本中的Python)代码;把它扔进你的
.gdbinit

python

# example: these breakpoints do stop - but cannot change their 
# stop method (which contains the "commands" for breakpoint in python)
#ax = gdb.Breakpoint("doSomething")
#print("hello", ax)
#print(dir(ax))
#print(ax.expression, ax.condition, ax.commands) # not writable!
#bx = gdb.Breakpoint("myprog.c:63")

# anything more than that - need to subclass:

class MyBreakpoint(gdb.Breakpoint):
  def __init__(self, spec, command=""):
    super(MyBreakpoint, self).__init__(spec, gdb.BP_BREAKPOINT,
                                             internal = False)
    self.command = command # not used

  def stop(self):
    # gdb.write - like print
    # gdb.decode_line() - like gdb.find_pc_line(pc)

    current_line = gdb.decode_line()
    symtline = current_line[1][0]
    #print(current_line, symtline.is_valid(), symtline.line , symtline.pc , symtline.symtab )

    sysy = symtline.symtab
    #print(sysy.filename, sysy.fullname(), sysy.is_valid() )

    sysyo = sysy.objfile
    #print(sysyo.filename, sysyo.is_valid(), sysyo.pretty_printers)
    ###print(gdb.solib_name()) # this breaks stuff??!

    sourcefilename = sysy.filename
    sourcefullpath = sysy.fullname()
    sourcelinenum = symtline.line   # somehow, it may be offset by 1, from what "list *$pc says"

    listingline = gdb.execute("list *$pc,+0", to_string=True)
    #print( "BREAK at %s:%d -- %s" % (sourcefilename, sourcelinenum, listingline) )

    llsplit = listingline.split("\n")
    listpreamble, gdbsourceline = llsplit[:2]
    addr, noneed, noneed, funcname, fileloc = listpreamble.split(" ")[:5]
    #linenum, sourceline = gdbsourceline.split("\t")[:2] # not using these - put gdb line verbatim

    outline = "[% 4s] %s % 16s:%s" % (sourcelinenum, addr, sourcefilename[-16:], gdbsourceline)
    print(outline)
    return False # continue (do not stop inferior)

ax = MyBreakpoint("doSomething")
bx = MyBreakpoint("myprog.c:63")
end

run
另外:python打印(gdb.execute(“list*$pc,+0”,False,True)。splitlines()[1])
[  56] 0x8048fe0         myprog.c:55    void doSomething() {
[  56] 0x8049058         myprog.c:63    }
python

# example: these breakpoints do stop - but cannot change their 
# stop method (which contains the "commands" for breakpoint in python)
#ax = gdb.Breakpoint("doSomething")
#print("hello", ax)
#print(dir(ax))
#print(ax.expression, ax.condition, ax.commands) # not writable!
#bx = gdb.Breakpoint("myprog.c:63")

# anything more than that - need to subclass:

class MyBreakpoint(gdb.Breakpoint):
  def __init__(self, spec, command=""):
    super(MyBreakpoint, self).__init__(spec, gdb.BP_BREAKPOINT,
                                             internal = False)
    self.command = command # not used

  def stop(self):
    # gdb.write - like print
    # gdb.decode_line() - like gdb.find_pc_line(pc)

    current_line = gdb.decode_line()
    symtline = current_line[1][0]
    #print(current_line, symtline.is_valid(), symtline.line , symtline.pc , symtline.symtab )

    sysy = symtline.symtab
    #print(sysy.filename, sysy.fullname(), sysy.is_valid() )

    sysyo = sysy.objfile
    #print(sysyo.filename, sysyo.is_valid(), sysyo.pretty_printers)
    ###print(gdb.solib_name()) # this breaks stuff??!

    sourcefilename = sysy.filename
    sourcefullpath = sysy.fullname()
    sourcelinenum = symtline.line   # somehow, it may be offset by 1, from what "list *$pc says"

    listingline = gdb.execute("list *$pc,+0", to_string=True)
    #print( "BREAK at %s:%d -- %s" % (sourcefilename, sourcelinenum, listingline) )

    llsplit = listingline.split("\n")
    listpreamble, gdbsourceline = llsplit[:2]
    addr, noneed, noneed, funcname, fileloc = listpreamble.split(" ")[:5]
    #linenum, sourceline = gdbsourceline.split("\t")[:2] # not using these - put gdb line verbatim

    outline = "[% 4s] %s % 16s:%s" % (sourcelinenum, addr, sourcefilename[-16:], gdbsourceline)
    print(outline)
    return False # continue (do not stop inferior)

ax = MyBreakpoint("doSomething")
bx = MyBreakpoint("myprog.c:63")
end

run