In GDB is it possible to give an address relative (in lines) from the start of a function?

喜夏-厌秋 提交于 2019-12-04 08:50:03

It's a longstanding request to add this to gdb. However, it doesn't exist right now. It's maybe sort of possible with Python, but perhaps not completely, as Python doesn't currently have access to all the breakpoint re-set events (so the breakpoint might work once but not on re-run or library load or some other inferior change).

However, the quoted text shows a nicer way -- use an probe point. These are so-called "SystemTap probe points", but in reality they're more like a generic ELF + GCC feature -- they originated from the SystemTap project but don't depend on it. These let you mark a spot in the source and easily put a breakpoint on it, regardless of other edits to the source. They are already used on linux distros to mark special spots in the unwinder and longjump runtime routines to make debugging work nicely in the presence of these.

I understand that this is an old question, but I still could not find a better solution even now in 2017. Here's a Python solution. Maybe it's not the most robust/cleanest one, but it works very well in many practical scenarios:

class RelativeFunctionBreakpoint (gdb.Breakpoint):
    def __init__(self, functionName, lineOffset):
        super().__init__(RelativeFunctionBreakpoint.calculate(functionName, lineOffset))

    def calculate(functionName, lineOffset):
        """
        Calculates an absolute breakpoint location (file:linenumber)
        based on functionName and lineOffset
        """
        # get info about the file and line number where the function is defined
        info = gdb.execute("info line "+functionName, to_string=True)
        # extract file name and line number 
        m = re.match(r'Line[^\d]+(\d+)[^"]+"([^"]+)', info)
        if not m:
            raise Exception('Failed to find function %s.' % functionName)
        line = int(m.group(1))+lineOffset #add the lineOffset
        fileName = m.group(2)
        return "%s:%d" % (fileName, line)

USAGE:

basic:

    RelativeFunctionBreakpoint("yourFunctionName", lineOffset=5)

custom breakpoint:

class YourCustomBreakpoint (RelativeFunctionBreakpoint):
    def __init__(self, funcName, lineOffset, customData):
        super().__init__(funcName, lineOffset)
        self.customData = customData
    def stop(self):
        # do something
        # here you can access self.customData
        return False   #or True if you want the execution to stop

Advantages of the solution

  • relatively fast, because the breakpoint is set only once, before the execution starts
  • robust to changes in the source file if they don't affect the function

Disadvatages

  • Of course, it's not robust to the edits in the function itself
  • Not robust to the changes in the output syntax of the info line funcName gdb command (probably there is a better way to extract the file name and line number)
  • other? you point out
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!