summaryrefslogtreecommitdiffstats
path: root/gnu/llvm/lldb/examples/python/pytracer.py
diff options
context:
space:
mode:
authorpatrick <patrick@openbsd.org>2020-08-03 14:33:06 +0000
committerpatrick <patrick@openbsd.org>2020-08-03 14:33:06 +0000
commit061da546b983eb767bad15e67af1174fb0bcf31c (patch)
tree83c78b820819d70aa40c36d90447978b300078c5 /gnu/llvm/lldb/examples/python/pytracer.py
parentImport LLVM 10.0.0 release including clang, lld and lldb. (diff)
downloadwireguard-openbsd-061da546b983eb767bad15e67af1174fb0bcf31c.tar.xz
wireguard-openbsd-061da546b983eb767bad15e67af1174fb0bcf31c.zip
Import LLVM 10.0.0 release including clang, lld and lldb.
ok hackroom tested by plenty
Diffstat (limited to 'gnu/llvm/lldb/examples/python/pytracer.py')
-rw-r--r--gnu/llvm/lldb/examples/python/pytracer.py361
1 files changed, 361 insertions, 0 deletions
diff --git a/gnu/llvm/lldb/examples/python/pytracer.py b/gnu/llvm/lldb/examples/python/pytracer.py
new file mode 100644
index 00000000000..27f88d7a3ee
--- /dev/null
+++ b/gnu/llvm/lldb/examples/python/pytracer.py
@@ -0,0 +1,361 @@
+from __future__ import print_function
+import sys
+import inspect
+from collections import OrderedDict
+
+
+class TracebackFancy:
+
+ def __init__(self, traceback):
+ self.t = traceback
+
+ def getFrame(self):
+ return FrameFancy(self.t.tb_frame)
+
+ def getLineNumber(self):
+ return self.t.tb_lineno if self.t is not None else None
+
+ def getNext(self):
+ return TracebackFancy(self.t.tb_next)
+
+ def __str__(self):
+ if self.t is None:
+ return ""
+ str_self = "%s @ %s" % (
+ self.getFrame().getName(), self.getLineNumber())
+ return str_self + "\n" + self.getNext().__str__()
+
+
+class ExceptionFancy:
+
+ def __init__(self, frame):
+ self.etraceback = frame.f_exc_traceback
+ self.etype = frame.exc_type
+ self.evalue = frame.f_exc_value
+
+ def __init__(self, tb, ty, va):
+ self.etraceback = tb
+ self.etype = ty
+ self.evalue = va
+
+ def getTraceback(self):
+ return TracebackFancy(self.etraceback)
+
+ def __nonzero__(self):
+ return self.etraceback is not None or self.etype is not None or self.evalue is not None
+
+ def getType(self):
+ return str(self.etype)
+
+ def getValue(self):
+ return self.evalue
+
+
+class CodeFancy:
+
+ def __init__(self, code):
+ self.c = code
+
+ def getArgCount(self):
+ return self.c.co_argcount if self.c is not None else 0
+
+ def getFilename(self):
+ return self.c.co_filename if self.c is not None else ""
+
+ def getVariables(self):
+ return self.c.co_varnames if self.c is not None else []
+
+ def getName(self):
+ return self.c.co_name if self.c is not None else ""
+
+ def getFileName(self):
+ return self.c.co_filename if self.c is not None else ""
+
+
+class ArgsFancy:
+
+ def __init__(self, frame, arginfo):
+ self.f = frame
+ self.a = arginfo
+
+ def __str__(self):
+ args, varargs, kwargs = self.getArgs(), self.getVarArgs(), self.getKWArgs()
+ ret = ""
+ count = 0
+ size = len(args)
+ for arg in args:
+ ret = ret + ("%s = %s" % (arg, args[arg]))
+ count = count + 1
+ if count < size:
+ ret = ret + ", "
+ if varargs:
+ if size > 0:
+ ret = ret + " "
+ ret = ret + "varargs are " + str(varargs)
+ if kwargs:
+ if size > 0:
+ ret = ret + " "
+ ret = ret + "kwargs are " + str(kwargs)
+ return ret
+
+ def getNumArgs(wantVarargs=False, wantKWArgs=False):
+ args, varargs, keywords, values = self.a
+ size = len(args)
+ if varargs and wantVarargs:
+ size = size + len(self.getVarArgs())
+ if keywords and wantKWArgs:
+ size = size + len(self.getKWArgs())
+ return size
+
+ def getArgs(self):
+ args, _, _, values = self.a
+ argWValues = OrderedDict()
+ for arg in args:
+ argWValues[arg] = values[arg]
+ return argWValues
+
+ def getVarArgs(self):
+ _, vargs, _, _ = self.a
+ if vargs:
+ return self.f.f_locals[vargs]
+ return ()
+
+ def getKWArgs(self):
+ _, _, kwargs, _ = self.a
+ if kwargs:
+ return self.f.f_locals[kwargs]
+ return {}
+
+
+class FrameFancy:
+
+ def __init__(self, frame):
+ self.f = frame
+
+ def getCaller(self):
+ return FrameFancy(self.f.f_back)
+
+ def getLineNumber(self):
+ return self.f.f_lineno if self.f is not None else 0
+
+ def getCodeInformation(self):
+ return CodeFancy(self.f.f_code) if self.f is not None else None
+
+ def getExceptionInfo(self):
+ return ExceptionFancy(self.f) if self.f is not None else None
+
+ def getName(self):
+ return self.getCodeInformation().getName() if self.f is not None else ""
+
+ def getFileName(self):
+ return self.getCodeInformation().getFileName() if self.f is not None else ""
+
+ def getLocals(self):
+ return self.f.f_locals if self.f is not None else {}
+
+ def getArgumentInfo(self):
+ return ArgsFancy(
+ self.f, inspect.getargvalues(
+ self.f)) if self.f is not None else None
+
+
+class TracerClass:
+
+ def callEvent(self, frame):
+ pass
+
+ def lineEvent(self, frame):
+ pass
+
+ def returnEvent(self, frame, retval):
+ pass
+
+ def exceptionEvent(self, frame, exception, value, traceback):
+ pass
+
+ def cCallEvent(self, frame, cfunct):
+ pass
+
+ def cReturnEvent(self, frame, cfunct):
+ pass
+
+ def cExceptionEvent(self, frame, cfunct):
+ pass
+
+tracer_impl = TracerClass()
+
+
+def the_tracer_entrypoint(frame, event, args):
+ if tracer_impl is None:
+ return None
+ if event == "call":
+ call_retval = tracer_impl.callEvent(FrameFancy(frame))
+ if not call_retval:
+ return None
+ return the_tracer_entrypoint
+ elif event == "line":
+ line_retval = tracer_impl.lineEvent(FrameFancy(frame))
+ if not line_retval:
+ return None
+ return the_tracer_entrypoint
+ elif event == "return":
+ tracer_impl.returnEvent(FrameFancy(frame), args)
+ elif event == "exception":
+ exty, exva, extb = args
+ exception_retval = tracer_impl.exceptionEvent(
+ FrameFancy(frame), ExceptionFancy(extb, exty, exva))
+ if not exception_retval:
+ return None
+ return the_tracer_entrypoint
+ elif event == "c_call":
+ tracer_impl.cCallEvent(FrameFancy(frame), args)
+ elif event == "c_return":
+ tracer_impl.cReturnEvent(FrameFancy(frame), args)
+ elif event == "c_exception":
+ tracer_impl.cExceptionEvent(FrameFancy(frame), args)
+ return None
+
+
+def enable(t=None):
+ global tracer_impl
+ if t:
+ tracer_impl = t
+ sys.settrace(the_tracer_entrypoint)
+
+
+def disable():
+ sys.settrace(None)
+
+
+class LoggingTracer:
+
+ def callEvent(self, frame):
+ print("call " + frame.getName() + " from " + frame.getCaller().getName() + " @ " + str(frame.getCaller().getLineNumber()) + " args are " + str(frame.getArgumentInfo()))
+
+ def lineEvent(self, frame):
+ print("running " + frame.getName() + " @ " + str(frame.getLineNumber()) + " locals are " + str(frame.getLocals()) + " in " + frame.getFileName())
+
+ def returnEvent(self, frame, retval):
+ print("return from " + frame.getName() + " value is " + str(retval) + " locals are " + str(frame.getLocals()))
+
+ def exceptionEvent(self, frame, exception):
+ print("exception %s %s raised from %s @ %s" % (exception.getType(), str(exception.getValue()), frame.getName(), frame.getLineNumber()))
+ print("tb: " + str(exception.getTraceback()))
+
+# the same functionality as LoggingTracer, but with a little more
+# lldb-specific smarts
+
+
+class LLDBAwareTracer:
+
+ def callEvent(self, frame):
+ if frame.getName() == "<module>":
+ return
+ if frame.getName() == "run_one_line":
+ print("call run_one_line(%s)" % (frame.getArgumentInfo().getArgs()["input_string"]))
+ return
+ if "Python.framework" in frame.getFileName():
+ print("call into Python at " + frame.getName())
+ return
+ if frame.getName() == "__init__" and frame.getCaller().getName(
+ ) == "run_one_line" and frame.getCaller().getLineNumber() == 101:
+ return False
+ strout = "call " + frame.getName()
+ if (frame.getCaller().getFileName() == ""):
+ strout += " from LLDB - args are "
+ args = frame.getArgumentInfo().getArgs()
+ for arg in args:
+ if arg == "dict" or arg == "internal_dict":
+ continue
+ strout = strout + ("%s = %s " % (arg, args[arg]))
+ else:
+ strout += " from " + frame.getCaller().getName() + " @ " + \
+ str(frame.getCaller().getLineNumber()) + " args are " + str(frame.getArgumentInfo())
+ print(strout)
+
+ def lineEvent(self, frame):
+ if frame.getName() == "<module>":
+ return
+ if frame.getName() == "run_one_line":
+ print("running run_one_line(%s) @ %s" % (frame.getArgumentInfo().getArgs()["input_string"], frame.getLineNumber()))
+ return
+ if "Python.framework" in frame.getFileName():
+ print("running into Python at " + frame.getName() + " @ " + str(frame.getLineNumber()))
+ return
+ strout = "running " + frame.getName() + " @ " + str(frame.getLineNumber()) + \
+ " locals are "
+ if (frame.getCaller().getFileName() == ""):
+ locals = frame.getLocals()
+ for local in locals:
+ if local == "dict" or local == "internal_dict":
+ continue
+ strout = strout + ("%s = %s " % (local, locals[local]))
+ else:
+ strout = strout + str(frame.getLocals())
+ strout = strout + " in " + frame.getFileName()
+ print(strout)
+
+ def returnEvent(self, frame, retval):
+ if frame.getName() == "<module>":
+ return
+ if frame.getName() == "run_one_line":
+ print("return from run_one_line(%s) return value is %s" % (frame.getArgumentInfo().getArgs()["input_string"], retval))
+ return
+ if "Python.framework" in frame.getFileName():
+ print("return from Python at " + frame.getName() + " return value is " + str(retval))
+ return
+ strout = "return from " + frame.getName() + " return value is " + \
+ str(retval) + " locals are "
+ if (frame.getCaller().getFileName() == ""):
+ locals = frame.getLocals()
+ for local in locals:
+ if local == "dict" or local == "internal_dict":
+ continue
+ strout = strout + ("%s = %s " % (local, locals[local]))
+ else:
+ strout = strout + str(frame.getLocals())
+ strout = strout + " in " + frame.getFileName()
+ print(strout)
+
+ def exceptionEvent(self, frame, exception):
+ if frame.getName() == "<module>":
+ return
+ print("exception %s %s raised from %s @ %s" % (exception.getType(), str(exception.getValue()), frame.getName(), frame.getLineNumber()))
+ print("tb: " + str(exception.getTraceback()))
+
+
+def f(x, y=None):
+ if x > 0:
+ return 2 + f(x - 2)
+ return 35
+
+
+def g(x):
+ return 1.134 / x
+
+
+def print_keyword_args(**kwargs):
+ # kwargs is a dict of the keyword args passed to the function
+ for key, value in kwargs.items():
+ print("%s = %s" % (key, value))
+
+
+def total(initial=5, *numbers, **keywords):
+ count = initial
+ for number in numbers:
+ count += number
+ for key in keywords:
+ count += keywords[key]
+ return count
+
+if __name__ == "__main__":
+ enable(LoggingTracer())
+ f(5)
+ f(5, 1)
+ print_keyword_args(first_name="John", last_name="Doe")
+ total(10, 1, 2, 3, vegetables=50, fruits=100)
+ try:
+ g(0)
+ except:
+ pass
+ disable()