主题行基本上都说明了一切。
如果我根据文件和行号给出位置,那么如果我编辑文件,该值可能会改变。事实上,如果我在重构期间编辑多个函数,它往往会经常变化并且不方便。但是,如果相对于函数的开头是(line-),它就不太可能改变。
如果不能从函数的开头给出行偏移量,那么是否可以使用便利变量来模拟它?即如果我要声明映射到特定函数开头的便利变量(我会不断更新的列表)?
根据help break
似乎似乎没有,但我认为我最好还是要确定。
(gdb) help break
Set breakpoint at specified line or function.
break [PROBE_MODIFIER] [LOCATION] [thread THREADNUM] [if CONDITION]
PROBE_MODIFIER shall be present if the command is to be placed in a
probe point. Accepted values are `-probe' (for a generic, automatically
guessed probe type) or `-probe-stap' (for a SystemTap probe).
LOCATION may be a line number, function name, or "*" and an address.
If a line number is specified, break at start of code for that line.
If a function is specified, break at start of code for that function.
If an address is specified, break at that exact address.
With no LOCATION, uses current execution address of the selected
stack frame. This is useful for breaking on return to a stack frame.
THREADNUM is the number from "info threads".
CONDITION is a boolean expression.
Multiple breakpoints at one place are permitted, and useful if their
conditions are different.
Do "help breakpoints" for info on other commands dealing with breakpoints.
答案 0 :(得分:5)
将这个添加到gdb是一个长期的要求。但是,它现在不存在。使用Python可能有点可能,但也许并不完全,因为Python目前无法访问所有断点重置事件(因此断点可能只运行一次,但不会重新运行或库加载或其他一些劣质更改)。
但是,引用的文本显示了更好的方法 - 使用探测点。这些是所谓的“SystemTap探测点”,但实际上它们更像是通用的ELF + GCC功能 - 它们来自SystemTap项目,但不依赖于它。这些允许您在源中标记一个点并轻松地在其上放置断点,而不管源的其他编辑。它们已经在linux发行版中用于标记unwinder和longjump运行时例程中的特殊位置,以便在存在这些例程的情况下很好地进行调试。
答案 1 :(得分:0)
我知道这是一个老问题,但即使是在2017年我仍然找不到更好的解决方案。这是一个Python解决方案。也许它不是最强大/最干净的,但它在许多实际场景中都能很好地运作:
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 强>:
基本:
RelativeFunctionBreakpoint("yourFunctionName", lineOffset=5)
自定义断点:
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
解决方案的优势
<强> Disadvatages 强>