this repo has no description
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)