smcc/libcore/vector-gdb.py
2025-03-05 15:45:19 +08:00

203 lines
6.1 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# # vector_gdb.py
# import gdb
# import re
# class VectorPrinter:
# """解析宏定义的 vector 结构体"""
# def __init__(self, val):
# self.val = val
# def check_vector_type(self):
# """验证是否为合法 vector 结构体"""
# try:
# # 检查是否包含 size/cap/data 字段
# return all(self.val.type.has_key(field)
# for field in ['size', 'cap', 'data'])
# except gdb.error:
# return False
# def get_array_view(self):
# """将 data 字段转换为数组视图"""
# if not self.check_vector_type():
# return None
# cap = int(self.val['cap'])
# data_ptr = self.val['data']
# if cap == 0 or data_ptr == 0:
# return []
# # 构造数组类型 (例如 int[cap])
# element_type = data_ptr.type.target()
# array_type = element_type.array(cap - 1) # C 数组声明语法
# return data_ptr.cast(array_type.pointer()).dereference()
# def to_string(self):
# if not self.check_vector_type():
# return "Not a vector type"
# size = self.val['size']
# cap = self.val['cap']
# data = self.get_array_view()
# return (f"vector(size={size}, cap={cap}, data={data})")
# class VectorInfoCommand(gdb.Command):
# """自定义命令:显示 vector 详细信息"""
# def __init__(self):
# super(VectorInfoCommand, self).__init__("vector_info",
# gdb.COMMAND_USER)
# def invoke(self, arg, from_tty):
# val = gdb.parse_and_eval(arg)
# printer = VectorPrinter(val)
# if not printer.check_vector_type():
# print(f"'{arg}' is not a vector structure")
# return
# size = int(val['size'])
# cap = int(val['cap'])
# data = printer.get_array_view()
# # 输出格式化信息
# print(f"Vector {arg}:")
# print(f"├─ Size: {size}")
# print(f"├─ Capacity: {cap}")
# print("└─ Data elements [0..{}]:".format(min(size, cap)-1))
# for i in range(min(size, cap)):
# try:
# print(f" [{i}]: {data[i]}")
# except gdb.MemoryError:
# print(f" [{i}]: <invalid memory>")
# def register_printers():
# """注册自动类型识别"""
# def vector_matcher(val):
# return VectorPrinter(val).check_vector_type()
# # 使用 lambda 包装以动态创建 printer
# gdb.pretty_printers.append(lambda val:
# VectorPrinter(val) if vector_matcher(val) else None)
# # 注册命令和打印机
# VectorInfoCommand()
# register_printers()
# vector_gdb.py
import gdb
from gdb.printing import PrettyPrinter
class VectorPrinter:
"""兼容新旧注册方式的最终方案"""
def __init__(self, val: gdb.Value):
self.val:gdb.Value = val
def check_type(self) -> bool:
"""类型检查(兼容匿名结构体)"""
try:
if self.val.type.code != gdb.TYPE_CODE_STRUCT:
return False
fields = self.val.type.fields()
if not fields:
return False
exp = ['size', 'cap', 'data']
for t in fields:
if t.name in exp:
exp.remove(t.name)
else:
return False
return True
except gdb.error:
return False
def to_string(self):
if not self.check_type():
return "Not a vector"
return "vector({} size={}, cap={})".format(
self.val.address,
self.val['size'],
self.val['cap'],
)
def display_hint(self):
return 'array'
def children(self):
"""生成数组元素(关键改进点)"""
if not self.check_type():
return []
size = int(self.val['size'])
cap = int(self.val['cap'])
data_ptr = self.val['data']
if cap == 0 or data_ptr == 0:
return []
# 使用 GDB 内置数组转换
array = data_ptr.dereference()
array = array.cast(data_ptr.type.target().array(cap - 1))
for i in range(size):
# state = "<used>" if i < size else "<unused>"
try:
value = array[i]
yield (f"[{i}] {value.type} {value.address}", value)
except gdb.MemoryError:
yield (f"[{i}]", "<invalid>")
# 注册方式一传统append方法您之前有效的方式self
def append_printer():
gdb.pretty_printers.append(
lambda val: VectorPrinter(val) if VectorPrinter(val).check_type() else None
)
# 注册方式二:新版注册方法(备用方案)
def register_new_printer():
class VectorPrinterLocator(PrettyPrinter):
def __init__(self):
super().__init__("vector_printer")
def __call__(self, val):
ret = VectorPrinter(val).check_type()
print(f"ret {ret}, type {val.type}, {[(i.name, i.type) for i in val.type.fields()]}")
return None
gdb.printing.register_pretty_printer(
gdb.current_objfile(),
VectorPrinterLocator()
)
# 双重注册保证兼容性
append_printer() # 保留您原来有效的方式
# register_new_printer() # 添加新版注册
class VectorInfoCommand(gdb.Command):
"""保持原有命令不变"""
def __init__(self):
super().__init__("vector_info", gdb.COMMAND_USER)
def invoke(self, arg, from_tty):
val = gdb.parse_and_eval(arg)
printer = VectorPrinter(val)
if not printer.check_type():
print("Invalid vector")
return
print("=== Vector Details ===")
print("Size:", val['size'])
print("Capacity:", val['cap'])
print("Elements:")
for name, value in printer.children():
print(f" {name}: {value}")
VectorInfoCommand()