def update_disassembly(self): if not self.should_update(): return pc = parse_result_line(run_cmd("-data-evaluate-expression $pc", True))["value"] if " " in pc: pc = pc[:pc.find(" ")] pc = int(pc, 16) if not (pc >= self.start and pc <= self.end): l = run_cmd("-data-disassemble -s $pc -e \"$pc+200\" -- 1", True) asms = parse_result_line(l) self.clear() asms = asms["asm_insns"] if "src_and_asm_line" in asms: l = listify(asms["src_and_asm_line"]) for src_asm in l: line = src_asm["line"] file = src_asm["file"] self.add_line("%s:%s\n" % (file, line)) self.add_insns(src_asm["line_asm_insn"]) else: self.add_insns(asms) self.update() view = self.get_view() reg = view.find("^0x[0]*%x:" % pc, 0) if reg is None: view.erase_regions("sublimegdb.programcounter") else: pos_scope = get_setting("position_scope", "entity.name.class") pos_icon = get_setting("position_icon", "bookmark") view.add_regions("sublimegdb.programcounter", [reg], pos_scope, pos_icon, sublime.HIDDEN)
def update_variables(self, sameFrame): if not self.should_update(): return if sameFrame: for var in self.variables: var.clear_dirty() ret = parse_result_line(run_cmd("-var-update --all-values *", True))["changelist"] if "varobj" in ret: ret = listify(ret["varobj"]) dellist = [] for value in ret: name = value["name"] for var in self.variables: real = var.find(name) if real != None: if "in_scope" in value and value["in_scope"] == "false": real.delete() dellist.append(real) continue real.update(value) if not "value" in value and not "new_value" in value: real.update_value() break for item in dellist: self.variables.remove(item) loc = self.extract_varnames(parse_result_line(run_cmd("-stack-list-locals 0", True))["locals"]) tracked = [] for var in loc: create = True for var2 in self.variables: if var2["exp"] == var and var2 not in tracked: tracked.append(var2) create = False break if create: self.variables.append(self.create_variable(var)) else: for var in self.variables: var.delete() args = self.extract_varnames( parse_result_line(run_cmd("-stack-list-arguments 0 %d %d" % (gdb_stack_index, gdb_stack_index), True))[ "stack-args" ]["frame"]["args"] ) self.variables = [] for arg in args: self.variables.append(self.create_variable(arg)) loc = self.extract_varnames(parse_result_line(run_cmd("-stack-list-locals 0", True))["locals"]) for var in loc: self.variables.append(self.create_variable(var)) self.update_view()
def insert_breakpoint(filename, line): cmd = "-break-insert %s:%d" % (filename, line) out = run_cmd(cmd, True) if get_result(out) == "error": return None, 0 res = parse_result_line(out) if "bkpt" not in res and "matches" in res: cmd = "-break-insert *%s" % res["matches"]["b"][0]["addr"] out = run_cmd(cmd, True) if get_result(out) == "error": return None, 0 res = parse_result_line(out) bp = res["bkpt"] f = bp["fullname"] if "fullname" in bp else bp["file"] return f, int(bp["line"])
def update_cursor(): global gdb_cursor global gdb_cursor_position global gdb_stack_index global gdb_stack_frame currFrame = parse_result_line(run_cmd("-stack-info-frame", True))["frame"] gdb_stack_index = int(currFrame["level"]) if "fullname" in currFrame: gdb_cursor = currFrame["fullname"] gdb_cursor_position = int(currFrame["line"]) sublime.active_window().focus_group(get_setting("file_group", 0)) sublime.active_window().open_file("%s:%d" % (gdb_cursor, gdb_cursor_position), sublime.ENCODED_POSITION) else: gdb_cursor_position = 0 sameFrame = gdb_stack_frame != None and gdb_stack_frame["func"] == currFrame["func"] if sameFrame and "shlibname" in currFrame and "shlibname" in gdb_stack_frame: sameFrame = currFrame["shlibname"] == gdb_stack_frame["shlibname"] if sameFrame and "fullname" in currFrame and "fullname" in gdb_stack_frame: sameFrame = currFrame["fullname"] == gdb_stack_frame["fullname"] gdb_stack_frame = currFrame if gdb_stack_index == 0 and not sameFrame: gdb_callstack_view.update_callstack() update_view_markers() gdb_variables_view.update_variables(sameFrame) gdb_register_view.update_values() gdb_disassembly_view.update_disassembly()
def add_breakpoint(filename, line): if is_running(): res = wait_until_stopped() line = int(parse_result_line(run_cmd("-break-insert %s:%d" % (filename, line), True))["bkpt"]["line"]) if res: resume() breakpoints[filename].append(line)
def edit_on_done(self, val): line = run_cmd("-var-assign %s \"%s\"" % (self.get_name(), val), True) if get_result(line) == "done": self.valuepair["value"] = parse_result_line(line)["value"] gdb_variables_view.update_variables(True) else: err = line[line.find("msg=") + 4:] sublime.status_message("Error: %s" % err)
def update_threads(self): if not self.should_update(): return res = run_cmd("-thread-info", True) ids = parse_result_line(run_cmd("-thread-list-ids", True)) if get_result(res) == "error": if "thread-ids" in ids and "thread-id" in ids["thread-ids"]: self.threads = [GDBThread(int(id)) for id in ids["thread-ids"]["thread-id"]] if "threads" in ids and "thread" in ids["threads"]: for thread in ids["threads"]["thread"]: if "thread-id" in thread and "state" in thread: tid = int(thread["thread-id"]) for t2 in self.threads: if t2.id == tid: t2.state = thread["state"] break else: l = parse_result_line(run_cmd("-thread-info", True)) else: self.threads = [] else: l = parse_result_line(res) self.threads = [] for thread in l["threads"]: func = "???" if "frame" in thread and "func" in thread["frame"]: func = thread["frame"]["func"] args = "" if "args" in thread["frame"]: for arg in thread["frame"]["args"]: if len(args) > 0: args += ", " if "name" in arg: args += arg["name"] if "value" in arg: args += " = " + arg["value"] func = "%s(%s);" % (func, args) self.threads.append(GDBThread(int(thread["id"]), thread["state"], func)) if "current-thread-id" in ids: self.current_thread = int(ids["current-thread-id"]) self.clear(True) self.threads.sort(key=lambda t: t.id) for thread in self.threads: self.add_line(thread.format(), True)
def update_callstack(self): if not self.should_update(): return global gdb_cursor_position line = run_cmd("-stack-list-frames", True) if get_result(line) == "error": gdb_cursor_position = 0 update_view_markers() return frames = listify(parse_result_line(line)["stack"]["frame"]) args = listify(parse_result_line(run_cmd("-stack-list-arguments 1", True))["stack-args"]["frame"]) self.clear() self.frames = [] for i in range(len(frames)): f = GDBCallstackFrame(frames[i]["func"], args[i]["args"]) self.frames.append(f) self.add_line(f.format()) self.update()
def update_values(self): if not self.should_update(): return dirtylist = [] if self.values == None: names = self.get_names() vals = self.get_values() self.values = [] for i in range(len(vals)): idx = int(vals[i]["number"]) self.values.append(GDBRegister(names[idx], idx, vals[i]["value"])) else: dirtylist = regs = parse_result_line(run_cmd("-data-list-changed-registers", True))["changed-registers"] regvals = parse_result_line(run_cmd("-data-list-register-values x %s" % " ".join(regs), True))[ "register-values" ] for i in range(len(regs)): reg = int(regvals[i]["number"]) self.values[reg].set_value(regvals[i]["value"]) self.clear() line = 0 for item in self.values: output, line = item.format(line) self.add_line(output) self.update() regions = [] v = self.get_view() for dirty in dirtylist: i = int(dirty) region = v.full_line(v.text_point(self.values[i].line, 0)) if self.values[i].lines > 1: region = region.cover(v.full_line(v.text_point(self.values[i].line + self.values[i].lines - 1, 0))) regions.append(region) v.add_regions( "sublimegdb.dirtyregisters", regions, get_setting("changed_variable_scope", "entity.name.class"), get_setting("changed_variable_icon", ""), sublime.DRAW_OUTLINED, )
def add_children(self, name): children = listify(parse_result_line(run_cmd("-var-list-children 1 \"%s\"" % name, True))["children"]["child"]) for child in children: child = GDBVariable(child) if child.get_name().endswith(".private") or \ child.get_name().endswith(".protected") or \ child.get_name().endswith(".public"): if child.has_children(): self.add_children(child.get_name()) else: self.children.append(child)
def insert_breakpoint(filename, line): # Attempt to simplify file paths for windows. As some versions of gdb choke on drive specifiers if os.name == 'nt': filename=os.path.relpath(filename,get_setting('sourcedir')) cmd = "-break-insert \"'%s':%d\"" % (filename, line) out = run_cmd(cmd, True) if get_result(out) == "error": return None, 0 res = parse_result_line(out) if "bkpt" not in res and "matches" in res: cmd = "-break-insert *%s" % res["matches"]["b"][0]["addr"] out = run_cmd(cmd, True) if get_result(out) == "error": return None, 0 res = parse_result_line(out) if "bkpt" not in res: return None, 0 bp = res["bkpt"] f = bp["fullname"] if "fullname" in bp else bp["file"] return f, int(bp["line"])
def sync_breakpoints(): global breakpoints newbps = {} for file in breakpoints: for bp in breakpoints[file]: if file in newbps: if bp in newbps[file]: continue cmd = "-break-insert %s:%d" % (file, bp) out = run_cmd(cmd, True) if get_result(out) == "error": continue bp = parse_result_line(out)["bkpt"] f = bp["fullname"] if "fullname" in bp else bp["file"] if not f in newbps: newbps[f] = [] newbps[f].append(int(bp["line"])) breakpoints = newbps update_view_markers()
def update_cursor(): global gdb_cursor global gdb_cursor_position global gdb_stack_index global gdb_stack_frame res = run_cmd("-stack-info-frame", True) if get_result(res) == "error": if gdb_run_status != "running": print "run_status is %s, but got error: %s" % (gdb_run_status, res) return currFrame = parse_result_line(res)["frame"] gdb_stack_index = int(currFrame["level"]) if "fullname" in currFrame: gdb_cursor = currFrame["fullname"] gdb_cursor_position = int(currFrame["line"]) sublime.active_window().focus_group(get_setting("file_group", 0)) sublime.active_window().open_file("%s:%d" % (gdb_cursor, gdb_cursor_position), sublime.ENCODED_POSITION) else: gdb_cursor_position = 0 sameFrame = gdb_stack_frame != None and \ gdb_stack_frame["func"] == currFrame["func"] if sameFrame and "shlibname" in currFrame and "shlibname" in gdb_stack_frame: sameFrame = currFrame["shlibname"] == gdb_stack_frame["shlibname"] if sameFrame and "fullname" in currFrame and "fullname" in gdb_stack_frame: sameFrame = currFrame["fullname"] == gdb_stack_frame["fullname"] gdb_stack_frame = currFrame # Always need to update the callstack since it's possible to # end up in the current function from many different call stacks gdb_callstack_view.update_callstack() gdb_threads_view.update_threads() update_view_markers() gdb_variables_view.update_variables(sameFrame) gdb_register_view.update_values() gdb_disassembly_view.update_disassembly()
def update_value(self): line = run_cmd("-var-evaluate-expression %s" % self["name"], True) if get_result(line) == "done": self['value'] = parse_result_line(line)["value"]
def extract_breakpoints(line): res = parse_result_line(line) if "bkpt" in res["BreakpointTable"]: return listify(res["BreakpointTable"]["bkpt"]) else: return listify(res["BreakpointTable"]["body"]["bkpt"])
def create_variable(self, exp): line = run_cmd("-var-create - * %s" % exp, True) var = parse_result_line(line) var['exp'] = exp return GDBVariable(var)
def get_names(self): line = run_cmd("-data-list-register-names", True) return parse_result_line(line)["register-names"]
def get_values(self): line = run_cmd("-data-list-register-values x", True) if get_result(line) != "done": return [] return parse_result_line(line)["register-values"]