def print_flag(valobj: lldb.SBValue, internal_dict: Dict) -> str: if valobj.GetType().IsReferenceType(): valobj = valobj.Dereference() data = valobj.GetChildMemberWithName("m_val").GetValueAsUnsigned() return "({}) {:b}".format(valobj.GetType().name, data)
def print_endpoint(valobj: lldb.SBValue, internal_dict: Dict) -> str: if valobj.GetType().IsReferenceType(): valobj = valobj.Dereference() union = valobj.GetChildMemberWithName("impl_").GetChildMemberWithName( "data_") family = (union.GetChildMemberWithName("base").GetChildMemberWithName( "sa_family").GetValueAsUnsigned()) if family == 2: a = (union.GetChildMemberWithName("v4").GetChildMemberWithName( "sin_addr").GetData().uint8s) addr = ".".join([f"{b}" for b in a]) p = swap16( union.GetChildMemberWithName("v4").GetChildMemberWithName( "sin_port").GetValueAsUnsigned()) return "{}:{}".format(addr, p) else: a = (union.GetChildMemberWithName("v6").GetChildMemberWithName( "sin6_addr").GetData().uint8s) p = swap16( union.GetChildMemberWithName("v6").GetChildMemberWithName( "sin6_port").GetValueAsUnsigned()) addr = ":".join(x + y for x, y in pairs(["{:02x}".format(b) for b in a])) return "[{}]:{}".format(addr, p)
def print_hash(valobj: lldb.SBValue, internal_dict: Dict) -> str: if valobj.GetType().IsReferenceType(): valobj = valobj.Dereference() data = valobj.GetChildMemberWithName("m_number").GetData().uint8s return bytes(data).hex()
def print_span(valobj: lldb.SBValue, internal_dict: Dict) -> str: if valobj.GetType().IsReferenceType(): valobj = valobj.Dereference() array = valobj.GetChildMemberWithName("m_ptr") size = valobj.GetChildMemberWithName("m_len").GetValueAsSigned() ret = "size = {}".format(size) for idx in range(size): if idx == 0: item = array.Dereference() else: item = array.GetChildAtIndex(idx, lldb.eNoDynamicValues, True) ret += "\n[{}] = {}".format(idx, item.summary) return ret
def addOneShotBreakPointInIMP(imp: lldb.SBValue, callbackFunc: str, name: str) -> None: target = lldb.debugger.GetSelectedTarget() bp = target.BreakpointCreateByAddress(imp.GetValueAsUnsigned()) bp.AddName(name) bp.SetOneShot(True) bp.SetScriptCallbackFunction(callbackFunc)
def _read_uint64(valobj: lldb.SBValue) -> Optional[int]: logger = LoggerModule.Logger() error = lldb.SBError() result: int = valobj.GetData().GetUnsignedInt64(error, 0) if error.fail: logger.write(f'SBData::GetUnsignedInt64 failed: {error.description}') return None return result
def print_bitfield(valobj: lldb.SBValue, internal_dict: Dict) -> str: if valobj.GetType().IsReferenceType(): valobj = valobj.Dereference() array = (valobj.GetChildMemberWithName("m_buf").GetChildMemberWithName( "__ptr_").GetChildMemberWithName("__value_")) size = array.Dereference().GetValueAsUnsigned() ret = "size: {} bits | ".format(size) for idx in range((size + 31) // 32): item = array.GetChildAtIndex(idx + 1, lldb.eNoDynamicValues, True) buffer = item.GetData().uint8s for b in buffer: ret += "{:08b}".format(int(b)) size -= 8 return ret
def get_summary(cls, valobj: lldb.SBValue, bindings: dict) -> str: provider = cls(valobj.GetNonSyntheticValue(), bindings) dv = provider.debug_view result = [f'offset={dv.encoded_offset}:{dv.transcoded_offset}'] if dv.is_scalar_aligned is not None: result.append( f'aligned={_format_expression(dv.is_scalar_aligned)}') if dv.character_stride is not None: result.append(f'stride={_format_expression(dv.character_stride)}') return f"<{' '.join(result)}>"
def read_unique_ptr(valobj: lldb.SBValue): # Rust-enabled LLDB using DWARF debug info will strip tuple field prefixes. # If LLDB is not Rust-enalbed or if using PDB debug info, they will be underscore-prefixed. pointer: lldb.SBValue = valobj.GetChildMemberWithName("pointer") child: lldb.SBValue = pointer.GetChildMemberWithName("__0") # Plain lldb if child.IsValid(): return child child = pointer.GetChildMemberWithName("0") # rust-lldb if child.IsValid(): return child return pointer # pointer no longer contains NonZero since Rust 1.33
def set_metadata(self, lldb_obj: lldb.SBValue): self.__dict__["@type_name"] = lldb_obj.GetTypeName() self.__dict__["@location"] = lldb_obj.GetLocation() if lldb_obj.GetNumChildren() == 0: self.__dict__["@value"] = lldb_obj.GetValue() self.__dict__["@value_unsigned"] = lldb_obj.GetValueAsUnsigned() self.__dict__["@value_signed"] = lldb_obj.GetValueAsSigned()
def __init__(self, valobj: lldb.SBValue, dict={}): self.valobj = valobj self.ptr = gcm(self.valobj, "ptr", "pointer") self.item_type = self.ptr.GetType().GetPointeeType() self.item_size = self.item_type.GetByteSize() # The dim and strides requires more processing self.dim = [ v.GetValueAsUnsigned() for v in gcm(self.valobj, "dim", "index").get_value_child_list() ] self.strides = [ v.GetValueAsUnsigned() for v in gcm( self.valobj, "strides", "index").get_value_child_list() ] self.len = reduce(lambda p, i: p * i, self.dim, 1) synth_by_id[valobj.GetID()] = self
def _create_debug_view(valobj: lldb.SBValue) -> core.StringIndexDebugView: raw_bits = _read_uint64(valobj.GetChildMemberWithName('_rawBits')) return core.StringIndexDebugView(raw_bits or 0)
def member(self, value: lldb.SBValue, name: str) -> lldb.SBValue: return value.GetChildMemberWithName(name)
def get_name_or_address(lldb_obj: lldb.SBValue) -> str: return (f"<anonymous at {lldb_obj.GetAddress()}>" if lldb_obj.GetName() is None else lldb_obj.GetName())
def judgeSBValueHasValue(val: lldb.SBValue) -> bool: if val.GetValue() is None or val.GetValueAsSigned() == 0: return False return True
def print_strong_type(valobj: lldb.SBValue, internal_dict: Dict) -> str: if valobj.GetType().IsReferenceType(): valobj = valobj.Dereference() name = valobj.GetType().name data = valobj.GetChildMemberWithName("m_val").GetValue() if "piece_index_tag" in name: name = "piece_index" elif "file_index_tag" in name: name = "file_index" elif "queue_position_tag" in name: name = "queue_pos" elif "piece_extent_tag" in name: name = "piece_extent" elif "storage_index_tag_t" in name: name = "storage_index" elif "disconnect_severity_tag" in name: name = "disconnect_severity" val = valobj.GetChildMemberWithName("m_val").GetValueAsUnsigned() if val == 0: data = "normal" elif val == 1: data = "failure" elif val == 2: data = "peer_error" else: data = "<unknown> ({})".format(val) elif "prio_index_tag_t" in name: name = "prio_index" elif "port_mapping_tag" in name: name = "port_mapping" elif "dl_queue_tag" in name or name == "libtorrent::download_queue_t": name = "download_queue" val = valobj.GetChildMemberWithName("m_val").GetValueAsUnsigned() if val == 0: data = "piece_downloading" elif val == 1: data = "piece_full" elif val == 2: data = "piece_finished" elif val == 3: data = "piece_zero_prio" elif val == 4: data = "piece_open" elif val == 5: data = "piece_downloading_reverse" elif val == 6: data = "piece_full_reverse" else: data = "<unknown> ({})".format(val) elif "piece_extent_tag" in name: name = "piece_extent" elif "picker_options_tag" in name: name = "picker_options" val = valobj.GetChildMemberWithName("m_val").GetValueAsUnsigned() flags = [] if (val & 1) != 0: flags.append("rarest_first") if (val & 2) != 0: flags.append("reverse") if (val & 4) != 0: flags.append("on_parole") if (val & 8) != 0: flags.append("prioritize_partials") if (val & 16) != 0: flags.append("sequential") if (val & 64) != 0: flags.append("align_expanded_pieces") if (val & 128) != 0: flags.append("piece_extent_affinity") data = "|".join(flags) else: name = "" return "({}) {}".format(name, data)
def boolOfSBValue(val: lldb.SBValue) -> bool: result = val.GetValue() if result == "True" or result == "true" or result == "YES": return True return False
def __init__(self, valobj: lldb.SBValue, _: dict): assert not valobj.IsSynthetic() self.valobj = valobj self.debug_view = _create_debug_view(self.valobj)
def logRedirectResult(val: lldb.SBValue, stream: str) -> None: if val.GetValueAsSigned() == 0: HM.DPrint(f"redirect {stream} failed") else: HM.DPrint(f"redirect {stream} successful")