diff --git a/gdb-port/parser-name-instrumentation-gdb.py b/gdb-port/parser-name-instrumentation-gdb.py index 6d55b62c2df54cb00ba11015f42c27060311a686..bf886b226de1d39e4e7f457263b14e7830d19ccb 100644 --- a/gdb-port/parser-name-instrumentation-gdb.py +++ b/gdb-port/parser-name-instrumentation-gdb.py @@ -122,6 +122,12 @@ class TopLevelParse: # Holds 32 characters starting at state->input_stream[index], used by the GUI self.current_input_chunk = '' self.current_parser_env = '' + self.vt_types = None + self.parser_decombinator = None + + def init_parser(self): + self.vt_types = VTTypes() + self.parser_decombinator = ParserDecombinator(self.vt_types) # Called from h_packrat_parse()'s handler, where the parse state and arena get initialized def enter_h_packrat_parse(self, parser): @@ -160,8 +166,8 @@ class TopLevelParse: parser_stack = self.peek_parserstack() parser_stack.push(parser_obj) - if parser_decombinator: - p_env = parser_decombinator.decompose_parser(parser_obj, self) + if self.parser_decombinator: + p_env = self.parser_decombinator.decompose_parser(parser_obj, self) self.set_parser_env(str(p_env)) return parser_obj @@ -345,6 +351,7 @@ class InitParserBreakpoint(gdb.Breakpoint): def stop(self): frame = gdb.selected_frame() block = frame.block() + top_level_parse.init_parser() # This will also catch locals that aren't parsers, but it's not a problem in practice, # since h_parse() will never be called on them diff --git a/gdb-port/parser-type-instrumentation-gdb.py b/gdb-port/parser-type-instrumentation-gdb.py index 59c4b26e4fc8ae3c7aba878bc54a369acb3f6080..93a017d0cc778726ec157490a5e9358cd86f3eb1 100644 --- a/gdb-port/parser-type-instrumentation-gdb.py +++ b/gdb-port/parser-type-instrumentation-gdb.py @@ -39,6 +39,7 @@ parser_name_defaults = { } class VTTypes: + # Intended to be initialized in InitParserBreakpoint def __init__(self): self.vt_symbols = {int(gdb.lookup_symbol(key)[0].value().address) : gdb.lookup_symbol(key)[0] for key in parser_name_defaults.keys()} @@ -52,11 +53,12 @@ class VTTypes: except KeyError: return None -vt_types = VTTypes() +#vt_types = VTTypes() class HParserEnv: def __init__(self, parser, top_level_parse): print("HParserEnv constructed") # DEBUG + self.vt_types = top_level_parse.vt_types # Memoize parser type list # parser is expected to be a Parser object def name_from_vtable(self, parser): @@ -65,7 +67,7 @@ class HParserEnv: # perhaps using gdb.Value would be the best vtable_p = gdb.parse_and_eval("((HParser*) " + str(parser_addr) + ")->vtable") try: - name = parser_name_defaults[vt_types.lookup_by_address(vtable_p).name] + name = parser_name_defaults[self.vt_types.lookup_by_address(vtable_p).name] # if lookup_by_address() returns None except AttributeError: name = "(Unknown parser type (vtable symbol not found in lookup)" @@ -130,14 +132,14 @@ class ActionEnv(HParserEnv): def __init__(self, parser, top_level_parse): self.parser = parser - member_parser_p = gdb.parse_and_eval("((HParseAction*) parser->env)->p"); + member_parser_p = gdb.parse_and_eval("((HParseAction*) parser->env)->p") parser_obj = top_level_parse.add_or_get_parser(member_parser_p) self.member_parser = parser_obj # should return a HAction - action = gdb.parse_and_eval("((HParseAction*) parser->env)->action"); + action = gdb.parse_and_eval("((HParseAction*) parser->env)->action") self.action = int(action) - user_data_p = gdb.parse_and_eval("(HParseAction*) parser->env)->user_data"); + user_data_p = gdb.parse_and_eval("((HParseAction*) parser->env)->user_data") self.user_data_p = int(user_data_p) def __str__(self): @@ -159,7 +161,7 @@ class ChEnv(HParserEnv): self.parser = parser self.ch_arg = gdb.parse_and_eval("(uint8_t) parser->env") - self.ch_value = ord(self.ch_arg.value()) + self.ch_value = int(self.ch_arg) def __str__(self): return str(self.ch_value) @@ -549,21 +551,20 @@ vtable_to_env = { # ParserDecomposer? class ParserDecombinator: - def __init__(self): + def __init__(self, vt_types): # TODO: make a better data structure than vtable_to_env + parser_name_defaults + this self.vt_envs = { k : (v,vtable_to_env[k]) for k,v in parser_name_defaults.items() } + self.vt_types = vt_types def decompose_parser(self, parser, top_level_parse): # Sadly, this is stringly typed for now parser_addr = parser.address vtable_p = gdb.parse_and_eval("((HParser*) " + str(parser_addr) + ")->vtable") try: - vtable_sym = vt_types.lookup_by_address(vtable_p) + vtable_sym = self.vt_types.lookup_by_address(vtable_p) envClass = vtable_to_env[vtable_sym.name] except KeyError: print("Unknown vtable: " + str(vtable_p)) return None return envClass(parser, top_level_parse) - -parser_decombinator = ParserDecombinator()