Skip to content

Instantly share code, notes, and snippets.

@anug7
Last active July 19, 2020 06:08
Show Gist options
  • Save anug7/4b35f5a827a0e76b5b74902c96f619bb to your computer and use it in GitHub Desktop.
Save anug7/4b35f5a827a0e76b5b74902c96f619bb to your computer and use it in GitHub Desktop.
"""
OpenCV Mat viewer in GDB
"""
import gdb
import cv2
import numpy as np
class PlotterCommand(gdb.Command):
"""
Plotter command class with gdb command base class
"""
def __init__(self):
super(PlotterCommand, self).__init__("plot",
gdb.COMMAND_DATA,
gdb.COMPLETE_SYMBOL)
def invoke(self, arg, from_tty):
args = gdb.string_to_argv(arg)
# generally, we type "plot someimage" in the GDB commandline
# where "someimage" is an instance of cv::Mat
v = gdb.parse_and_eval(args[0])
cmd = ""
if len(args) > 1:
cmd = args[1]
CV_CN_MAX = 512
CV_CN_SHIFT = 3
CV_MAT_CN_MASK = (CV_CN_MAX - 1) << CV_CN_SHIFT
flags = v['flags']
# Mat.channels() will work only the method is used in the code
# otherwise the function is not generated for the template
channel = (((flags) & CV_MAT_CN_MASK) >> CV_CN_SHIFT) + 1
CV_DEPTH_MAX = (1 << CV_CN_SHIFT)
CV_MAT_DEPTH_MASK = CV_DEPTH_MAX - 1
depth = (flags) & CV_MAT_DEPTH_MASK
if depth == cv2.CV_8U:
dtype = np.uint8
elif depth == cv2.CV_8S:
dtype = np.int8
elif depth == cv2.CV_16U:
dtype = np.uint16
elif depth == cv2.CV_16S:
dtype = np.int16
elif depth == cv2.CV_16S:
dtype = np.int16
elif depth == cv2.CV_32F:
dtype = np.float32
elif depth == cv2.CV_64F:
dtype = np.float64
# conver the v['data'] type to "char*" type
char_type = gdb.lookup_type("char")
char_pointer_type = char_type.pointer()
gbuffer = v['data'].cast(char_pointer_type)
# read bytes from inferior's memory, because
# we run the opencv-python module in GDB's own process
# otherwise, we use memory corss processes
buf = v['step']['buf']
cbytes = buf[0] * v['rows'] # buf[0] is the step? Not quite sure.
inferior = gdb.selected_inferior()
mem = inferior.read_memory(gbuffer, cbytes)
img = np.frombuffer(mem, dtype)
if channel != 1:
img = img.reshape((v['cols'], v['rows'], channel))
else:
img = img.reshape((v['rows'], v['cols']))
if cmd == "":
cv2.namedWindow('debugger')
cv2.imshow('debugger', img)
# the below statement is necessory, otherwise, the Window
# will hang
cv2.waitKey(0)
elif cmd == "print":
print(img)
PlotterCommand()
@anug7
Copy link
Author

anug7 commented Jul 19, 2020

Usage: inside gdb
source cv_plotter.py
plot img # displays image in opencv Window
plot img print # prints the image. Useful for seeing pixel values

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