diff --git a/gdb-port/parser-name-instrumentation-gdb.py b/gdb-port/parser-name-instrumentation-gdb.py index 0eba78aefa289febd8babd3cf0a3f82dd83394ad..ec1067a227cfe67c8dfabba7bdb4dc383e35f718 100644 --- a/gdb-port/parser-name-instrumentation-gdb.py +++ b/gdb-port/parser-name-instrumentation-gdb.py @@ -297,6 +297,7 @@ class TopLevelParse: # TODO: get_avg_mem_use_all_arenas, get_total_mem_use +print(": Initializing TopLevelParse") top_level_parse = TopLevelParse() # Approach 1: load the application, set breakpoints, execute stack commands on breakpoint hit, continue @@ -386,6 +387,7 @@ hammer_retq_breakpoints = [] # func_retq = locate_retq(func[0], func[1]) # self.h_rule_breakpoints[func] = HRuleBreakpoint("*" + hex(func_retq)) +print(": Initializing BreakpointManager") breakpoint_manager = BreakpointManager(H_RULE_FUNCTIONS) class PDFMainBreakpoint(gdb.Breakpoint): @@ -398,6 +400,8 @@ class PDFMainBreakpoint(gdb.Breakpoint): # GDB parameters # TODO: hammer parameter prefix +print(": Registering commands") + class ExtendedParseStepInfo(gdb.Parameter): """Controls whether to display parser stack and input preview on stepping the parse.""" def __init__(self): @@ -405,6 +409,7 @@ class ExtendedParseStepInfo(gdb.Parameter): self.show_doc = "Show parser stack and input preview after hammer-parse-step:" #self.set_doc = "Show parser stack and input preview after hammer-parse-step:" self.value = True + print(":: hammer-extended-parse-step-info") ExtendedParseStepInfo() @@ -416,6 +421,7 @@ ExtendedParseStepInfo() class HammerParserBacktrace(gdb.Command): def __init__(self): super(HammerParserBacktrace, self).__init__ ("hammer-parser-backtrace", gdb.COMMAND_OBSCURE) + print(":: hammer-parser-backtrace") def invoke(self, arg, from_tty): parserstack = top_level_parse.peek_parserstack().p_stack @@ -448,6 +454,7 @@ HammerParserBacktrace() class HammerParserMemUse(gdb.Command): def __init__(self): super(HammerParserMemUse, self).__init__("hammer-parser-mem-use", gdb.COMMAND_OBSCURE) + print(":: hammer-parser-mem-use") def invoke(self, arg, from_tty): args = gdb.string_to_argv(arg) @@ -469,6 +476,7 @@ HammerParserMemUse() class HammerParserMemUseName(gdb.Command): def __init__(self): super(HammerParserMemUseName, self).__init__("hammer-parser-mem-use-name", gdb.COMMAND_OBSCURE) + print(":: hammer-parser-mem-use-name") def invoke(self, arg, from_tty): args = gdb.string_to_argv(arg) @@ -487,6 +495,7 @@ HammerParserMemUseName() class HammerParserTopSingleArenaMem(gdb.Command): def __init__(self): super(HammerParserTopSingleArenaMem, self).__init__("hammer-parser-top-single-arena-mem", gdb.COMMAND_OBSCURE) + print(":: hammer-parser-top-single-arena-mem") def invoke(self, arg, from_tty): args = gdb.string_to_argv(arg) @@ -499,6 +508,7 @@ HammerParserTopSingleArenaMem() class HammerParserTopTotalArenaMem(gdb.Command): def __init__(self): super(HammerParserTopTotalArenaMem, self).__init__("hammer-parser-top-total-arena-mem", gdb.COMMAND_OBSCURE) + print(":: hammer-parser-top-total-arena-mem") def invoke(self, arg, from_tty): args = gdb.string_to_argv(arg) @@ -515,6 +525,7 @@ HammerParserTopTotalArenaMem() class HammerParserPreviewInput(gdb.Command): def __init__(self): super(HammerParserPreviewInput, self).__init__("hammer-parser-preview-input", gdb.COMMAND_OBSCURE) + print(":: hammer-parser-preview-input") def invoke(self, arg, from_tty): args = gdb.string_to_argv(arg) @@ -526,6 +537,7 @@ HammerParserPreviewInput() class HammerParserAverageMem(gdb.Command): def __init__(self): super(HammerParserAverageMem, self).__init__("hammer-parser-average-mem", gdb.COMMAND_OBSCURE) + print(":: hammer-parser-average-mem") def invoke(self, arg, from_tty): args = gdb.string_to_argv(arg) @@ -539,6 +551,7 @@ HammerParserAverageMem() class HammerParserCurrentEnv(gdb.Command): def __init__(self): super(HammerParserCurrentEnv, self).__init__("hammer-parser-current-env", gdb.COMMAND_OBSCURE) + print(":: hammer-parser-current-env") def invoke(self, arg, from_tty): p = top_level_parse.h_do_parse_parser @@ -547,6 +560,7 @@ class HammerParserCurrentEnv(gdb.Command): HammerParserCurrentEnv() +print(": Registering exit handler") # Clean up by-address breakpoints in hammer when inferior exits. # Caveat: Assumes there's a single inferior, the debugged parser, so no checking is done # TODO: where to store breakpoints? TopLevelParse? A BreakpointManager class?i @@ -557,6 +571,7 @@ def exit_handler(event): gdb.events.exited.connect(exit_handler) +print(": Setting PDFMain breakpoint") # Break on main so that libhammer.so gets to load main = PDFMainBreakpoint("main") @@ -568,6 +583,8 @@ main = PDFMainBreakpoint("main") #h_packrat_parse = HPackratParseBreakpoint("h_packrat_parse") #perform_lowlevel_parse = PerformLowLevelParseBreakpoint("perform_lowlevel_parse") #h_arena_malloc_raw = HArenaMallocRawBreakpoint("h_arena_malloc_raw") +print(": Setting Hammer library breakpoints") +print(":: Normal breakpoints") breakpoint_manager.set_hammer_breakpoints() # TODO: investigate GDB frame filters for rendering backtraces @@ -604,12 +621,14 @@ breakpoint_manager.set_hammer_breakpoints() #parse_get = ParserVirtualBreakpoint("parse_get") #parse_whitespace = ParserVirtualBreakpoint("parse_whitespace") #parse_xor = ParserVirtualBreakpoint("parse_xor") +print(":: Parser vtable breakpoints") breakpoint_manager.set_parser_virtual_breakpoints() # Commandline: # $ gdb -ex "source /path/to/parser-name-instrumentation-gdb.py" --args /path/to/pdf /path/to/input.pdf # run until main +print(": Running until main") gdb.execute("run") #plp_retq = locate_perform_lowlevel_parse_retq() @@ -619,6 +638,8 @@ gdb.execute("run") #i_p_retq = breakpoint_manager.locate_retq("init_parser") #init_parser = InitParserBreakpoint("*" + hex(i_p_retq)) +print(": Setting application breakpoints") +print(":: init_parser breakpoint") breakpoint_manager.set_init_parser_breakpoint() #hammer_retq_breakpoints = [perform_lowlevel_parse_ret, h_packrat_parse_ret] @@ -628,14 +649,17 @@ breakpoint_manager.set_init_parser_breakpoint() #for func in H_RULE_FUNCTIONS: # func_retq = locate_retq(func[0], func[1]) # h_rule_breakpoints[func] = HRuleBreakpoint("*" + hex(func_retq)) +print(":: RET breakpoints in functions with H_RULES") breakpoint_manager.set_h_rule_breakpoints() # TODO: the RET breakpoints in hammer break when "run" is executed again. figure out a way to automatically replace these # Run until stop position, if set. Finish parsing otherwise +print(": Continuing execution") gdb.execute("continue") +print(": Printing memory statistics") print([(p.name, hex(p.address), p.bytes_used) for p in top_level_parse.parser_objs.values()]) # Approach 2: capture process trace with gdb, load the trace, execute stack commands on breakpoint hit, etc