Пример #1
1
def main():
    filename = sys.argv[1]
    fptr = open(filename, "r")
    source = fptr.read()
    fptr.seek(0)
    source_lines = format_source_lines(fptr.readlines())
    fptr.close()

    draw_header("Source")
    display_source(source_lines)
    code = compile(source, filename, "exec")

    vm = BytecodeVM(code, source_lines, filename)

    WITH_DEBUGGER = False

    if not WITH_DEBUGGER:
        draw_header("Disassembly")
        dis.dis(code)
        #  Configure the VM and set the settings based on command line. For now use defaults
        config = configure_vm()
        config.show_disassembly = True
        vm.config = config
        vm.execute()
    else:
        debugger = Debugger(code, source_lines, filename)
        debugger.execute(False)
Пример #2
0
 def initialize_vm(self, code, source, filename):
     self.__vm = BytecodeVM(code, source, filename)
     config = VMConfig()
     self.__vm.config = config
     config.show_disassembly = True
     self.__vm.execute = self.execute
Пример #3
0
class Debugger:
    def __init__(self, code, source, filename):
        self.__breakpoints = {}
        self.__prompt = ">>> "
        self.__debugger_broken = False

        self.__code = code
        self.__source = source
        self.__filename = filename

        self.initialize_vm(code, source, filename)
        draw_header("Initializing Debugger...")

        self.__breakpoint_hit = None
        self.__vm_running = False

    def initialize_vm(self, code, source, filename):
        self.__vm = BytecodeVM(code, source, filename)
        config = VMConfig()
        self.__vm.config = config
        config.show_disassembly = True
        self.__vm.execute = self.execute

    def set_breakpoint(self, line_no):
        self.__breakpoints[line_no] = True

    def disable_breakpoint(self, line_no):
        if line_no not in self.__breakpoints.keys():
            return

        self.__breakpoints[line_no] = False

    def clear_breakpoint(self, line_no):
        if line_no not in self.__breakpoints.keys():
            return

        del self.__breakpoints[line_no]

    def clear_all_breakpoints(self):
        self.__breakpoints = {}

    def view_locals(self, local_var=None):
        draw_header("Locals")
        current_exec_frame = self.__vm.exec_frame

        while current_exec_frame is not None:
            locals = current_exec_frame.locals
            for k, v in locals.items():
                if local_var is None or local_var == k:
                    print("%s: %s" % (k, v))

            current_exec_frame = current_exec_frame.parent_exec_frame

    def view_globals(self, global_var=None):
        globals = self.__vm.exec_frame.globals

        draw_header("Globals")
        for k, v in globals.items():
            if global_var is None or global_var == k:
                print("%s: %s" % (k, v))

    def set_local(self, local_var, val_to_set):
        val, exec_frame = self.__vm.exec_frame.get_local_var_value(local_var)
        t = type(val)
        try:
            exec_frame.set_local_var_value(local_var, t(val_to_set))
        except:
            exec_frame.set_local_var_value(local_var, val_to_set)

        draw_header("Locals Changed")
        val, exec_frame = self.__vm.exec_frame.get_local_var_value(local_var)
        print("%s: %s" % (local_var, val))

    def view_backtrace(self):
        stack_trace = [frame for frame in self.__vm.exec_frame_stack]
        stack_trace.append(self.__vm.exec_frame)

        stack_trace.reverse()

        draw_header("Stacktrace")
        backtrace = ""
        for i, frame in enumerate(stack_trace):
            backtrace += "\t<Frame %s - %s>" % (i, frame) + "\n"

        print(backtrace)

    def view_breakpoints(self):
        draw_header("Breakpoints Set")
        for bp, status in self.__breakpoints.items():
            breakpoint_hit = self.__vm.exec_frame.line_no_obj.get_source_line(bp)
            breakpoint_hit = breakpoint_hit.strip()
            if status == True:
                status = "Enabled"
            else:
                status = "Disabled"
            print("Breakpoint Line %s: %s ---> %s" % (bp, status, breakpoint_hit))

    def view_source(self, lineno):
        if lineno > 0:
            lines = self.__vm.exec_frame.line_no_obj.get_source_sorrounding_line(lineno)
        else:
            lines = self.__vm.exec_frame.line_no_obj.get_all_source_lines()

        print(lines)

    def display_help(self):
        print("\tnext - Execute Next Instruction")
        print("\trun - Run VM")
        print("\tset bp <loc> - Set Breakpoint at loc")
        print("\tdisable bp <loc> - Disable Breakpoint at loc")
        print("\tclear bp <loc> - Disable Breakpoint at loc")
        print("\tclear all bps - Clear all Breakpoints")
        print("\tview source <loc> - View Source. If no loc is specified entire source is shown")
        print("\tview locals - View the Local variables")
        print("\tview globals - View the Global variables")
        print("\tview local <var> - View local var")
        print("\tview global <var> - View global var")
        print("\tview backtrace - View the BackTrace")
        print("\tview bp - View Breakpoints")
        print("\thelp - Display this help")
        print("\tquit - Quit")

    def parse_command(self, cmd):
        if cmd == "next":
            return DebuggerCmds.VM_NEXT_INST
        elif cmd == "run":
            return DebuggerCmds.VM_RUN
        elif "set bp" in cmd:
            parts = cmd.split(" ")
            bp_location = int(parts[2])
            cmd = DebuggerCmds.VM_SET_BP
            return (cmd, bp_location)
        elif "disable bp" in cmd:
            parts = cmd.split(" ")
            bp_location = int(parts[2])
            cmd = DebuggerCmds.VM_DISABLE_BP
            return (cmd, bp_location)
        elif "clear bp" in cmd:
            parts = cmd.split(" ")
            bp_location = int(parts[2])
            cmd = DebuggerCmds.VM_CLEAR_BP
            return (cmd, bp_location)
        elif cmd == "clear all bps":
            cmd = DebuggerCmds.VM_CLEAR_ALL_BP
            return cmd
        elif "view source" in cmd:
            parts = cmd.split()
            cmd = DebuggerCmds.VM_VIEW_SOURCE
            if len(parts) == 3:
                lineno = int(parts[2])
            else:
                lineno = 0
            return (cmd, lineno)
        elif cmd == "view locals":
            cmd = DebuggerCmds.VM_VIEW_LOCALS
            return cmd
        elif cmd == "view globals":
            cmd = DebuggerCmds.VM_VIEW_GLOBALS
            return cmd
        elif "view local" in cmd:
            parts = cmd.split(" ")
            var = parts[2]
            cmd = DebuggerCmds.VM_VIEW_LOCAL
            return (cmd, var)
        elif "view global" in cmd:
            parts = cmd.split(" ")
            var = parts[2]
            cmd = DebuggerCmds.VM_VIEW_GLOBAL
            return (cmd, var)
        elif "set local" in cmd:
            parts = cmd.split(" ")
            var = parts[2]
            val = parts[3]
            cmd = DebuggerCmds.VM_SET_LOCAL
            return (cmd, var, val)
        elif cmd == "view backtrace":
            cmd = DebuggerCmds.VM_VIEW_BACKTRACE
            return cmd
        elif cmd == "view bp":
            cmd = DebuggerCmds.VM_VIEW_BREAKPOINTS
            return cmd
        elif cmd == "help":
            cmd = DebuggerCmds.HELP
            return cmd
        elif cmd == "quit":
            cmd = DebuggerCmds.QUIT
            return cmd

    def display_prompt(self):
        cmd_str = input(self.__prompt)
        cmd_res = self.parse_command(cmd_str)
        return cmd_res

    def run_vm(self):
        # Run until any breakpoint is hit
        self.__vm_running = True
        while True:
            opmethod, oparg, current_lineno = self.__vm.get_opcode()

            # Check if any breakpoint got hit
            if current_lineno in self.__breakpoints.keys():
                if self.__breakpoints[current_lineno] is True:
                    breakpoint_hit = self.__vm.exec_frame.line_no_obj.get_source_line(current_lineno)
                    draw_header("Breakpoint Hit: %s" % breakpoint_hit)
                    lines = self.__vm.exec_frame.line_no_obj.get_source_sorrounding_line(current_lineno)
                    print(lines)
                    self.__breakpoint_hit = current_lineno
                    return

            terminate = self.__vm.execute_opcode(opmethod, oparg)
            if terminate:
                break

        # Reinitialize for next execution
        self.initialize_vm(self.__code, self.__source, self.__filename)
        print("App exited...")
        self.__vm_running = False
        return

    def next_inst(self):
        if self.__vm_running is False:
            print("App is not running. Run it with 'run'")
            return

        current_lineno = self.__vm.exec_frame.line_no_obj.line_number(self.__vm.exec_frame.ip)
        lineno = current_lineno

        while lineno == current_lineno:
            opmethod, oparg, lineno = self.__vm.get_opcode()
            terminate = self.__vm.execute_opcode(opmethod, oparg)

            if terminate:
                # Reinitialize for next execution
                self.initialize_vm(self.__code, self.__source, self.__filename)
                print("App exited...")
                self.__vm_running = False
                return

        lines = self.__vm.exec_frame.line_no_obj.get_source_sorrounding_line(lineno)
        print(lines)


    def view_asm(self):
        if self.__breakpoint_hit is None:
            # Display the entire source frame for this
            self.__vm.exec_frame.line_no_obj.get_all_source_lines()
        else:
            self.__vm.exec_frame.line_no_obj.get_source_sorrounding_line(self.__breakpoint_hit)

    def execute(self, call_from_vm = True):
        while True:
            arg1 = None

            if not call_from_vm:
                cmd_res = self.display_prompt()
                if isinstance(cmd_res, tuple):
                    cmd = cmd_res[0]
                    arg1 = cmd_res[1]
                else:
                    cmd = cmd_res
            else:
                cmd = DebuggerCmds.VM_RUN

            if cmd is DebuggerCmds.VM_RUN:
                self.run_vm()
            elif cmd is DebuggerCmds.VM_NEXT_INST:
                self.next_inst()
            elif cmd is DebuggerCmds.VM_SET_BP:
                self.set_breakpoint(arg1)
            elif cmd is DebuggerCmds.VM_DISABLE_BP:
                self.disable_breakpoint(arg1)
            elif cmd is DebuggerCmds.VM_CLEAR_BP:
                self.clear_breakpoint(arg1)
            elif cmd is DebuggerCmds.VM_CLEAR_ALL_BP:
                self.clear_all_breakpoints()
            elif cmd is DebuggerCmds.VM_VIEW_LOCALS:
                self.view_locals()
            elif cmd is DebuggerCmds.VM_VIEW_LOCAL:
                self.view_locals(arg1)
            elif cmd is DebuggerCmds.VM_SET_LOCAL:
                val = cmd_res[2]
                self.set_local(arg1, val)
            elif cmd is DebuggerCmds.VM_VIEW_GLOBALS:
                self.view_globals()
            elif cmd is DebuggerCmds.VM_VIEW_GLOBAL:
                self.view_globals(arg1)
            elif cmd is DebuggerCmds.VM_VIEW_BACKTRACE:
                self.view_backtrace()
            elif cmd is DebuggerCmds.VM_VIEW_BREAKPOINTS:
                self.view_breakpoints()
            elif cmd is DebuggerCmds.VM_VIEW_SOURCE:
                self.view_source(arg1)
            elif cmd is DebuggerCmds.HELP:
                self.display_help()
            elif cmd is DebuggerCmds.QUIT:
                sys.exit(0)

            call_from_vm = False
