Skip to content

Instantly share code, notes, and snippets.

@kuzen
Last active December 3, 2021 09:11
Show Gist options
  • Save kuzen/516005eee1b059b9e7decc6f7cf4b7b7 to your computer and use it in GitHub Desktop.
Save kuzen/516005eee1b059b9e7decc6f7cf4b7b7 to your computer and use it in GitHub Desktop.
lldbscripts
# debugvis.py
# use: 1. for conditional breakpoint:
# /py plot_cvimage($mat)
# 2. for debug console
# imshow mat
import io
import lldb
import debugger
import base64
import numpy as np
import matplotlib
matplotlib.use('agg')
import matplotlib.pyplot as plt
def __lldb_init_module(debugger, dict):
debugger.HandleCommand(
"command script add -f debugvis.imshow imshow")
def show():
image_bytes = io.BytesIO()
plt.savefig(image_bytes, format='png', bbox_inches='tight')
document = '<html><img src="data:image/png;base64,%s"></html>' % base64.b64encode(image_bytes.getvalue()).decode('utf-8')
debugger.display_html(document, position=2)
def getCvType(flags):
cv_type_name = None
depth = flags & 7
if depth == 0:
cv_type_name = 'CV_8U'
elif depth == 1:
cv_type_name = 'CV_8S'
elif depth == 2:
cv_type_name = 'CV_16U'
elif depth == 3:
cv_type_name = 'CV_16S'
elif depth == 4:
cv_type_name = 'CV_32S'
elif depth == 5:
cv_type_name = 'CV_32F'
elif depth == 6:
cv_type_name = 'CV_64F'
else:
print("cvMat Type not sypported")
return cv_type_name
def parseCvMat(root):
flags = int(root.GetChildMemberWithName("flags").GetValue())
# Channels.
channels = 1 + (flags >> 3) & 63
# Type of cvMat.
cv_type_name = getCvType(flags)
# Rows and columns.
rows = int(root.GetChildMemberWithName("rows").GetValue())
cols = int(root.GetChildMemberWithName("cols").GetValue())
# Get the step (access to value of a buffer with GetUnsignedInt16()).
error = lldb.SBError()
line_step = root.GetChildMemberWithName("step").GetChildMemberWithName(
'buf').GetData().GetUnsignedInt16(error, 0)
# Get data address.
data_address = int(root.GetChildMemberWithName("data").GetValue(), 16)
print("data_address:")
print(data_address)
# Create a dictionary for the output.
Mat = {'cols': cols, 'rows': rows, 'channels': channels, 'line_step': line_step,
'data_address': data_address, 'flags': flags,
'cv_type_name': cv_type_name, 'data': 0}
np_dtype = {
'CV_8U': np.uint8,
'CV_8S': np.int8,
'CV_16U': np.uint16,
'CV_16S': np.int16,
'CV_32F': np.float32,
'CV_32S': np.int32,
'CV_64F': np.float64,
}.get(cv_type_name, None)
if np_dtype is None:
return 'Unsupported type: {}'.format(cv_type_name)
error = lldb.SBError()
memory_data = root.GetProcess().ReadMemory(data_address, rows * cols * channels,
error)
# print(line_step)
# print(height)
# print(np.dtype(np_dtype).itemsize)
# print(height*width*n_channel)
Mat['data'] = np.frombuffer(memory_data, dtype=np_dtype).reshape((rows,cols,channels))
return Mat
# 在conditonal breakpoint中调用: /py debugvis.plot_cvimage($mat)
def plot_cvimage(mat, cmap='nipy_spectral_r'):
cv_type_name = getCvType(mat.flags)
if cv_type_name:
channels = 1 + (mat.flags >> 3) & 63
np_dtype = {
'CV_8U': np.uint8,
'CV_8S': np.int8,
'CV_16U': np.uint16,
'CV_16S': np.int16,
'CV_32F': np.float32,
'CV_32S': np.int32,
'CV_64F': np.float64,
}.get(cv_type_name, None)
if np_dtype is None:
return 'Unsupported type: {}'.format(cv_type_name)
image = debugger.unwrap(mat.data)
if image.TypeIsPointerType():
image_addr = image.GetValueAsUnsigned()
else:
image_addr = image.AddressOf().GetValueAsUnsigned()
data = lldb.process.ReadMemory(image_addr, mat.rows * mat.cols * channels, lldb.SBError())
bgr = np.frombuffer(data, dtype=np_dtype).reshape((mat.rows, mat.cols, channels))
rgb = bgr[...,::-1]
plt.imshow(rgb, cmap='nipy_spectral_r', interpolation='nearest')
show()
# 在debug console中调用: imshow mat
def imshow(debugger, command, result, internal_dict):
target = debugger.GetSelectedTarget()
process = target.GetProcess()
thread = process.GetSelectedThread()
frame = thread.GetFrameAtIndex(0)
root = frame.FindVariable(command)
if root.GetValueForExpressionPath(".flags").IsValid():
mat = parseCvMat(root)
bgr = mat['data']
rgb = bgr[...,::-1]
plt.imshow(rgb, cmap='nipy_spectral_r', interpolation='nearest')
show()
else:
return root.GetSummary()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment