1. 调用追踪
我们的函数都是执行在栈中的,调用追踪就是追踪函数执行的栈信息.调试的时候我们除了想知道哪条代码错了,也会想知道是谁调用了这条错误的代码. 又或者希望知道运行时的堆栈信息.这个时候调用追踪模块就有用了
本节需要的预备知识有:
1.1. 一个简单的例子
import traceback def func(): s = traceback.extract_stack() print('%s Invoked me!'%s[-2][2]) def a(): func() b = lambda :func()
a()
a Invoked me!
b()
<lambda> Invoked me!
traceback的api是这些,我将它翻译出来,英文不好的同学也可以对照着使用:
traceback.print_tb(tb, limit=None, file=None)
如果
limit
参数是正数,则打印limit条数的(从调用者这一帧开始的)traceback对象的堆栈跟踪条目,否则打印最后的abs(limit)条目,如果limit
被省略或为None,则打印所有条目 如果省略file
或者None
,则输出到sys.stderr
,否则它应该是一个打开的文件或类似文件的对象来接收输出。
打印,以限制堆栈跟踪条目从traceback对象(从调用者这帧开始),如果限制是积极的。否则,打印最后的ABS(限制)条目。如果限制被省略或没有,所有条目打印。如果文件被省略或没有,输出到`sys.stderr`;否则应打开的文件或类似文件的对象来接收输出。
traceback.print_exception(etype, value, tb, limit=None, file=None, chain=True)
将异常信息和堆栈跟踪条目从traceback对象tb打印到文件。这与
print_tb()
有以下不同:- 如果tb不是None,它会打印一个 header Traceback(通常是最近一次调用):
- 它在堆栈跟踪之后打印异常etype和值
- 如果etype是SyntaxError,并且value具有相应的格式,则会打印出语法错误发生的行,并带有指示错误大致位置的插入符号。
可选的limit参数与`print_tb()`的含义相同.如果chain为true(默认值),那么也会打印异常链(`__cause__`或`__context__`异常的属性),就像解释器本身在打印未处理的异常时一样。
traceback.print_exc(limit=None, file=None, chain=True)
print_exception(*sys.exc_info(), limit, file, chain)
的缩写traceback.print_last(limit=None, file=None, chain=True)
这是
print_exception(sys.last_type,sys.last_value,sys.last_traceback,limit,file,chain)
的缩写。一般来说,只有在异常已经达到交互式提示之后才会有效
traceback.print_stack(f=None, limit=None, file=None)
如果limit为正值则以limit参数为条数打印堆栈跟踪条目(从调用点开始)否则,打印最后一个abs(limit)条目。如果省略limit或None,则打印所有条目。可选的f参数可用于指定要启动的备用堆栈帧。可选file参数与
print_tb()
具有相同的含义。traceback.extract_tb(tb, limit=None)
返回从traceback对象tb提取的“预处理”堆栈跟踪条目列表。它对于堆栈跟踪的替代格式很有用。可选的limit参数与print_tb()的含义相同。 “预处理”堆栈跟踪条目是表示通常为堆栈跟踪打印的信息的4元组(文件名,行号,函数名称,文本)。文本是带有前导和尾随空格的字符串;如果源不可用,则为None。
traceback.extract_stack(f=None, limit=None)
从当前堆栈帧中提取原始的追溯。返回值的格式与
extract_tb()
的格式相同。可选的f和limit参数与print_stack()
具有相同的含义。traceback.format_list(extracted_list)
给定一个由
extract_tb()
或extract_stack()
返回的元组列表,返回一个准备打印的字符串列表。结果列表中的每个字符串对应于参数列表中具有相同索引的项。每个字符串以换行符结尾.对于源文本行不为None的项目,字符串也可能包含内部换行符。
traceback.format_exception_only(etype, value)
格式化traceback的异常部分。参数是异常类型和值,例如由
sys.last_type
和sys.last_value
给出的。返回值是一个字符串列表,每个都以换行符结尾。通常,列表包含单个字符串;但是,对于SyntaxError
异常,它包含几行(打印时)显示有关发生语法错误的详细信息。指示发生哪个异常的消息是列表中始终最后一个字符串。
traceback.format_exception(etype, value, tb, limit=None, chain=True)
格式化堆栈跟踪和异常信息。参数与
print_exception()
的相应参数具有相同的含义。返回值是字符串列表,每个都以换行符结尾,一些包含内部换行符。当这些行连接并打印时,打印与print_exception()
完全相同的文本。
traceback.format_exc(limit=None, chain=True)
类似
print_exc(limit)
,但是返回一个字符串而不是打印到一个文件
traceback.format_tb(tb, limit=None)
format_list(extract_tb(tb,limit))
的缩写traceback.format_stack(f=None, limit=None)
format_list(extract_stack(f, limit))
的缩写traceback.clear_frames(tb)
通过调用每个帧对象的
clear()
方法来清除traceback对象tb中所有堆栈帧的局部变量。traceback.walk_stack(f)
从给定帧中的
f.f_back
后面移动一个堆栈,产生每个帧的帧和行号。如果f为None,则使用当前堆栈。它常用于和StackSummary.extract()
一起使用。traceback.walk_tb(tb)
在tb_next之后走一个回溯,产生每个帧的帧和行号。此帮助程序与
StackSummary.extract()
一起使用。
class traceback.StackSummary
StackSummary对象表示可以进行格式化的调用堆栈,它的静态方法
extract
常与traceback.walk_stack
或者traceback.walk_tb
配合使用classmethod extract(frame_gen, *, limit=None, lookup_lines=True, capture_locals=False)
从帧生成器构造一个
StackSummary
对象(例如由walk_stack()或walk_tb()的返回).如果有limit
参数,则只有这么多帧是从frame_gen中获取的。如果lookup_lines
为False,则返回的FrameSummary对象将不会读取它们的行,从而使得创建StackSummary的成本更低(如果实际上可能没有格式化,则可能是有价值的).如果capture_locals
为True,则每个FrameSummary中的局部变量被捕获为对象表示。
1.2. *段错误追踪
所谓的段错误就是指访问的内存超出了系统所给这个程序的内存空间,通常这个值是由gd tr来保存的,他是一个48位的寄存器,其中的32位是保存由它指向的 gdt表,后13位保存 相应于gdt的下标,最后3位包括了程序是否在内存中以及程序的在cpu中的运行级别,指向 的gdt是由以64位为一个单位的表,在这张表中就保存着程序运行的代码段以及数据段的起 始地址以及与此相应的段限和页面交换还有程序运行级别还有内存粒度等等的信息。
在编程中以下几类做法容易导致段错误,基本上是错误地使用指针引起的。
- 访问系统数据区,尤其是往系统保护的内存地址写数据最常见就是给一个指针以0地址。
- 内存越界(数组越界,变量类型不一致等): 访问到不属于你的内存区域。
python由于与C有着千丝万缕的联系,所以使用ctypes这类模块的时候也很容易出段错误这种问题.python3.5+提供了faulthandler
工具来做段错误追踪.
%%writefile src/C3/faulthandler_test.py import ctypes ctypes.string_at(0)
Overwriting src/C3/faulthandler_test.py
!python3 src/C3/faulthandler_test.py
a()
0
a()
1
另一中用法是在文件内写入faulthandler.enable()
a()
2
a()
3
a()
4
a()
5
还没有评论,来说两句吧...