def mstepi_update_and_display(self, frame): # this will update the Maple gdb runtime metadata store. m_datastore.mgdb_rdata.update_gdb_runtime_data() m_datastore.mgdb_rdata.update_frame_change_counter() ds = m_datastore.get_stack_frame_data(frame) if not ds: return if m_debug.Debug: m_debug.dbg_print("retrieved ds=", ds) if m_set.msettings['stack'] == 'on': m_util.gdb_exec('mlocal -stack') asm_path = ds['frame_func_header_info']['asm_path'] asm_line = ds['frame_func_src_info']['asm_line'] asm_offset = ds['frame_func_src_info']['asm_offset'] gdb_print("asm file: %s%s%s" % (MColors.BT_SRC, asm_path, MColors.ENDC)) f = open(asm_path, 'r') f.seek(asm_offset) gdb_print("=> %d : %s" % (asm_line, f.readline().rstrip())) gdb_print(" %d : %s" % (asm_line + 1, f.readline().rstrip())) gdb_print(" %d : %s" % (asm_line + 2, f.readline().rstrip())) f.close() m_util.gdb_exec('display')
def mni_display_last_opcodes(): # to display the latest instructions will be executed after this command frame = m_frame.get_selected_frame() if not frame: return ds = m_datastore.get_stack_frame_data(frame) if not ds: return if m_debug.Debug: m_debug.dbg_print("retrieved ds=", ds) if m_set.msettings['stack'] == 'on': m_util.gdb_exec('mlocal -stack') asm_path = ds['frame_func_header_info']['asm_path'] asm_line = ds['frame_func_src_info']['asm_line'] asm_offset = ds['frame_func_src_info']['asm_offset'] gdb_print("asm file: %s%s%s" % (MColors.BT_SRC, asm_path, MColors.ENDC)) f = open(asm_path, 'r') f.seek(asm_offset) line = f.readline() gdb_print(str(asm_line) + " : " + line.rstrip()) line = f.readline() gdb_print(str(asm_line+1) + " : " + line.rstrip()) line = f.readline() gdb_print(str(asm_line+2) + " : " + line.rstrip()) f.close()
def mstep_func(self, args): frame = m_frame.get_selected_frame() ds = m_datastore.get_stack_frame_data(frame) if not ds: return if m_debug.Debug: m_debug.dbg_print("retrieved ds=", ds) asm_path = ds['frame_func_header_info']['asm_path'] asm_line = ds['frame_func_src_info']['asm_line'] asm_offset = ds['frame_func_src_info']['asm_offset'] stop = False short_src_file_name = None short_src_file_line = None count = 0 while not stop: # before we execute msi command, we must know should we stop keep executing msi after the current msi # is executed. If current msi command is executed and found it should stop, then we need the source file # information after stop. stop, short_src_file_name, short_src_file_line = m_asm.look_up_next_opcode( asm_path, asm_line, asm_offset) if m_debug.Debug: m_debug.dbg_print("stop =", stop, "short_src_file_name=", short_src_file_name, "short_src_file_line=", short_src_file_line) m_util.gdb_exec("msi -internal") count += 1 if m_debug.Debug: m_debug.dbg_print("executed %d opcodes", count) # retrieve the new frame data since one opcode can change to a different frame frame = m_frame.get_selected_frame() ds = m_datastore.get_stack_frame_data(frame) if not ds: gdb_print("Warning: Failed to get new stack frame to continue") return if m_debug.Debug: m_debug.dbg_print("retrieved ds=", ds) asm_path = ds['frame_func_header_info']['asm_path'] asm_line = ds['frame_func_src_info']['asm_line'] asm_offset = ds['frame_func_src_info']['asm_offset'] gdb_print("Info: executed %d %s" % (count, 'opcode' if count == 1 else 'opcodes')) if m_debug.Debug: m_debug.dbg_print("short_src_file_name = ", short_src_file_name, "short_src_file_line=", short_src_file_line) file_full_path = None for source_path in m_list.maple_source_path_list: file_full_path = m_list.find_one_file(short_src_file_name, source_path) if not file_full_path: continue else: break if not file_full_path: gdb_print("Warning: source file %s not found" % (short_src_file_name)) else: m_list.display_src_file_lines(file_full_path, short_src_file_line) return
def __init__(self): gdb.Command.__init__ (self, "mbreak", gdb.COMMAND_BREAKPOINTS, gdb.COMPLETE_NONE) """ mbp_table: mbp_table is a runtime table mbreak command keeps. mbp_table is a dict, key of mbp_table item is the symbol. value of each item in mbp_table is also a dict. item dict defined as { 'count' : int, a count down number of a Maple symbol to be ignored 'disabled': True|False, 'object' : Instance object of class MapleBreakpoint, 'address' : Breakpoint reported by 'info b' command + 0x4 } """ self.mbp_object = None self.mbp_id = None self.mbp_dync_object = None self.mbp_dync_id = None self.symbol_index = 1 self.initialized_gdb_bp = False # create alias mb to mbreak m_util.gdb_exec('alias mb = mbreak')
def mfinish_func(self, args): frame = m_frame.get_newest_frame() if not frame: return silent_finish() m_util.gdb_exec("msi") m_util.gdb_exec("mlist") m_datastore.mgdb_rdata.update_frame_change_counter()
def __init__(self): gdb.Command.__init__(self, "mstepi", gdb.COMMAND_RUNNING, gdb.COMPLETE_NONE) self.mbp_object = None self.msi_bp_id = None m_util.gdb_exec('alias msi = mstepi') self.msi_mode_default = 0 self.msi_mode_internal = 1
def mfinish_func(self, args): frame = m_frame.get_newest_frame() if not frame: return silent_finish() frame = m_frame.get_selected_frame() if m_debug.Debug: m_debug.dbg_print("frame.name()=", frame.name()) m_util.gdb_exec("msi") m_util.gdb_exec("mlist") m_datastore.mgdb_rdata.update_frame_change_counter()
def disable_maple_invoke_bp_plt(buf): """ disable a Maple breakpoint plt params: buf: a string output of m_util.gdb_exec_to_str("info b") """ match_pattern = "<maple::maple_invoke_method(maple::method_header_t const*, maple::MFunction const*)@plt>" buf = buf.split('\n') for line in buf: if match_pattern in line: cmd = 'disable ' + line.split()[0] m_util.gdb_exec(cmd)
def disable_maple_invoke_dync_bp_plt(buf): """ disable a Maple breakpoint plt params: buf: a string output of m_util.gdb_exec_to_str("info b") """ match_pattern = "<maple::InvokeInterpretMethod(maple::DynMFunction&)@plt>" buf = buf.split('\n') for line in buf: if match_pattern in line: cmd = 'disable ' + line.split()[0] m_util.gdb_exec(cmd)
def update_maple_invoke_bp(buf, op_enable=True): """ update maple::maple_invoke_method breakpoint when number of enabled maple breakpoints is 0, disable maple::maple_invoke_method when number of enabled maple breakpoints changes from 0 to non-0, enable maple::maple_invoke_method but if maple::maple_invoke_method is pending, then do nothing. params: buf: a string output of m_util.gdb_exec_to_str("info b") op_enable = True, to enable the maple::maple_invoke_method op_enable = False, to disable the maple::maple_invoke_method """ match_pattern = "in maple::maple_invoke_method(maple::method_header_t const*, maple::MFunction const*)" buf = buf.split('\n') for line in buf: if match_pattern in line: cmd = 'disable ' if op_enable is False else 'enable ' cmd += line.split()[0] m_util.gdb_exec(cmd)
def debugger_exception_handler(etype, evalue, etraceback): """ Exception handler for Maple debugger """ import traceback if type(evalue) is KeyboardInterrupt: gdb.write('Interrupted by user.\n', gdb.STDERR) elif type(evalue) is gdb.error: gdb.write('gdb.error occured.\n', gdb.STDERR) else: gdb.write( 'Warning, an uncaught exception occured. ' 'Enable trace with "mset trace on" for more details.\n', gdb.STDERR) traceback.print_exception(etype, evalue, etraceback) if not m_util.is_interactive(): m_util.gdb_exec('quit') # Resume trace setting if it has been set if sys.getprofile() == m_set.trace_maple_debugger: sys.setprofile(m_set.trace_maple_debugger)
def mni_func(self, args, from_tty): s = args.split() if len(s) > 1: # msi into next Maple instruction self.usage() return if len(s) == 0: mni_common() elif len(s) == 1 and s[0].isdigit(): for i in range(int(s[0])): if m_inf.is_inferior_running(): mni_common() else: break else: self.usage() return if m_inf.is_inferior_running(): mni_display_last_opcodes() m_util.gdb_exec('display') return
def mni_common(): #start_level_num = get_current_stack_level() prev_frame = m_frame.get_newest_frame() m_util.gdb_exec('msi -internal') new_frame = m_frame.get_newest_frame() #end_level_num = get_current_stack_level() if not new_frame: return if new_frame != prev_frame and prev_frame.is_valid(): #assert start_level_num < end_level_num m_stepi.silent_finish() m_util.gdb_exec('msi -internal') #else: # assert start_level_num >= end_level_num # a trigger point to update m_datastore caches if m_inf.is_inferior_running(): m_datastore.mgdb_rdata.update_gdb_runtime_data() m_datastore.mgdb_rdata.update_frame_change_counter()
def __init__(self): gdb.Command.__init__(self, "msrcpath", gdb.COMMAND_FILES, gdb.COMPLETE_NONE) global maple_source_path_list # add current working directory at the top line = m_util.gdb_exec_to_str('pwd') if line: s = line.split() line = s[2][:-1] if len(s) is 3 else None if line: maple_source_path_list.append( os.path.expandvars(os.path.expanduser(line))) ''' if len(maple_source_path_list) == 1: gdb_print("Maple application source code search path only has one path as following:") gdb_print(" ", maple_source_path_list[0]) gdb_print("Please add more search paths using msrcpath -add <path> command") ''' m_util.gdb_exec('alias msp = msrcpath')
def __init__(self): gdb.Command.__init__(self, "mstep", gdb.COMMAND_RUNNING, gdb.COMPLETE_NONE) m_util.gdb_exec('alias ms = mstep')
def silent_finish(): fbp = MapleFinishBreakpoint() m_util.gdb_exec("continue")
def init_gdb(): m_util.gdb_exec('set auto-load python-scripts off') m_util.enable_color_output(m_util.is_interactive()) sys.excepthook = debugger_exception_handler m_event.init_event_handlers()
def mstepi_common_dync(self, threadno, count): msi_bp_dync_exist, msi_bp_dync_id = is_msi_bp_dync_existed() if not msi_bp_dync_exist: # there is no msi bp exist, so just create a new msi breakpoint self.init_gdb_breakpoint(threadno, count, False, True) else: if msi_bp_dync_id != self.msi_bp_dync_id: # if existing msi bp id does not match to self.msi_bp_id gdb_print( "There are one or more breakpints already created at __inc_opcode_cnt_dyn\n" "In order to use mstepi command, please delete those breakpoints first\n" ) return None else: # the existing msi bp id matches to self.msi_bp_id, it was created # by mstepi command previously. if self.msi_bp_dync_id.enabled is False: enable_msi_bp_dync() self.mbp_dync_object.set_bp_attr('thread', threadno) self.mbp_dync_object.set_bp_attr('count', count) assert count > 0 if self.mbp_dync_object.ignore_count != count - 1: self.mbp_dync_object.ignore_count = count - 1 hitcnt = self.mbp_dync_object.hit_count # It is important to perform a continue command here for the msi breakpoint # to be reached. m_util.gdb_exec("continue") """ if the msi breakpoint's count reaches to 1, it will return True to cause gdb stop at msi breakpoint by previous 'continue' command. Once gdb stops here, a gdb 'finish' command shall be called. However, 'finish' command must NOT be called inside of msi breakpoint stop() logic """ frame = None if self.mbp_dync_object.hit_count - hitcnt == count: """ if gdb stops here, it must have hit one breakpoint. However. the breakpoint it hits may not be the msi breakpoint, it could be another breakpoint the user set up. In this case, we check if it is a Maple frame. If it is, then the breakpoint is ours. Otherwise just stop here and return because it hit a user's other stop. """ frame = m_frame.get_selected_frame() if not frame: return None if not m_frame.is_maple_frame(frame): if m_set.msettings['opcode'] == 'on': m_util.gdb_exec("finish") else: silent_finish() # now get the new selected frame frame = m_frame.get_selected_frame() if not frame: return None # this will update the Maple gdb runtime metadata store. m_datastore.mgdb_rdata.update_gdb_runtime_data() m_datastore.mgdb_rdata.update_frame_change_counter() # always disable msi breakpoint after msi is excuted disable_msi_bp_dync() return frame
def __init__(self): gdb.Command.__init__(self, "mbacktrace", gdb.COMMAND_STACK, gdb.COMPLETE_NONE) m_util.gdb_exec('alias mbt = mbacktrace')
def __init__(self): gdb.Command.__init__ (self, "mnexti", gdb.COMMAND_RUNNING, gdb.COMPLETE_NONE) m_util.gdb_exec('alias mni = mnexti')