def get_current_frame(self, with_variables=False):
        """
        Returns the current stack frame, optionally with it's parameters.
        @type with_variables: bool
        @rtype: debugee.Frame | None
        """
        output = self.debugger.communicator.send("-stack-info-frame")

        if output:
            try:
                frame = self.parser.parse_stack_frame(output.data)

                if with_variables:
                    variables_info = self.parser.parse_frame_variables(
                        self.debugger.communicator.send(
                            "-stack-list-variables --skip-unavailable 0").data)

                    for variable in variables_info:
                        try:
                            variable = self.debugger.variable_manager.\
                                get_variable(variable["name"])
                            if variable:
                                frame.variables.append(variable)
                        except:
                            Logger.debug(
                                "Coult not load variable {}".format(variable))

                return frame
            except:
                Logger.debug(traceback.format_exc())

        return None
Exemple #2
0
    def get_registers(self):
        """
        Returns the register values as a list of tuples with name and value of
        the given register.
        @rtype: list of register.Register
        """
        try:
            register_names = self.debugger.communicator.send(
                "-data-list-register-names")
            if not register_names:
                return []

            register_names = self.parser.parse(
                register_names.data)["register-names"]

            register_values = self.debugger.communicator.send(
                "-data-list-register-values --skip-unavailable x")
            if not register_values:
                return []

            registers = []
            register_values = self.parser.parse(
                register_values.data)["register-values"]
            for reg in register_values:
                number = int(reg["number"])
                if (number < len(register_names) and
                        len(register_names[number]) > 0):
                    registers.append(Register(str(register_names[number]),
                                              str(reg["value"])))
            return registers
        except:
            Logger.debug(traceback.format_exc())

        return []
    def get_current_frame(self, with_variables=False):
        """
        Returns the current stack frame, optionally with it's parameters.
        @type with_variables: bool
        @rtype: debugee.Frame | None
        """
        output = self.debugger.communicator.send("-stack-info-frame")

        if output:
            try:
                frame = self.parser.parse_stack_frame(output.data)

                if with_variables:
                    variables_info = self.parser.parse_frame_variables(
                        self.debugger.communicator.send(
                            "-stack-list-variables --skip-unavailable 0").data
                    )

                    for variable in variables_info:
                        try:
                            variable = self.debugger.variable_manager.\
                                get_variable(variable["name"])
                            if variable:
                                frame.variables.append(variable)
                        except:
                            Logger.debug("Coult not load variable {}"
                                         .format(variable))

                return frame
            except:
                Logger.debug(traceback.format_exc())

        return None
    def _set_debugger_location(self):
        location = self.debugger.file_manager.get_current_location()

        Logger.debug("Stop at {0}".format(location))

        if location and location[0]:
            run_on_gui(self.set_exec_line, location[0], location[1])
Exemple #5
0
    def _set_debugger_location(self):
        location = self.debugger.file_manager.get_current_location()

        Logger.debug("Stop at {0}".format(location))

        if location and location[0]:
            run_on_gui(self.set_exec_line, location[0], location[1])
Exemple #6
0
    def _emit_buffer(self):
        if not self.debugger.io_manager.stdin:
            return

        input_buffer = self._collect_buffer()

        try:
            self.debugger.io_manager.stdin.write(input_buffer)
        except:
            Logger.debug(traceback.format_exc())
Exemple #7
0
    def get_main_source_file(self):
        output = self.debugger.communicator.send("info sources")

        if output:
            try:
                files = output.cli_data[1]
                return files.split(",")[0]
            except:
                Logger.debug(traceback.format_exc())

        return None
Exemple #8
0
    def _get_current_file(self):
        output = self.debugger.communicator.send("info source")

        if output:
            try:
                cli_data = output.cli_data[2]
                return cli_data[11:]
            except:
                Logger.debug(traceback.format_exc())

        return None
    def get_frames(self):
        """
        @rtype: list of debugee.Frame
        """
        output = self.debugger.communicator.send("-stack-list-frames")

        if output:
            try:
                return self.parser.parse_stack_frames(output.data)
            except:
                Logger.debug(traceback.format_exc())

        return []
Exemple #10
0
 def handle_drag_end(self, target):
     """
     @type target: Drawable
     """
     if isinstance(target, VariableContainer):
         variable = target.variable
         if variable.type.name != self.variable.target_type.name:
             Logger.debug(
                 "Assigned {} pointer to variable of type {}".format(
                     self.variable.target_type.name, variable.type.name))
         if variable.address:
             self.variable.value = variable.address
             self.invalidate()
    def get_frames(self):
        """
        @rtype: list of debugee.Frame
        """
        output = self.debugger.communicator.send("-stack-list-frames")

        if output:
            try:
                return self.parser.parse_stack_frames(output.data)
            except:
                Logger.debug(traceback.format_exc())

        return []
