Skip to content

Instantly share code, notes, and snippets.

@mikezucc
Last active December 4, 2018 18:56
Show Gist options
  • Save mikezucc/3cb24a0bc36ef13997bd32210db17db1 to your computer and use it in GitHub Desktop.
Save mikezucc/3cb24a0bc36ef13997bd32210db17db1 to your computer and use it in GitHub Desktop.
Version 1 of the assertion reporting platform
import lldb
import json
import subprocess
from os.path import expanduser
import time
import os
import sys
home = expanduser("~")
def getBreakpointIndexesOfCFunction(cFunctionName, interpreter):
res = lldb.SBCommandReturnObject()
interpreter.HandleCommand('breakpoint list', res)
res.Succeeded()
output = res.GetOutput()
if cFunctionName in output:
splits = output.split('\n')
return [line.split(':')[0] for line in splits if cFunctionName in line]
return []
def deleteBreakpointAtCFunction(cFunctionName, interpreter):
res = lldb.SBCommandReturnObject()
breakpointIndexes = getBreakpointIndexesOfCFunction(cFunctionName, interpreter)
for breakpointIndex in breakpointIndexes:
interpreter.HandleCommand('breakpoint delete ' + breakpointIndex, res)
def setBreakpointAtCFunction(cFunctionName, interpreter):
res = lldb.SBCommandReturnObject()
# interpreter.HandleCommand('breakpoint set --name ' + cFunctionName + ' -C breakpointonassert', res)
interpreter.HandleCommand('breakpoint set --name ' + cFunctionName, res)
breakpointIndexes = getBreakpointIndexesOfCFunction(cFunctionName, interpreter)
breakpointID = breakpointIndexes[0]
interpreter.HandleCommand('breakpoint command add ' + breakpointID + ' -F "reportassert.BreakpointOnAssert"', res)
setCommand = res.Succeeded()
interpreter.HandleCommand('breakpoint modify --auto-continue true ' + breakpointID, res)
print 'Assert Breakpoint Definition: ' + str(setCommand and res.Succeeded())
def BreakpointOnAssert(frame, bp_loc, dict):
thread = frame.GetThread()
process = thread.GetProcess()
target = process.GetTarget()
debugger = target.GetDebugger()
interpreter = debugger.GetCommandInterpreter()
command_result = lldb.SBCommandReturnObject()
# Here we would actually want to reset to the GetAsync old value, however,
# I am over prodding the mysterious ethereus Beast that is LLDB PYTHON
debugger.SetAsync(False)
print "SENDING IP TO THE NSA YEET"
processedCallStack = []
for frame in thread.frames:
frameName = frame.GetFunction().GetDisplayName()
frameValuesList = frame.GetVariables(True, True, False, False)
callFrameVariables = []
for value in frameValuesList:
try:
valueType = value.GetTypeName()
if valueType is None:
continue
path = lldb.SBStream()
value.GetExpressionPath(path)
expressableName = path.GetData()
varNiceValue = value.GetValue()
if '*' in str(valueType):
debugResult = frame.EvaluateExpression('[' + str(expressableName) + ' debugDescription]')
if debugResult is not None:
varNiceValue = debugResult.GetSummary()
if varNiceValue is None:
varNiceValue = "nil or could not access address"
callFrameVariables.append({"name": expressableName, "type": valueType, "value": varNiceValue})
except Exception as e:
print e
x = 1
processedCallStack.append({"frame": str(frameName), "variables": callFrameVariables})
reportTime = time.strftime("%Y-%m-%d %H:%M")
report = { "callstack": processedCallStack,
"target": str(target),
"time": reportTime }
print report
jsonString = json.dumps(report)
with open(home + '/assertion_results', 'w+') as results_file:
results_file.write(jsonString)
# response = urllib.urlopen('http://localhost:3003/assert', data=jsonString.encode('utf8'))
# print response.read().decode('utf8')
# reportInvocation = Popen(["python", "~/post_assertion.py"], stdin=None, stdout=None, stderr=None, shell=True)
# subprocess.check_output('nix-shell . --run "python ' + home + '/post_assertion.py"', shell=True)
# req = urllib2.Request(url,
# headers = {
# "Content-Type": "application/json",
# "Accept": "*/*",
# }, data = jsonString)
# f = urllib2.urlopen(req)
# reportInvocation.wait()we
# print reportInvocation.returncode
devnull = open(os.devnull, 'wb') # Use this in Python < 3.3
# Python >= 3.3 has subprocess.DEVNULL
subprocess.Popen(['nohup', home + '/post_assertion.py'], stdout=devnull, stderr=devnull, preexec_fn=os.setpgrp, shell=True, env='$PATH')
debugger.SetAsync(True)
return True
def __lldb_init_module(debugger, internal_dict):
interpreter = debugger.GetCommandInterpreter()
res = lldb.SBCommandReturnObject()
interpreter.HandleCommand('command script import -r reportassert.py', res)
print 'Initialize Script: ' + str(res.Succeeded())
deleteBreakpointAtCFunction('BreakpointFindMe', interpreter)
setBreakpointAtCFunction('BreakpointFindMe', interpreter)
return None
@mikezucc
Copy link
Author

mikezucc commented Dec 3, 2018

Latest: Recursively prints arguments/ visible variables in scope in each frame.
Next: Working on printing ivars

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment