Ejemplo n.º 1
0
    def cleanup(cls, w=None):
        global _is_debugging
        _is_debugging = False

        set_disabled_bps([])
        ui_updater().stop()
        driver = driver_instance()
        if driver:
            driver.stop()
            set_driver_instance(None)
        lldb_view_send('\nDebugging session ended.\n')
Ejemplo n.º 2
0
    def cleanup(cls, w=None):
        global _is_debugging
        _is_debugging = False

        set_disabled_bps([])
        ui_updater().stop()
        driver = driver_instance()
        if driver:
            driver.stop()
            set_driver_instance(None)
        lldb_view_send('\nDebugging session ended.\n')
Ejemplo n.º 3
0
    def __init__(self, window, log_callback=None, process_stopped_callback=None, on_exit_callback=None):
        super(LldbDriver, self).__init__(name='sublime.lldb.driver')
        self.__window = window
        lldb.SBDebugger.Initialize()
        self.__broadcaster = lldb.SBBroadcaster('Driver')
        self.__process_stopped_callback = process_stopped_callback
        self.__on_exit_callback = on_exit_callback

        # if log_callback:
            # self._debugger = lldb.SBDebugger.Create(False, log_callback)
        # else:
        self._debugger = lldb.SBDebugger.Create(False)
        self.__listener = self._debugger.GetListener()
        set_driver_instance(self)
        r, w = os.pipe()
        self.__io_channel_r_fh = os.fdopen(r, 'r', 0)
        self.__io_channel_w_fh = os.fdopen(w, 'w', 0)
        self.__io_channel = IOChannel(self, self.__io_channel_r_fh, lldb_view_send)
        # self._debugger.SetCloseInputOnEOF(False)
        self.__input_reader = lldb.SBInputReader()