Exemple #12
0
    def _get_current_line(self):
        output = self.debugger.communicator.send("info line")

        if output:
            try:
                cli_data = output.cli_data[0][5:]
                match = re.match("(\d+)", cli_data)

                return int(match.group(0))
            except:
                Logger.debug(traceback.format_exc())

        return None
Exemple #13
0
 def handle_drag_end(self, target):
     """
     @type target: Drawable
     """
     if isinstance(target, VariableContainer):
         variable = target.variable
         if variable.type.name != self.variable.target_type.name:
             Logger.debug(
                 "Assigned {} pointer to variable of type {}".format(
                     self.variable.target_type.name, variable.type.name))
         if variable.address:
             self.variable.value = variable.address
             self.invalidate()
    def get_thread_info(self):
        """
        Returns (active_thread_id, all_threads).
        @rtype: debugee.ThreadInfo | None
        """
        output = self.debugger.communicator.send("-thread-info")

        if output:
            try:
                return self.parser.parse_thread_info(output.data)
            except:
                Logger.debug(traceback.format_exc())

        return None
    def get_thread_info(self):
        """
        Returns (active_thread_id, all_threads).
        @rtype: debugee.ThreadInfo | None
        """
        output = self.debugger.communicator.send("-thread-info")

        if output:
            try:
                return self.parser.parse_thread_info(output.data)
            except:
                Logger.debug(traceback.format_exc())

        return None
Exemple #16
0
    def _parse_address(self, expression):
        """
        @type expression: str
        @rtype: str | None
        """
        try:
            address = self.parser.parse_print_expression(expression)

            if len(address) > 0 and address[0] == "(":
                return address[address.rfind(" ") + 1:]
            elif address[:2] == "0x":
                return address[:address.find(" ")]
        except:
            Logger.debug(traceback.format_exc())

        return None
Exemple #17
0
    def get_current_location(self):
        """
        Returns the current file and line of the debugged process.
        @rtype: tuple of basestring, int | None
        """
        frame = self.debugger.thread_manager.get_current_frame(False)

        if not frame:
            return None

        line = frame.line
        location = frame.file

        Logger.debug("Getting current location: ({0}, {1})".format(
            location, line))

        return (location, line)
    def _read_thread(self, alloc_path):
        """
        @type alloc_path: str
        """
        try:
            with os.fdopen(os.open(alloc_path, os.O_NONBLOCK | os.O_RDONLY),
                           "r", 1) as alloc_file:
                self.alloc_file = alloc_file

                while not self.stop_flag.is_set():
                    if len(select.select([alloc_file], [], [], 0.1)[0]) != 0:
                        line = alloc_file.readline()[:-1]

                        if line:
                            self._handle_message(line)
        except:
            Logger.debug(traceback.format_exc())
Exemple #19
0
    def disassemble(self, filename, line):
        """
        Returns disassembled code for the given location.
        Returns None if no code was found,
        @type filename: str
        @type line: int
        @rtype: str | None
        """
        command = "-data-disassemble -f {0} -l {1} -n 10 -- 1".format(
            filename, line)
        result = self.debugger.communicator.send(command)
        if result:
            try:
                disassembled = self.parser.parse_disassembly(result.data)
                if disassembled:
                    return disassembled
            except:
                Logger.debug(traceback.format_exc())

        return None
    def get_frames_with_variables(self):
        """
        Returns all stack frames with all their local variables and arguments.
        @rtype: list of debugger.debugee.Frame
        """
        current_frame = self.get_current_frame(False)

        if not current_frame:
            return []

        frames = []
        try:
            for i, fr in enumerate(self.get_frames()):
                self.change_frame(i, False)
                frames.append(self.get_current_frame(True))
        except:
            Logger.debug(traceback.format_exc())
        finally:
            self.change_frame(current_frame.level, False)

        return frames
    def _handle_message(self, message):
        """
        @type message: str
        """
        util.Logger.debug("HEAP: {}".format(message))

        msg_parts = message.split(" ")
        action = msg_parts[0]
        args = msg_parts[1:]

        try:
            if action in ("malloc", "calloc"):
                self._handle_malloc(*args)
            elif action == "realloc":
                self._handle_realloc(*args)
            elif action == "free":
                self._handle_free(*args)
            else:
                Logger.debug("Unknown allocation action: {}".format(action))
        except:
            Logger.debug(traceback.format_exc())
    def get_frames_with_variables(self):
        """
        Returns all stack frames with all their local variables and arguments.
        @rtype: list of debugger.debugee.Frame
        """
        current_frame = self.get_current_frame(False)

        if not current_frame:
            return []

        frames = []
        try:
            for i, fr in enumerate(self.get_frames()):
                self.change_frame(i, False)
                frames.append(self.get_current_frame(True))
        except:
            Logger.debug(traceback.format_exc())
        finally:
            self.change_frame(current_frame.level, False)

        return frames
