如何使用gdb.pretty_printers按行列打印结构体指针成员?报错求助
解决GDB打印自定义矩阵结构体时的"Cannot convert value to float."异常
问题背景
定义的C结构体:
typedef uint8_t matrix_size_t; typedef float ElemType; struct _matrix { /* data */ uint8_t inited; matrix_size_t rows; matrix_size_t cols; ElemType* data; };
为了按行列格式打印Matrix.data,编写了以下GDB美化打印的Python代码:
import gdb import numpy as np import logging class McuMatrixPrinter: def __init__(self, variety, val): self.variety = variety self.inited = val["inited"] self.rows = int(val["rows"]) self.cols = int(val["cols"]) self.data = val["data"] self.type = self.data.type.unqualified().strip_typedefs() self.data = self.data.cast(self.type.pointer()) logging.info(self.type) logging.info(type(self.data)) def to_string(self): if int(self.inited) == 0: return "This matrix has not been inited!" mat = np.zeros((self.rows, self.cols), dtype=np.float64) for row in range(self.rows): for col in range(self.cols): offset = row * self.cols + col item = (self.data + offset).dereference() logging.info(type(item)) mat[row, col] = float(item) return "Matrix::%s<%d,%d>\n%s\n" % (self.variety, self.rows, self.cols, self.data, mat) def PrintMatrix(val): type = val.type if type.code == gdb.TYPE_CODE_REF: type = type.target() type = type.unqualified().strip_typedefs() typename = type.tag if typename == None: return None if typename.find("_matrix") != -1: return McuMatrixPrinter("Matrix", val) return None def register_matrix_printers(obj): "Register eigen pretty-printers with objfile Obj" logging.basicConfig( level=logging.DEBUG, filename='/tmp/gdbpy.log', filemode='a', format= '%(asctime)s - %(pathname)s[line:%(lineno)d] - %(levelname)s: %(message)s' ) if obj == None: obj = gdb obj.pretty_printers.append(PrintMatrix)
执行时出现异常:
(gdb) p vector
$1 = Python Exception <class 'gdb.error'> Cannot convert value to float.:(gdb) p vector
$2 = Python Exception <class 'gdb.error'> Cannot convert value to float.:
问题原因
异常触发在float(item)行:
item是GDB的gdb.Value对象,直接用Python原生float()转换会因为类型不兼容报错;- 代码中冗余的指针类型转换操作,可能导致
data指针的实际类型与预期不符; - 字符串返回格式存在错误,直接拼接指针对象会引发额外格式问题。
修复方案
1. 修正指针类型处理
结构体中data已经是ElemType*(即float*),无需额外的类型转换,直接使用原始指针即可。
2. 正确获取浮点数数值
使用gdb.Value对象自带的float()方法提取数值,而非Python原生float()函数。
3. 修正返回字符串格式
移除多余的指针拼接,只保留矩阵的可读格式输出。
修改后的McuMatrixPrinter类代码:
class McuMatrixPrinter: def __init__(self, variety, val): self.variety = variety self.inited = val["inited"] self.rows = int(val["rows"]) self.cols = int(val["cols"]) # 直接使用原始data指针,无需额外类型转换 self.data = val["data"] logging.info(self.data.type) logging.info(type(self.data)) def to_string(self): if int(self.inited) == 0: return "This matrix has not been inited!" mat = np.zeros((self.rows, self.cols), dtype=np.float64) for row in range(self.rows): for col in range(self.cols): offset = row * self.cols + col item = (self.data + offset).dereference() logging.info(type(item)) # 使用gdb.Value的float()方法获取正确数值 mat[row, col] = item.float() # 格式化返回矩阵信息 return f"Matrix::{self.variety}<{self.rows},{self.cols}>\n{mat}"
额外注意
如果目标是MCU程序,需确认字节序是否与GDB运行环境一致(大部分现代MCU为小端,与PC环境兼容,无需额外处理)。
内容的提问来源于stack exchange,提问作者user14503825
相关产品推荐
相关产品推荐

