this repo has no description
at trunk 92 lines 2.9 kB view raw
1#!/usr/bin/env python2 2# Copyright (c) Facebook, Inc. and its affiliates. (http://www.facebook.com) 3 4# To enable, put something like this in ~/.lldbinit: 5# 6# command script import $PYRO_ROOT/util/lldb_support.py 7# type summary add -F lldb_support.format_raw_object -p -x "python::Raw.*" 8 9import lldb 10 11 12def as_enum(target, name, value): 13 """Given a name like LayoutId or ObjectFormat and an int, return the string 14 name of the value. 15 """ 16 type = target.FindFirstType("python::" + name) 17 data = lldb.SBData.CreateDataFromInt(value, size=type.size) 18 enum = target.CreateValueFromData(name, data, type) 19 return str(enum).split(" = ")[1] 20 21 22def format_heap_obj(val, raw): 23 """Format a HeapObject's address and information from its header.""" 24 address = raw - 1 25 header_type = val.target.FindFirstType("python::RawHeader") 26 header = val.CreateValueFromAddress("header", address - 8, header_type) 27 header_raw = header.GetChildMemberWithName("raw_").GetValueAsUnsigned() 28 return "HeapObject @ 0x%x %s" % (address, format_header(val, header_raw)) 29 30 31def get_bits(raw, n): 32 """Extract n bottom bits from raw, returning the value and raw with those 33 bits shifted out. 34 """ 35 return (raw & ((1 << n) - 1), raw >> n) 36 37 38def format_header(val, raw): 39 """Format all relevant information from a HeapObject's header.""" 40 tag, raw = get_bits(raw, 3) 41 format, raw = get_bits(raw, 3) 42 layout_id, raw = get_bits(raw, 20) 43 hash, raw = get_bits(raw, 30) 44 count, raw = get_bits(raw, 8) 45 return "Header<%s, %s, hash=%d, count=%d>" % ( 46 as_enum(val.target, "ObjectFormat", format), 47 as_enum(val.target, "LayoutId", layout_id), 48 hash, 49 count, 50 ) 51 52 53def format_error_or_seq(raw): 54 """Format an error or small sequence.""" 55 tag = (raw >> 3) & 0x3 56 if tag == 2: 57 return "Error" 58 if tag == 3: 59 return "<invalid>" 60 raw >>= 5 61 length = raw & 0x7 62 raw >>= 3 63 result = "" 64 for _i in range(length): 65 result += chr(raw & 0xFF) 66 raw >>= 8 67 return "%s('%s')" % ("SmallStr" if tag == 1 else "SmallBytes", result) 68 69 70def format_imm(raw): 71 """Format one of the singleton immediate values.""" 72 tag = (raw >> 3) & 0x3 73 if tag == 0: 74 return "True" if raw & 0x20 else "False" 75 return ("NotImplemented", "Unbound", "None")[tag - 1] 76 77 78def format_raw_object(raw_object, internal_dict): 79 """Format a RawObject.""" 80 raw = raw_object.GetChildMemberWithName("raw_").GetValueAsUnsigned() 81 # SmallInt 82 if raw & 0x1 == 0: 83 return str(raw_object.GetChildMemberWithName("raw_").GetValueAsSigned() >> 1) 84 85 low_tag = (raw >> 1) & 0x3 86 if low_tag == 0: 87 return format_heap_obj(raw_object, raw) 88 if low_tag == 1: 89 return format_header(raw_object, raw) 90 if low_tag == 2: 91 return format_error_or_seq(raw) 92 return format_imm(raw)