【问题标题】:How to print the current line of source at breakpoint in GDB and nothing else?如何在 GDB 的断点处打印当前的源代码行,仅此而已?
【发布时间】:2013-07-27 02:02:18
【问题描述】:

我想在gdb 中设置一个“滚动”断点;只打印带有一些信息的当前源代码行;然后继续。我从这样的事情开始:

break doSomething
commands
  continue
end

这会自行打印出来:

Breakpoint 1, doSomething () at myprog.c:55
55  void doSomething() {

我想删除“Breakpoint X ... at ...”消息,可以使用silent 完成 - 然后只打印源代码行;所以我尝试了:

break doSomething
commands
  silent
  list 
  continue
end

这个结果有 10 行列表,如下所示

50  // some comments
...
55  void doSomething() {
...
59  // other comments

问题是,说list 1 将再次给出10 行,只是从第一行开始;在执行list +0,+0 时,确实只会提供一行源代码 - 但行错误(在我的情况下,它给出了第 50 行)。

然后,我意识到可以通过使用程序计数器$pc 获取并打印当前程序地址 - 并且考虑到还可以列出程序地址,我尝试了这个:

break doSomething
commands
  silent
  #print $pc
  list *$pc,+0
  continue
end

这导致正确的源代码行 - 但由于某种原因,再次出现额外消息,这次是“ADDR 在 X ...”:

0x8048fe0 is in doSomething (myprog.c:55).
55  void doSomething() {

任何想法如何仅打印源代码行?

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

【问题讨论】:

    标签: gdb


    【解决方案1】:

    嗯,我想我用 gdb 的 Python 有更好的地方;现在我可以让输出看起来像这样(使用 gdb 7.3.50.20110806-cvs):

    [  56] 0x8048fe0         myprog.c:55    void doSomething() {
    [  56] 0x8049058         myprog.c:63    }
    

    在大多数情况下,我尝试使用Symbol-Tables-In-Python 来解决这个问题(结果也有一个关于这个的问题:gdb find memory address of line number)。

    但是,由于某种原因,当我使用“表示此对象的当前行号”的Symtab_and_line.line 时,它似乎没有改变?在上面的示例中,它是方括号中的第一个数字,并且始终位于 56(在两种情况下都是错误的)。人们会希望 API 能够涵盖所有内容。虽然行号在那里(尽管错了?) - 我在任何地方都找不到相应源代码行的字符串内容,作为对象属性。另一方面,当我根据 OP 使用 gdb.execute("list *$pc,+0") 直接查询 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 print(gdb.execute("list *$pc,+0", False, True).splitlines()[1])
    猜你喜欢
    • 1970-01-01
    • 2019-03-10
    • 2015-12-26
    • 2013-01-12
    • 2011-03-08
    • 1970-01-01
    • 2011-10-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多