"""Debugging utilities for constructs"""from __future__ import print_functionimport sysimport tracebackimport pdbimport inspectfrom .core import Construct, Subconstructfrom .lib import HexString, Container, ListContainerclass Probe(Construct):"""A probe: dumps the context, stack frames, and stream content to the screento aid the debugging process.See also Debugger.Parameters:* name - the display name* show_stream - whether or not to show stream contents. default is True.the stream must be seekable.* show_context - whether or not to show the context. default is True.* show_stack - whether or not to show the upper stack frames. defaultis True.* stream_lookahead - the number of bytes to dump when show_stack is set.default is 100.Example:Struct("foo",UBInt8("a"),Probe("between a and b"),UBInt8("b"),)"""__slots__ = ["printname", "show_stream", "show_context", "show_stack","stream_lookahead"]counter = 0def __init__(self, name = None, show_stream = True,show_context = True, show_stack = True,stream_lookahead = 100):Construct.__init__(self, None)if name is None:Probe.counter += 1name = "<unnamed %d>" % (Probe.counter,)self.printname = nameself.show_stream = show_streamself.show_context = show_contextself.show_stack = show_stackself.stream_lookahead = stream_lookaheaddef __repr__(self):return "%s(%r)" % (self.__class__.__name__, self.printname)def _parse(self, stream, context):self.printout(stream, context)def _build(self, obj, stream, context):self.printout(stream, context)def _sizeof(self, context):return 0def printout(self, stream, context):obj = Container()if self.show_stream:obj.stream_position = stream.tell()follows = stream.read(self.stream_lookahead)if not follows:obj.following_stream_data = "EOF reached"else:stream.seek(-len(follows), 1)obj.following_stream_data = HexString(follows)if self.show_context:obj.context = contextif self.show_stack:obj.stack = ListContainer()frames = [s[0] for s in inspect.stack()][1:-1]frames.reverse()for f in frames:a = Container()a.__update__(f.f_locals)obj.stack.append(a)print("=" * 80)print("Probe", self.printname)print(obj)print("=" * 80)class Debugger(Subconstruct):"""A pdb-based debugger. When an exception occurs in the subcon, a debuggerwill appear and allow you to debug the error (and even fix on-the-fly).Parameters:* subcon - the subcon to debugExample:Debugger(Enum(UBInt8("foo"),a = 1,b = 2,c = 3))"""__slots__ = ["retval"]def _parse(self, stream, context):try:return self.subcon._parse(stream, context)except Exception:self.retval = NotImplementedself.handle_exc("(you can set the value of 'self.retval', ""which will be returned)")if self.retval is NotImplemented:raiseelse:return self.retvaldef _build(self, obj, stream, context):try:self.subcon._build(obj, stream, context)except Exception:self.handle_exc()def handle_exc(self, msg = None):print("=" * 80)print("Debugging exception of %s:" % (self.subcon,))print("".join(traceback.format_exception(*sys.exc_info())[1:]))if msg:print(msg)pdb.post_mortem(sys.exc_info()[2])print("=" * 80)
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。