Пример #4
0
 def initialize_vm(self, code, source, filename):
     self.__vm = BytecodeVM(code, source, filename)
     config = VMConfig()
     self.__vm.config = config
     config.show_disassembly = True
     self.__vm.execute = self.execute
Пример #5
0
class Debugger:
    def __init__(self, code, source, filename):
        self.__breakpoints = {}
        self.__prompt = ">>> "
        self.__debugger_broken = False

        self.__code = code
        self.__source = source
        self.__filename = filename

        self.initialize_vm(code, source, filename)
        draw_header("Initializing Debugger...")

        self.__breakpoint_hit = None
        self.__vm_running = False

    def initialize_vm(self, code, source, filename):
        self.__vm = BytecodeVM(code, source, filename)
        config = VMConfig()
        self.__vm.config = config
        config.show_disassembly = True
        self.__vm.execute = self.execute

    def set_breakpoint(self, line_no):
        self.__breakpoints[line_no] = True

    def disable_breakpoint(self, line_no):
        if line_no not in self.__breakpoints.keys():
            return

        self.__breakpoints[line_no] = False

    def clear_breakpoint(self, line_no):
        if line_no not in self.__breakpoints.keys():
            return

        del self.__breakpoints[line_no]

    def clear_all_breakpoints(self):
        self.__breakpoints = {}

    def view_locals(self, local_var=None):
        draw_header("Locals")
        current_exec_frame = self.__vm.exec_frame

        while current_exec_frame is not None:
            locals = current_exec_frame.locals
            for k, v in locals.items():
                if local_var is None or local_var == k:
                    print("%s: %s" % (k, v))

            current_exec_frame = current_exec_frame.parent_exec_frame

    def view_globals(self, global_var=None):
        globals = self.__vm.exec_frame.globals

        draw_header("Globals")
        for k, v in globals.items():
            if global_var is None or global_var == k:
                print("%s: %s" % (k, v))

    def set_local(self, local_var, val_to_set):
        val, exec_frame = self.__vm.exec_frame.get_local_var_value(local_var)
        t = type(val)
        try:
            exec_frame.set_local_var_value(local_var, t(val_to_set))
        except:
            exec_frame.set_local_var_value(local_var, val_to_set)

        draw_header("Locals Changed")
        val, exec_frame = self.__vm.exec_frame.get_local_var_value(local_var)
        print("%s: %s" % (local_var, val))

    def view_backtrace(self):
        stack_trace = [frame for frame in self.__vm.exec_frame_stack]
        stack_trace.append(self.__vm.exec_frame)

        stack_trace.reverse()

        draw_header("Stacktrace")
        backtrace = ""
        for i, frame in enumerate(stack_trace):
            backtrace += "\t<Frame %s - %s>" % (i, frame) + "\n"

        print(backtrace)

    def view_breakpoints(self):
        draw_header("Breakpoints Set")
        for bp, status in self.__breakpoints.items():
            breakpoint_hit = self.__vm.exec_frame.line_no_obj.get_source_line(
                bp)
            breakpoint_hit = breakpoint_hit.strip()
            if status == True:
                status = "Enabled"
            else:
                status = "Disabled"
            print("Breakpoint Line %s: %s ---> %s" %
                  (bp, status, breakpoint_hit))

    def view_source(self, lineno):
        if lineno > 0:
            lines = self.__vm.exec_frame.line_no_obj.get_source_sorrounding_line(
                lineno)
        else:
            lines = self.__vm.exec_frame.line_no_obj.get_all_source_lines()

        print(lines)

    def display_help(self):
        print("\tnext - Execute Next Instruction")
        print("\trun - Run VM")
        print("\tset bp <loc> - Set Breakpoint at loc")
        print("\tdisable bp <loc> - Disable Breakpoint at loc")
        print("\tclear bp <loc> - Disable Breakpoint at loc")
        print("\tclear all bps - Clear all Breakpoints")
        print(
            "\tview source <loc> - View Source. If no loc is specified entire source is shown"
        )
        print("\tview locals - View the Local variables")
        print("\tview globals - View the Global variables")
        print("\tview local <var> - View local var")
        print("\tview global <var> - View global var")
        print("\tview backtrace - View the BackTrace")
        print("\tview bp - View Breakpoints")
        print("\thelp - Display this help")
        print("\tquit - Quit")

    def parse_command(self, cmd):
        if cmd == "next":
            return DebuggerCmds.VM_NEXT_INST
        elif cmd == "run":
            return DebuggerCmds.VM_RUN
        elif "set bp" in cmd:
            parts = cmd.split(" ")
            bp_location = int(parts[2])
            cmd = DebuggerCmds.VM_SET_BP
            return (cmd, bp_location)
        elif "disable bp" in cmd:
            parts = cmd.split(" ")
            bp_location = int(parts[2])
            cmd = DebuggerCmds.VM_DISABLE_BP
            return (cmd, bp_location)
        elif "clear bp" in cmd:
            parts = cmd.split(" ")
            bp_location = int(parts[2])
            cmd = DebuggerCmds.VM_CLEAR_BP
            return (cmd, bp_location)
        elif cmd == "clear all bps":
            cmd = DebuggerCmds.VM_CLEAR_ALL_BP
            return cmd
        elif "view source" in cmd:
            parts = cmd.split()
            cmd = DebuggerCmds.VM_VIEW_SOURCE
            if len(parts) == 3:
                lineno = int(parts[2])
            else:
                lineno = 0
            return (cmd, lineno)
        elif cmd == "view locals":
            cmd = DebuggerCmds.VM_VIEW_LOCALS
            return cmd
        elif cmd == "view globals":
            cmd = DebuggerCmds.VM_VIEW_GLOBALS
            return cmd
        elif "view local" in cmd:
            parts = cmd.split(" ")
            var = parts[2]
            cmd = DebuggerCmds.VM_VIEW_LOCAL
            return (cmd, var)
        elif "view global" in cmd:
            parts = cmd.split(" ")
            var = parts[2]
            cmd = DebuggerCmds.VM_VIEW_GLOBAL
            return (cmd, var)
        elif "set local" in cmd:
            parts = cmd.split(" ")
            var = parts[2]
            val = parts[3]
            cmd = DebuggerCmds.VM_SET_LOCAL
            return (cmd, var, val)
        elif cmd == "view backtrace":
            cmd = DebuggerCmds.VM_VIEW_BACKTRACE
            return cmd
        elif cmd == "view bp":
            cmd = DebuggerCmds.VM_VIEW_BREAKPOINTS
            return cmd
        elif cmd == "help":
            cmd = DebuggerCmds.HELP
            return cmd
        elif cmd == "quit":
            cmd = DebuggerCmds.QUIT
            return cmd

    def display_prompt(self):
        cmd_str = input(self.__prompt)
        cmd_res = self.parse_command(cmd_str)
        return cmd_res

    def run_vm(self):
        # Run until any breakpoint is hit
        self.__vm_running = True
        while True:
            opmethod, oparg, current_lineno = self.__vm.get_opcode()

            # Check if any breakpoint got hit
            if current_lineno in self.__breakpoints.keys():
                if self.__breakpoints[current_lineno] is True:
                    breakpoint_hit = self.__vm.exec_frame.line_no_obj.get_source_line(
                        current_lineno)
                    draw_header("Breakpoint Hit: %s" % breakpoint_hit)
                    lines = self.__vm.exec_frame.line_no_obj.get_source_sorrounding_line(
                        current_lineno)
                    print(lines)
                    self.__breakpoint_hit = current_lineno
                    return

            terminate = self.__vm.execute_opcode(opmethod, oparg)
            if terminate:
                break

        # Reinitialize for next execution
        self.initialize_vm(self.__code, self.__source, self.__filename)
        print("App exited...")
        self.__vm_running = False
        return

    def next_inst(self):
        if self.__vm_running is False:
            print("App is not running. Run it with 'run'")
            return

        current_lineno = self.__vm.exec_frame.line_no_obj.line_number(
            self.__vm.exec_frame.ip)
        lineno = current_lineno

        while lineno == current_lineno:
            opmethod, oparg, lineno = self.__vm.get_opcode()
            terminate = self.__vm.execute_opcode(opmethod, oparg)

            if terminate:
                # Reinitialize for next execution
                self.initialize_vm(self.__code, self.__source, self.__filename)
                print("App exited...")
                self.__vm_running = False
                return

        lines = self.__vm.exec_frame.line_no_obj.get_source_sorrounding_line(
            lineno)
        print(lines)

    def view_asm(self):
        if self.__breakpoint_hit is None:
            # Display the entire source frame for this
            self.__vm.exec_frame.line_no_obj.get_all_source_lines()
        else:
            self.__vm.exec_frame.line_no_obj.get_source_sorrounding_line(
                self.__breakpoint_hit)

    def execute(self, call_from_vm=True):
        while True:
            arg1 = None

            if not call_from_vm:
                cmd_res = self.display_prompt()
                if isinstance(cmd_res, tuple):
                    cmd = cmd_res[0]
                    arg1 = cmd_res[1]
                else:
                    cmd = cmd_res
            else:
                cmd = DebuggerCmds.VM_RUN

            if cmd is DebuggerCmds.VM_RUN:
                self.run_vm()
            elif cmd is DebuggerCmds.VM_NEXT_INST:
                self.next_inst()
            elif cmd is DebuggerCmds.VM_SET_BP:
                self.set_breakpoint(arg1)
            elif cmd is DebuggerCmds.VM_DISABLE_BP:
                self.disable_breakpoint(arg1)
            elif cmd is DebuggerCmds.VM_CLEAR_BP:
                self.clear_breakpoint(arg1)
            elif cmd is DebuggerCmds.VM_CLEAR_ALL_BP:
                self.clear_all_breakpoints()
            elif cmd is DebuggerCmds.VM_VIEW_LOCALS:
                self.view_locals()
            elif cmd is DebuggerCmds.VM_VIEW_LOCAL:
                self.view_locals(arg1)
            elif cmd is DebuggerCmds.VM_SET_LOCAL:
                val = cmd_res[2]
                self.set_local(arg1, val)
            elif cmd is DebuggerCmds.VM_VIEW_GLOBALS:
                self.view_globals()
            elif cmd is DebuggerCmds.VM_VIEW_GLOBAL:
                self.view_globals(arg1)
            elif cmd is DebuggerCmds.VM_VIEW_BACKTRACE:
                self.view_backtrace()
            elif cmd is DebuggerCmds.VM_VIEW_BREAKPOINTS:
                self.view_breakpoints()
            elif cmd is DebuggerCmds.VM_VIEW_SOURCE:
                self.view_source(arg1)
            elif cmd is DebuggerCmds.HELP:
                self.display_help()
            elif cmd is DebuggerCmds.QUIT:
                sys.exit(0)

            call_from_vm = False