Skip to main content

27.1. bdb —调试器框架

源代码: Lib/bdb.py


bdb 模块处理基本调试器功能,如设置断点或通过调试器管理执行。

定义了以下异常:

exception bdb.BdbQuit

Bdb 类提出的用于退出调试器的异常。

bdb 模块还定义了两个类:

class bdb.Breakpoint(self, file, line, temporary=0, cond=None, funcname=None)

此类实现临时断点,忽略计数,禁用和(重新)启用和条件。

断点通过名为 bpbynumber 的列表通过数字索引,通过 bplist 通过 (file, line) 对索引。前者指向 Breakpoint 类的单个实例。后者指向此类实例的列表,因为每行可能有多个断点。

创建断点时,其关联的文件名应为规范形式。如果定义了 funcname,当执行该函数的第一行时,将计算断点命中。条件断点总是计算命中。

Breakpoint 实例有以下方法:

deleteMe()

从与文件/行关联的列表中删除断点。如果它是该位置中的最后一个断点,它还会删除文件/行的条目。

enable()

将断点标记为已启用。

disable()

将断点标记为禁用。

bpformat()

返回一个包含断点的所有信息的字符串,格式很好:

  • 断点号。

  • 如果是临时的或不是。

  • 它的文件,行位置。

  • 导致中断的条件。

  • 如果必须忽略下一个N次。

  • 断点命中计数。

3.2 新版功能.

bpprint(out=None)

bpformat() 的输出打印到 out 文件,如果是 None,则打印到标准输出。

class bdb.Bdb(skip=None)

Bdb 类充当一个通用的Python调试器基类。

这个类负责跟踪设施的细节;派生类应该实现用户交互。标准调试器类(pdb.Pdb)就是一个例子。

skip 参数,如果给定,必须是可迭代的glob样式模块名称模式。调试器不会步入到源于与这些模式之一匹配的模块中的帧。帧是否被认为起源于特定模块由帧全局中的 __name__ 确定。

3.1 新版功能: skip 参数。

Bdb 的以下方法通常不需要被覆盖。

canonic(filename)

用于以规范形式获取文件名的辅助方法,即作为大小写标准化(在不区分大小写的文件系统上)绝对路径,剥离了周围的尖括号。

reset()

botframestopframereturnframequitting 属性设置为准备开始调试的值。

trace_dispatch(frame, event, arg)

此功能作为调试帧的跟踪功能安装。它的返回值是新的跟踪函数(在大多数情况下,也就是说,它自己)。

默认实现决定如何分派帧,具体取决于要执行的事件类型(作为字符串传递)。 event 可以是以下之一:

  • "line":将执行一行新代码。

  • "call":一个函数即将被调用,或者另一个代码块被输入。

  • "return":函数或其他代码块即将返回。

  • "exception":发生异常。

  • "c_call":C函数即将被调用。

  • "c_return":C函数已返回。

  • "c_exception":C函数引发了一个异常。

对于Python事件,调用专门的函数(见下文)。对于C事件,不采取任何操作。

arg 参数取决于先前的事件。

有关跟踪功能的更多信息,请参阅 sys.settrace() 文档。有关代码和框架对象的更多信息,请参阅 标准类型层次结构

dispatch_line(frame)

如果调试器应该在当前行上停止,调用 user_line() 方法(应在子类中重写)。如果设置了 Bdb.quitting 标志(可以从 user_line() 设置),则提高 BdbQuit 异常。返回对 trace_dispatch() 方法的引用,以便在该范围内进行进一步跟踪。

dispatch_call(frame, arg)

如果调试器应该在此函数调用上停止,调用 user_call() 方法(应在子类中重写)。如果设置了 Bdb.quitting 标志(可以从 user_call() 设置),则提高 BdbQuit 异常。返回对 trace_dispatch() 方法的引用,以便在该范围内进行进一步跟踪。

dispatch_return(frame, arg)

如果调试器应该停止在此函数返回,调用 user_return() 方法(应在子类中重写)。如果设置了 Bdb.quitting 标志(可以从 user_return() 设置),则提高 BdbQuit 异常。返回对 trace_dispatch() 方法的引用,以便在该范围内进行进一步跟踪。

dispatch_exception(frame, arg)

如果调试器应该停止在此异常,调用 user_exception() 方法(应在子类中重写)。如果设置了 Bdb.quitting 标志(可以从 user_exception() 设置),则提高 BdbQuit 异常。返回对 trace_dispatch() 方法的引用,以便在该范围内进行进一步跟踪。

通常派生类不会覆盖以下方法,但如果他们想重新定义停止和断点的定义,它们可能会被覆盖。

stop_here(frame)

此方法检查 frame 是否在调用堆栈中的 botframe 之下。 botframe 是调试开始的帧。