Exemple #23
0
    def get_memory(self, address, count):
        """
        Returns count bytes from the given address.
        @type address: str
        @type count: int
        @rtype: list of int
        """
        command = "x/{0}xb {1}".format(count, address)
        output = self.debugger.communicator.send(command)

        bytes = []
        try:
            for line in output.cli_data:
                start = line.find(":")
                line = line[start + 1:]
                for num in line.split("\\t"):
                    if num:
                        bytes.append(int(num, 16))
        except:
            Logger.debug(traceback.format_exc())

        return bytes
Exemple #24
0
    def update_variable(self, variable):
        """
        Updates the variable's value in the debugged process.
        @type variable: debugee.Variable
        """
        format = "set variable *{0} = {1}"

        value = variable.value

        try:
            if variable.type.type_category == TypeCategory.String:
                format = "call static_cast<std::string*>({0})->assign(\"{1}\")"
            elif BasicTypeCategory.is_char(variable.type.basic_type_category):
                char_value = variable.value
                if len(char_value) == 1 and not char_value[0].isdigit():
                    value = "'{}'".format(char_value)
        except:
            Logger.debug(traceback.format_exc())
            return False

        result = self.debugger.communicator.send(format.format(
            variable.address, value))

        return result.is_success()
Exemple #25
0
    def disassemble_raw(self, filename, line):
        """
        Disassembles the given line in a raw form (returns a string with the
        line and all assembly instructions for it).
        @type filename: str
        @type line: int
        @rtype: str | None
        """
        address = self.get_line_address(filename, line)

        if not address:
            return None

        command = "disas /m {0}, {1}".format(address[0], address[1])
        result = self.debugger.communicator.send(command)
        if result:
            try:
                return "\n".join([
                    row.replace("\\t", "\t") for row in result.cli_data[1:-1]
                ])
            except:
                Logger.debug(traceback.format_exc())

        return None
Exemple #26
0
    def get_variable(self, expression, level=0):
        """
        Returns a variable for the given expression-
        @type expression: str
        @type level: int
        @rtype: debugee.Variable
        """
        if level > VariableManager.RECURSION_LIMIT:
            return None

        type = self.get_type(expression)
        output = self.debugger.communicator.send("p {0}".format(expression))

        if output and type:
            try:
                data = self.parser.parse_print_expression(output.cli_data)
            except:
                Logger.debug(traceback.format_exc())
                return None

            address = None
            address_output = self.debugger.communicator.send(
                "p &{0}".format(expression))

            try:
                if address_output:
                    address = self._parse_address(address_output.cli_data)
            except:
                Logger.debug(traceback.format_exc())

            name = self._get_name(expression)
            value = None
            variable = None
            children = []

            try:
                if type.type_category == TypeCategory.Builtin:
                    value = data
                    variable = Variable(address, name, value, type, expression)

                elif type.type_category == TypeCategory.Pointer:
                        value = data[data.rfind(" ") + 1:].lower()
                        target_type = self.get_type("*{0}".format(expression))

                        if (target_type and BasicTypeCategory.is_char(
                                target_type.basic_type_category)):
                            type.type_category = TypeCategory.CString
                            value = value[1:-1]  # strip quotes
                        variable = PointerVariable(target_type, address, name,
                                                   value, type, expression)

                elif type.type_category == TypeCategory.Reference:
                    value = data[data.find("@") + 1:data.find(":")]
                    address = self.debugger.communicator.send(
                        "p &(&{0})".format(expression))
                    if address:
                        address = self._parse_address(address.cli_data)
                    else:
                        address = "0x0"

                    target_type = self.get_type("*{0}".format(expression))
                    variable = PointerVariable(target_type, address, name,
                                               value, type, expression)

                elif type.type_category == TypeCategory.Function:
                    # skip function pointer type
                    if data.startswith("({}) ".format(type.name)):
                        data = data[(3 + len(type.name)):]

                    variable = Variable(address, name, data, type, expression)

                elif type.type_category == TypeCategory.String:
                    value = data.strip("\"")
                    variable = Variable(address, name, value, type, expression)

                elif type.type_category in (TypeCategory.Class,
                                            TypeCategory.Struct,
                                            TypeCategory.Union):
                    result = self.debugger.communicator.send(
                        "python print([field.name for field in "
                        "gdb.lookup_type(\"{0}\").fields()])".format(type.name)
                    )

                    if result:
                        members = self.parser.parse_struct_member_names(
                            result.cli_data[0])
                        for member in members:
                            child = self.get_variable("({0}).{1}".format(
                                expression, member), level + 1)
                            if child:
                                children.append(child)
                    variable = Variable(address, name, value, type, expression)

                elif type.type_category == TypeCategory.Vector:
                    length = self.get_variable(
                        "({0}._M_impl._M_finish - {0}._M_impl._M_start)"
                        .format(expression), level + 1)

                    if length:
                        length = int(length.value)

                    data_address = self.debugger.communicator.send(
                        "p {}._M_impl._M_start".format(expression))
                    data_address = " ".join(data_address.cli_data).rstrip()
                    data_address = data_address[data_address.rfind(" ") + 1:]
                    variable = VectorVariable(length, data_address, address,
                                              name, value, type, expression)
                elif type.type_category == TypeCategory.Array:
                    length = type.count
                    data_address = self.get_variable(
                        "&({}[0])".format(expression), level + 1)

                    if data_address:
                        data_address = data_address.value
                    else:
                        data_address = ""

                    variable = VectorVariable(length, data_address, address,
                                              name, value, type, expression)

                elif type.type_category == TypeCategory.Enumeration:
                    variable = Variable(address, name, data, type, expression)
                else:
                    return None

            except:
                Logger.debug(traceback.format_exc())
                return None

            if variable:
                variable.on_value_changed.subscribe(self.update_variable)

                for child in children:
                    if child:
                        variable.add_child(child)

            return variable

        else:
            return None
