import gdb class KstdErrorCodePrinter(gdb.ValuePrinter): def __init__(self, val): self.__val = val def _error_value(self): return int(self.__val["m_value"]) def _category_name(self): try: category_pointer = self.__val["m_category"] if int(category_pointer) == 0: return "" category = category_pointer.dereference() try: dynamic = category.dynamic_type name = str(dynamic) except gdb.error: name = str(category.type) name = name.replace("(anonymous namespace)::", "") if name.endswith("_t"): name = name[:-2] return name except (gdb.error, AttributeError): return "?" def _message(self): try: category_pointer = self.__val["m_category"] if int(category_pointer) == 0: return None value = self._error_value() address = int(category_pointer) result = gdb.parse_and_eval( f"((kstd::error_category const *){address:#x})->message({value})" ) try: ptr = result["_M_str"] length = int(result["_M_len"]) if int(ptr) != 0 and length > 0: return ptr.string(length=length) except (gdb.error, AttributeError, KeyError): pass return str(result) except (gdb.error, RuntimeError): return None def to_string(self): value = self._error_value() category = self._category_name() msg = self._message() if msg is not None: return f"{category}:{value} ({msg})" return f"{category}:{value}" def children(self): yield ("value", self.__val["m_value"]) category_pointer = self.__val["m_category"] if int(category_pointer) != 0: yield ("category", category_pointer.dereference()) def display_hint(self): return None