Ejemplo n.º 4
0
    def run(self):
        thread_created('<' + self.name + '>')

        sb_interpreter = self._debugger.GetCommandInterpreter()
        #listener = self._debugger.GetListener()
        listener = self.__listener
        listener.StartListeningForEventClass(self._debugger,
                     lldb.SBTarget.GetBroadcasterClassName(),
                     lldb.SBTarget.eBroadcastBitBreakpointChanged)
        # This isn't in Driver.cpp. Check why it listens to those events (because it uses SBDebugger's listener?)
        # listener.StartListeningForEventClass(self._debugger,
        #              lldb.SBProcess.GetBroadcasterClassName(),
        #              lldb.SBProcess.eBroadcastBitStateChanged |     \
        #              lldb.SBProcess.eBroadcastBitInterrupt |        \
        #              lldb.SBProcess.eBroadcastBitSTDOUT |           \
        #              lldb.SBProcess.eBroadcastBitSTDERR)

        # Warn whoever started us that we can start working
        self.broadcaster.BroadcastEventByType(LldbDriver.eBroadcastBitThreadDidStart)

        # Create pipes for communicating with the debugger
        in_pipe_fd, out_pipe_fd = os.pipe()
        self.__from_debugger_fh_r = os.fdopen(in_pipe_fd, 'r', 0)
        self.__from_debugger_fh_w = os.fdopen(out_pipe_fd, 'w', 0)
        in_pipe_fd, out_pipe_fd = os.pipe()
        self.__to_debugger_fh_r = os.fdopen(in_pipe_fd, 'r', 0)
        self.__to_debugger_fh_w = os.fdopen(out_pipe_fd, 'w', 0)

        self.__file_monitor = FileMonitor(self.__master_thread_bytes_received, self.__from_debugger_fh_r)
        self.debugger.SetOutputFileHandle(self.__from_debugger_fh_w, False)
        self.debugger.SetErrorFileHandle(self.__from_debugger_fh_w, False)
        self.debugger.SetInputFileHandle(self.__to_debugger_fh_r, False)

        # m_debugger.SetUseExternalEditor(m_option_data.m_use_external_editor);

        error = lldb.SBError(self.__input_reader.Initialize(self.debugger,
                                                            self.__input_reader_callback,
                                                            lldb.eInputReaderGranularityLine,
                                                            None,  # end token (NULL == never done)
                                                            None,  # Prompt (NULL == taken care of elsewhere)
                                                            False))  # echo input (we'll take care of this elsewhere)

        if error.Fail():
            # Fail now... We can't have any input reader
            sublime.error_message('error: ' + error.GetCString())
            return

        self.debugger.PushInputReader(self.__input_reader)

        if listener.IsValid():
            iochannel_thread_exited = False
            listener.StartListeningForEvents(self.io_channel.broadcaster,
                        IOChannel.eBroadcastBitHasUserInput |      \
                        IOChannel.eBroadcastBitUserInterrupt |     \
                        IOChannel.eBroadcastBitThreadShouldExit |  \
                        IOChannel.eBroadcastBitThreadDidStart |    \
                        IOChannel.eBroadcastBitThreadDidExit)

            self.io_channel.start()
            if self.io_channel.is_alive():
                listener.StartListeningForEvents(sb_interpreter.GetBroadcaster(),
                            lldb.SBCommandInterpreter.eBroadcastBitQuitCommandReceived |    \
                            lldb.SBCommandInterpreter.eBroadcastBitAsynchronousOutputData | \
                            lldb.SBCommandInterpreter.eBroadcastBitAsynchronousErrorData)

                result = lldb.SBCommandReturnObject()
                sb_interpreter.SourceInitFileInHomeDirectory(result)
                # TODO Remove this debugging feature and have a way to report
                # errors in init files.
                if True:
                    result.PutError(self.debugger.GetErrorFileHandle())
                    result.PutOutput(self.debugger.GetOutputFileHandle())

                sb_interpreter.SourceInitFileInCurrentWorkingDirectory(result)
                # TODO Remove this debugging feature and have a way to report
                # errors in init files.
                if True:
                    result.PutError(self.debugger.GetErrorFileHandle())
                    result.PutOutput(self.debugger.GetOutputFileHandle())

                event = lldb.SBEvent()
                listener.WaitForEventForBroadcasterWithType(BIG_TIMEOUT,
                            self.io_channel.broadcaster,
                            IOChannel.eBroadcastBitThreadDidStart,
                            event)

                self.ready_for_command()
                while not self.is_done:
                    listener.WaitForEvent(BIG_TIMEOUT, event)
                    if event:
                        if event.GetBroadcaster():
                            ev_type = event.GetType()
                            if (event.BroadcasterMatchesRef(self.io_channel.broadcaster)):
                                if ev_type & IOChannel.eBroadcastBitHasUserInput:
                                    command_string = lldb.SBEvent.GetCStringFromEvent(event)
                                    if command_string is None:
                                        command_string = ''
                                    result = lldb.SBCommandReturnObject()

                                    self.debugger.GetCommandInterpreter().HandleCommand(command_string, result, True)
                                    if result.GetOutputSize() > 0:
                                        self.io_channel.out_write(result.GetOutput(), IOChannel.NO_ASYNC)

                                    if result.GetErrorSize() > 0:
                                        self.io_channel.err_write(result.GetError(), IOChannel.NO_ASYNC)

                                    debug(debugDriver, 'waiting_for_command = False')
                                    self.__waiting_for_command = False
                                    if self.__input_reader.IsActive():
                                        self.ready_for_command()

                                elif ev_type & IOChannel.eBroadcastBitThreadShouldExit \
                                    or ev_type & IOChannel.eBroadcastBitThreadDidExit:
                                    self.is_done = True
                                    if ev_type & IOChannel.eBroadcastBitThreadDidExit:
                                        iochannel_thread_exited = True
                                    else:
                                        # TODO: __handle_io_event is not implemented
                                        if self.__handle_io_event(event):
                                            self.is_done = True
                            elif lldb.SBProcess.EventIsProcessEvent(event):
                                self.__handle_process_event(event)
                            elif lldb.SBBreakpoint.EventIsBreakpointEvent(event):
                                self.__handle_breakpoint_event(event)
                            elif event.BroadcasterMatchesRef(sb_interpreter.GetBroadcaster()):
                                # This first one should be replaced with a CommandOverrideCallback function
                                if ev_type & lldb.SBCommandInterpreter.eBroadcastBitQuitCommandReceived:
                                    self.is_done = True
                                elif ev_type & lldb.SBCommandInterpreter.eBroadcastBitAsynchronousErrorData:
                                    data = lldb.SBEvent.GetCStringFromEvent(event)
                                    self.io_channel.err_write(data, IOChannel.ASYNC)
                                    lldb_view_send(stderr_msg(data))
                                elif ev_type & lldb.SBCommandInterpreter.eBroadcastBitAsynchronousOutputData:
                                    data = lldb.SBEvent.GetCStringFromEvent(event)
                                    self.io_channel.out_write(data, IOChannel.ASYNC)
                                    lldb_view_send(stdout_msg(data))

                if not iochannel_thread_exited:
                    event.Clear()
                    listener.GetNextEventForBroadcasterWithType(self.io_channel.broadcaster,
                                                                IOChannel.eBroadcastBitThreadDidExit,
                                                                event)
                    if not event:
                        self.io_channel.stop()

                self.__file_monitor.setDone()
                # Ensure the listener (and everything else, really) is destroyed BEFORE the SBDebugger
                # Otherwise lldb will try to lock a destroyed mutex.
                # TODO: Track that bug!
                listener = None
                lldb.SBDebugger.Destroy(self.debugger)

        debug(debugDriver, 'leaving')
        set_driver_instance(None)
        if self.__on_exit_callback:
            self.__on_exit_callback()