Exemple #27
0
    def get_type(self, expression, level=0):
        """
        Returns type for the given expression.
        @type expression: str
        @type level: int
        @rtype: debugee.Type
        """
        if level > VariableManager.RECURSION_LIMIT:
            return None

        output = self.debugger.communicator.send("ptype {0}".
                                                 format(expression))
        short_output = self.debugger.communicator.send("whatis {0}".
                                                       format(expression))

        if output and short_output:
            try:
                type = self.parser.parse_variable_type(output.cli_data[0])
                type_name = self.parser.parse_variable_type(
                    short_output.cli_data[0])
            except:
                Logger.debug(traceback.format_exc())
                return None

            basic_type_category = BasicTypeCategory.Invalid
            type_category = TypeCategory.Class

            modificators = []

            try:
                while type.startswith("volatile") or type.startswith("const"):
                    modificator = type[:type.find(" ")]
                    type = type[len(modificator) + 1:]
                    modificators.append(modificator)

                    if type_name.startswith(modificator):
                        type_name = type_name[len(modificator) + 1:]
            except:
                Logger.debug(traceback.format_exc())
                return None

            if type in basic_type_map:
                basic_type_category = basic_type_map[type]
                type_category = TypeCategory.Builtin
            else:
                if type_name.startswith("std::vector"):
                    type_category = TypeCategory.Vector
                elif type_name.startswith("std::string"):
                    type_category = TypeCategory.String
                elif type_name.endswith("*"):
                    type_category = TypeCategory.Pointer
                elif type_name.endswith("&"):
                    type_category = TypeCategory.Reference
                elif type_name.endswith("]"):
                    type_category = TypeCategory.Array
                elif type_name.endswith(")"):
                    type_category = TypeCategory.Function
                elif type.startswith("struct"):
                    type_category = TypeCategory.Struct
                elif type.startswith("class"):
                    type_category = TypeCategory.Class
                elif type.startswith("union"):
                    type_category = TypeCategory.Union
                elif type.startswith("enum"):
                    type_category = TypeCategory.Enumeration

            size = None
            size_output = self.debugger.communicator.send("p sizeof({0})".
                                                          format(type_name))
            if size_output:
                try:
                    size = int(self.parser.parse_print_expression(
                        size_output.cli_data[0]))
                except:
                    Logger.debug(traceback.format_exc())
                    return None

            args = [type_name, type_category, basic_type_category, size,
                    tuple(modificators)]

            try:
                if type_category == TypeCategory.Array:
                    right_bracket_end = type_name.rfind("]")
                    right_bracket_start = type_name.rfind("[")
                    count = int(type_name[
                                right_bracket_start + 1:right_bracket_end])
                    child_type = self.get_type("{}[0]".format(expression),
                                               level + 1)
                    type = ArrayType(count, child_type, *args)
                elif type_category == TypeCategory.Vector:
                    child_type = self.debugger.communicator.send(
                        "python print(gdb.lookup_type(\"{}\")"
                        ".template_argument(0))".format(type_name))
                    child_type = self.get_type(" ".join(child_type.cli_data),
                                               level + 1)
                    type = ArrayType(0, child_type, *args)
                else:
                    type = Type(*args)
            except:
                Logger.debug(traceback.format_exc())
                return None

            return type
        else:
            return None