diff --git a/scripts/gdb/commands.py b/scripts/gdb/commands.py index 76d255fe2699a7084aad955ae8d2045d662b293c..796baedfec150f1b426c2b0f80d083027602096b 100644 --- a/scripts/gdb/commands.py +++ b/scripts/gdb/commands.py @@ -1,17 +1,18 @@ -import sys -import gdb - import re import subprocess +import sys +import gdb _demangle_cache = {} def demangle(name): if name not in _demangle_cache: - _demangle_cache[name] = subprocess.run(['c++filt', "-t", name], stdout=subprocess.PIPE).stdout - return _demangle_cache[name].decode('utf-8').strip() + _demangle_cache[name] = subprocess.run( + ["c++filt", "-t", name], stdout=subprocess.PIPE + ).stdout + return _demangle_cache[name].decode("utf-8").strip() def dynamic_cast(val): @@ -52,11 +53,21 @@ def shared_ptr_deref(ptr): def get_type_name(type_index): - return gdb.lookup_global_symbol("mgb::imperative::debug::get_type_name(std::type_index const&)").value()(type_index).string() + return ( + gdb.lookup_global_symbol( + "mgb::imperative::debug::get_type_name(std::type_index const&)" + ) + .value()(type_index) + .string() + ) -mge_apply_transform_pattern = re.compile(r"^(.*)::apply_transform\(mgb::imperative::Operator const&, mgb::imperative::Span\)$") -mge_op_fallback_pattern = re.compile(r"^(.*)::fallback\(mgb::imperative::Span\) const$") +mge_apply_transform_pattern = re.compile( + r"^(.*)::apply_transform\(mgb::imperative::Operator const&, mgb::imperative::Span\)$" +) +mge_op_fallback_pattern = re.compile( + r"^(.*)::fallback\(mgb::imperative::Span\) const$" +) def is_mge_frame(frame): @@ -66,11 +77,15 @@ def is_mge_frame(frame): matcher = mge_apply_transform_pattern.match(function.name) if matcher: typename = matcher.group(1) - return is_subclass_of(gdb.lookup_type(typename), gdb.lookup_type("mgb::imperative::Transform")) + return is_subclass_of( + gdb.lookup_type(typename), gdb.lookup_type("mgb::imperative::Transform") + ) matcher = mge_op_fallback_pattern.match(function.name) if matcher: typename = matcher.group(1) - return is_subclass_of(gdb.lookup_type(typename), gdb.lookup_type("mgb::imperative::Operator")) + return is_subclass_of( + gdb.lookup_type(typename), gdb.lookup_type("mgb::imperative::Operator") + ) return False @@ -84,18 +99,24 @@ def count_frame_level(frame): def print_mge_frame(frame): function = frame.function() - op = eval_on_val(dynamic_cast(frame.read_var("op")), ".to_string().c_str()").string() + op = eval_on_val( + dynamic_cast(frame.read_var("op")), ".to_string().c_str()" + ).string() inputs = str(frame.read_var("inputs")) matcher = mge_apply_transform_pattern.match(function.name) if matcher: name = matcher.group(1) else: name = mge_op_fallback_pattern.match(function.name).group(1) - #TODO: span + # TODO: span sal = frame.find_sal() filename = sal.symtab.filename line = sal.line - print("#{} {} apply {} on {}, file: {}:{}".format(count_frame_level(frame), name, op, inputs, filename, line)) + print( + "#{} {} apply {} on {}, file: {}:{}".format( + count_frame_level(frame), name, op, inputs, filename, line + ) + ) class MegengineBacktrace(gdb.Command): @@ -118,7 +139,9 @@ class MegengineBreakApply(gdb.Command): super().__init__("mge-brk-apply", gdb.COMMAND_USER) def invoke(self, arg, from_tty): - gdb.Breakpoint("mgb::imperative::apply(mgb::imperative::Operator const&, mgb::imperative::Span)") + gdb.Breakpoint( + "mgb::imperative::apply(mgb::imperative::Operator const&, mgb::imperative::Span)" + ) class MegengineWatch(gdb.Command): @@ -126,7 +149,9 @@ class MegengineWatch(gdb.Command): super().__init__("mge-watch", gdb.COMMAND_USER) def invoke(self, arg, from_tty): - watch = gdb.lookup_global_symbol("mgb::imperative::debug::watch_value(mgb::imperative::ValueRef)").value() + watch = gdb.lookup_global_symbol( + "mgb::imperative::debug::watch_value(mgb::imperative::ValueRef)" + ).value() value = gdb.parse_and_eval(arg) watch(value) print("watching {}".format(str(value))) @@ -176,7 +201,9 @@ class MegengineInfo(gdb.Command): def invoke(self, arg, from_tty): if arg == "opr": - registered_oprs = gdb.lookup_global_symbol("mgb::imperative::Operator::registered_types()").value()() + registered_oprs = gdb.lookup_global_symbol( + "mgb::imperative::Operator::registered_types()" + ).value()() size = vector_size(registered_oprs) for i in range(size): registered_opr = vector_item(registered_oprs, i) @@ -184,7 +211,9 @@ class MegengineInfo(gdb.Command): name = get_type_name(registered_opr) print("{}: {}".format(i, demangle(name))) elif arg == "trf": - dispatch_context = gdb.lookup_global_symbol("mgb::imperative::Transform::get_context()").value()() + dispatch_context = gdb.lookup_global_symbol( + "mgb::imperative::Transform::get_context()" + ).value()() transformations = dispatch_context["transformations"] size = vector_size(transformations) for i in range(size): @@ -207,7 +236,7 @@ if sys.version_info.major > 2: MegengineDown() MegengineInfo() MegengineWatch() - + gdb.Breakpoint("mgb::imperative::debug::notify_event(char const*)") else: print("skip import commands") diff --git a/scripts/gdb/pretty_printers.py b/scripts/gdb/pretty_printers.py index ef17f4ff331860a1850575a29efe4a47acd47070..9ec1fa77b06cd3cc2b28046b4f9b4753c65f75a5 100644 --- a/scripts/gdb/pretty_printers.py +++ b/scripts/gdb/pretty_printers.py @@ -1,4 +1,5 @@ import sys + import gdb import gdb.printing import gdb.types @@ -21,38 +22,40 @@ def eval_on_val(val, eval_str): class SmallVectorPrinter: def __init__(self, val): t = val.type.template_argument(0) - self.begin = val['m_begin_ptr'].cast(t.pointer()) - self.end = val['m_end_ptr'].cast(t.pointer()) + self.begin = val["m_begin_ptr"].cast(t.pointer()) + self.end = val["m_end_ptr"].cast(t.pointer()) self.size = self.end - self.begin - self.capacity = val['m_capacity_ptr'].cast(t.pointer()) - val['m_begin_ptr'].cast(t.pointer()) + self.capacity = val["m_capacity_ptr"].cast(t.pointer()) - val[ + "m_begin_ptr" + ].cast(t.pointer()) def to_string(self): - return 'SmallVector of Size {}'.format(self.size) + return "SmallVector of Size {}".format(self.size) def display_hint(self): - return 'array' + return "array" def children(self): for i in range(self.size): - yield "[{}]".format(i), (self.begin+i).dereference() + yield "[{}]".format(i), (self.begin + i).dereference() class MaybePrinter: def __init__(self, val): - self.val = val['m_ptr'] + self.val = val["m_ptr"] def to_string(self): if self.val: - return 'Some {}'.format(self.val) + return "Some {}".format(self.val) else: - return 'None' + return "None" def display_hint(self): - return 'array' + return "array" def children(self): if self.val: - yield '[0]', self.val.dereference() + yield "[0]", self.val.dereference() class ToStringPrinter: @@ -81,16 +84,16 @@ class HandlePrinter: def to_string(self): if self.val: - return 'Handle of TensorInfo at {}'.format(self.val) + return "Handle of TensorInfo at {}".format(self.val) else: - return 'Empty Handle' + return "Empty Handle" def display_hint(self): - return 'array' + return "array" def children(self): if self.val: - yield '[0]', self.val.dereference() + yield "[0]", self.val.dereference() def print_small_tensor(device_nd): @@ -124,17 +127,17 @@ def print_small_tensor(device_nd): class LogicalTensorDescPrinter: def __init__(self, val): - self.layout = val['layout'] - self.comp_node = val['comp_node'] - self.value = val['value'] + self.layout = val["layout"] + self.comp_node = val["comp_node"] + self.value = val["value"] def to_string(self): - return 'LogicalTensorDesc' + return "LogicalTensorDesc" def children(self): - yield 'layout', self.layout - yield 'comp_node', self.comp_node - yield 'value', print_small_tensor(self.value) + yield "layout", self.layout + yield "comp_node", self.comp_node + yield "value", print_small_tensor(self.value) class OpDefPrinter: @@ -145,49 +148,67 @@ class OpDefPrinter: return self.val.dynamic_type.name def children(self): - concrete_val = self.val.address.cast(self.val.dynamic_type.pointer()).dereference() + concrete_val = self.val.address.cast( + self.val.dynamic_type.pointer() + ).dereference() for field in concrete_val.type.fields(): if field.is_base_class or field.artificial: continue - if field.name == 'sm_typeinfo': + if field.name == "sm_typeinfo": continue yield field.name, concrete_val[field.name] class SpanPrinter: def __init__(self, val): - self.begin = val['m_begin'] - self.end = val['m_end'] + self.begin = val["m_begin"] + self.end = val["m_end"] self.size = self.end - self.begin def to_string(self): - return 'Span of Size {}'.format(self.size) + return "Span of Size {}".format(self.size) def display_hint(self): - return 'array' + return "array" def children(self): for i in range(self.size): - yield "[{}]".format(i), (self.begin+i).dereference() + yield "[{}]".format(i), (self.begin + i).dereference() if sys.version_info.major > 2: pp = gdb.printing.RegexpCollectionPrettyPrinter("MegEngine") -# megdnn - pp.add_printer('megdnn::SmallVectorImpl', '^megdnn::SmallVector(Impl)?<.*>$', SmallVectorPrinter) - pp.add_printer('megdnn::TensorLayout', '^megdnn::TensorLayout$', ToStringPrinter) - pp.add_printer('megdnn::TensorShape', '^megdnn::TensorShape$', ToStringPrinter) -# megbrain - pp.add_printer('mgb::CompNode', '^mgb::CompNode$', ToStringPrinter) - pp.add_printer('mgb::Maybe', '^mgb::Maybe<.*>$', MaybePrinter) -# imperative - pp.add_printer('mgb::imperative::LogicalTensorDesc', '^mgb::imperative::LogicalTensorDesc$', LogicalTensorDescPrinter) - pp.add_printer('mgb::imperative::OpDef', '^mgb::imperative::OpDef$', OpDefPrinter) - pp.add_printer('mgb::imperative::Subgraph', '^mgb::imperative::Subgraph$', ReprPrinter) - pp.add_printer('mgb::imperative::EncodedSubgraph', '^mgb::imperative::EncodedSubgraph$', ReprPrinter) -# imperative dispatch - pp.add_printer('mgb::imperative::ValueRef', '^mgb::imperative::ValueRef$', ToStringPrinter) - pp.add_printer('mgb::imperative::Span', '^mgb::imperative::Span<.*>$', SpanPrinter) + # megdnn + pp.add_printer( + "megdnn::SmallVectorImpl", + "^megdnn::SmallVector(Impl)?<.*>$", + SmallVectorPrinter, + ) + pp.add_printer("megdnn::TensorLayout", "^megdnn::TensorLayout$", ToStringPrinter) + pp.add_printer("megdnn::TensorShape", "^megdnn::TensorShape$", ToStringPrinter) + # megbrain + pp.add_printer("mgb::CompNode", "^mgb::CompNode$", ToStringPrinter) + pp.add_printer("mgb::Maybe", "^mgb::Maybe<.*>$", MaybePrinter) + # imperative + pp.add_printer( + "mgb::imperative::LogicalTensorDesc", + "^mgb::imperative::LogicalTensorDesc$", + LogicalTensorDescPrinter, + ) + pp.add_printer("mgb::imperative::OpDef", "^mgb::imperative::OpDef$", OpDefPrinter) + pp.add_printer( + "mgb::imperative::Subgraph", "^mgb::imperative::Subgraph$", ReprPrinter + ) + pp.add_printer( + "mgb::imperative::EncodedSubgraph", + "^mgb::imperative::EncodedSubgraph$", + ReprPrinter, + ) + # imperative dispatch + pp.add_printer( + "mgb::imperative::ValueRef", "^mgb::imperative::ValueRef$", ToStringPrinter + ) + pp.add_printer("mgb::imperative::Span", "^mgb::imperative::Span<.*>$", SpanPrinter) gdb.printing.register_pretty_printer(gdb.current_objfile(), pp) else: print("skip import pretty printers") diff --git a/scripts/gdb/xmethods.py b/scripts/gdb/xmethods.py index 9dfc54f87f10eb33c03ebac125ce68356b1eb2d6..fe4de72fa394e7e9ff8968077d2b4331be25fb3e 100644 --- a/scripts/gdb/xmethods.py +++ b/scripts/gdb/xmethods.py @@ -1,5 +1,5 @@ -import sys import re +import sys import gdb import gdb.types @@ -11,13 +11,13 @@ class SmallVectorImplWorker_at(gdb.xmethod.XMethodWorker): self.t = t def get_arg_types(self): - return gdb.lookup_type('int') + return gdb.lookup_type("int") def get_result_type(self, *args): return self.t def __call__(self, obj, i): - return (obj['m_begin_ptr'].cast(self.t.pointer()) + i).dereference() + return (obj["m_begin_ptr"].cast(self.t.pointer()) + i).dereference() class SmallVectorImplWorker_size(gdb.xmethod.XMethodWorker): @@ -28,24 +28,25 @@ class SmallVectorImplWorker_size(gdb.xmethod.XMethodWorker): return None def get_result_type(self, *args): - return gdb.lookup_type('int') + return gdb.lookup_type("int") def __call__(self, obj): - return obj['m_end_ptr'].cast(self.t.pointer()) - obj['m_begin_ptr'].cast(self.t.pointer()) - - + return obj["m_end_ptr"].cast(self.t.pointer()) - obj["m_begin_ptr"].cast( + self.t.pointer() + ) + + class SmallVectorImplMatcher(gdb.xmethod.XMethodMatcher): def __init__(self): - super().__init__('SmallVectorImplMatcher') - + super().__init__("SmallVectorImplMatcher") + def match(self, class_type, method_name): - if re.match('^megdnn::SmallVector(Impl)?<.*>', - class_type.tag): - if method_name == 'at': + if re.match("^megdnn::SmallVector(Impl)?<.*>", class_type.tag): + if method_name == "at": return SmallVectorImplWorker_at(class_type.template_argument(0)) - if method_name == 'operator[]': + if method_name == "operator[]": return SmallVectorImplWorker_at(class_type.template_argument(0)) - if method_name == 'size': + if method_name == "size": return SmallVectorImplWorker_size(class_type.template_argument(0))