break_here(frame)

此方法检查文件名和行中是否存在属于 frame 的断点,或者至少在当前函数中。如果断点是临时断点,此方法将删除它。

break_anywhere(frame)

此方法检查当前帧的文件名中是否有断点。

派生类应该覆盖这些方法以获得对调试器操作的控制。

user_call(frame, argument_list)

当有可能在被调用函数内的任何地方可能需要中断时,从 dispatch_call() 调用此方法。

user_line(frame)

stop_here()break_here() 产生 True 时,从 dispatch_line() 调用此方法。

user_return(frame, return_value)

stop_here() 产生 True 时,从 dispatch_return() 调用该方法。

user_exception(frame, exc_info)

stop_here() 产生 True 时,从 dispatch_exception() 调用该方法。

do_clear(arg)

处理断点如果是临时断点必须删除。

此方法必须由派生类实现。

派生类和客户端可以调用以下方法来影响步进状态。

set_step()

在一行代码后停止。

set_next(frame)

停止在给定帧中或下面的下一行。

set_return(frame)

从给定帧返回时停止。

set_until(frame)

当线路不大于当前线路的线路或从当前帧返回时停止。

set_trace([frame])

frame 开始调试。如果未指定 frame,则从调用者的框架开始调试。

set_continue()

仅在断点处或完成后停止。如果没有断点,请将系统跟踪功能设置为 None

set_quit()

quitting 属性设置为 True。这在下一次调用 dispatch_*() 方法中的一个时引发 BdbQuit

派生类和客户端可以调用以下方法来操作断点。如果出现错误,这些方法返回一个包含错误消息的字符串,如果一切正常,则返回 None

set_break(filename, lineno, temporary=0, cond, funcname)

设置新的断点。如果对于作为参数传递的 filenamelineno 行不存在,则返回错误消息。 filename 应该是规范形式,如 canonic() 方法中所述。

clear_break(filename, lineno)

删除 filenamelineno 中的断点。如果没有设置,则返回错误消息。

clear_bpbynumber(arg)

删除在 Breakpoint.bpbynumber 中具有索引 arg 的断点。如果 arg 不是数字或超出范围,则返回错误消息。

clear_all_file_breaks(filename)

删除 filename 中的所有断点。如果没有设置,则返回错误消息。

clear_all_breaks()

删除所有现有断点。

get_bpbynumber(arg)

返回由给定数字指定的断点。如果 arg 是一个字符串,它将被转换为一个数字。如果 arg 是非数字字符串,如果给定的断点从不存在或已被删除,则引发 ValueError

3.2 新版功能.

get_break(filename, lineno)

检查 filenamelineno 是否有断点。

get_breaks(filename, lineno)

filename 中返回 lineno 的所有断点,如果没有设置则返回一个空列表。

get_file_breaks(filename)

返回 filename 中的所有断点,如果没有设置,则返回一个空列表。

get_all_breaks()

返回设置的所有断点。

派生类和客户端可以调用以下方法来获取表示堆栈跟踪的数据结构。

get_stack(f, t)

获取帧和所有较高(调用)和较低帧的记录列表,以及较高部分的大小。

format_stack_entry(frame_lineno, lprefix=': ')

返回包含由 (frame, lineno) 元组标识的堆栈条目的信息的字符串:

  • 包含框架的文件名的规范格式。

  • 函数名称或 "<lambda>"

  • 输入参数。

  • 返回值。

  • 代码行(如果存在)。

客户端可以调用以下两种方法来使用调试器调试 statement,以字符串形式给出。

run(cmd, globals=None, locals=None)

调试通过 exec() 函数执行的语句。 globals 默认为 __main__.__dict__locals 默认为 globals

runeval(expr, globals=None, locals=None)

调试通过 eval() 函数执行的表达式。 globalslocals 具有与 run() 中相同的含义。

runctx(cmd, globals, locals)

用于向后兼容。调用 run() 方法。

runcall(func, *args, **kwds)

调试单个函数调用,并返回其结果。

最后,该模块定义了以下功能:

bdb.checkfuncname(b, frame)

检查我们是否应该在这里断开,这取决于断点 b 的设置方式。

如果它是通过行号设置的,它检查 b.line 是否与帧中也作为参数传递的相同。如果断点是通过函数名设置的,我们必须检查我们是否在正确的框架(正确的函数),如果我们在其第一个可执行行。

bdb.effective(file, line, frame)

确定此行代码是否存在有效(活动)断点。返回一个断点的元组和一个布尔值,指示是否可以删除临时断点。如果没有匹配的断点,则返回 (None, None)

bdb.set_trace()

使用 Bdb 实例从调用者的框架开始调试。