# Should be loaded last print(": Initializing BreakpointManager") breakpoint_manager = BreakpointManager(H_RULE_FUNCTIONS) 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 def exit_handler(event): #breakpoints = [ perform_lowlevel_parse_ret, h_packrat_parse_ret ] #del_hammer_retq_breakpoints(breakpoints) breakpoint_manager.del_hammer_retq_breakpoints() gdb.events.exited.connect(exit_handler) print(": Setting PDFMain breakpoint") # Break on main so that libhammer.so gets to load main = PDFMainBreakpoint("main") print(": Setting Hammer library breakpoints") print(":: Normal breakpoints") breakpoint_manager.set_hammer_breakpoints() #TODO: there would be less complaining about pending breakpoints if vtable breakpoints were set after running to main print(":: Parser vtable breakpoints") breakpoint_manager.set_parser_virtual_breakpoints() # run until main print(": Running until main") gdb.execute("run") print(": Setting application breakpoints") print(":: init_parser breakpoint") breakpoint_manager.set_init_parser_breakpoint() 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()])