- 重命名和重构了多个文件,包括 lexer、parser 和 AST 相关代码 - 添加了日志功能,使用 LOG_* 宏替代原有的 error 和 warn 函数 - 优化了错误处理和内存分配方式 - 调整了代码结构,提高了模块化和可读性
203 lines
6.2 KiB
Python
203 lines
6.2 KiB
Python
# # 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 # type: ignore
|
||
from gdb.printing import PrettyPrinter # type: ignore
|
||
|
||
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()
|