Пример #1
0
    def __init__(self, debugger_store, app):
        Thread.__init__(self)
        self.daemon = True
        self._debugger_store = debugger_store
        self._app = app
        self._listener = debugger_store.debugger.GetListener()
        lldb = get_lldb()
        self.breakpoint_event_type_to_name_map = {
            lldb.eBreakpointEventTypeAdded: 'Added',
            lldb.eBreakpointEventTypeCommandChanged: 'Command Changed',
            lldb.eBreakpointEventTypeConditionChanged: 'Condition Changed',
            lldb.eBreakpointEventTypeDisabled: 'Disabled',
            lldb.eBreakpointEventTypeEnabled: 'Enabled',
            lldb.eBreakpointEventTypeIgnoreChanged: 'Ignore Changed',
            lldb.eBreakpointEventTypeInvalidType: 'Invalid Type',
            lldb.eBreakpointEventTypeLocationsAdded: 'Location Added',
            lldb.eBreakpointEventTypeLocationsRemoved: 'Location Removed',
            lldb.eBreakpointEventTypeLocationsResolved: 'Location Resolved',
            lldb.eBreakpointEventTypeRemoved: 'Removed',
            lldb.eBreakpointEventTypeThreadChanged: 'Thread Changed',
        }

        process = debugger_store.debugger.GetSelectedTarget().process
        self._add_listener_to_process(process)

        # LLDB will not emit any stopping event during attach.
        # Linux lldb has a bug of not emitting stopping event during launch.
        if self._debugger_store.is_attach or sys.platform.startswith('linux'):
            if process.state != lldb.eStateStopped:
                # Instead of using assert() which will crash debugger log an error message
                # and tolerate this non-fatal situation.
                log_error(
                    'Inferior should be stopped after attach or linux launch')
            self._send_paused_notification(process)
        self._add_listener_to_target(process.target)
Пример #2
0
    def _handle_process_event(self, event):
        lldb = get_lldb()
        # Ignore non-stopping events.
        if lldb.SBProcess.GetRestartedFromEvent(event):
            log_debug('Non stopping event: %s' % str(event))
            return

        # Reset the object group so old frame variable objects don't linger
        # forever.
        self._debugger_store.thread_manager.release()

        process = lldb.SBProcess.GetProcessFromEvent(event)
        if process.state == lldb.eStateStopped:
            self._send_paused_notification(process)
        elif process.state == lldb.eStateExited:
            exit_message = 'Process(%d) exited with: %u' % (
                    process.GetProcessID(),
                    process.GetExitStatus())
            if process.GetExitDescription():
                exit_message += (', ' + process.GetExitDescription())
            self._send_user_output('log', exit_message)
            self.should_quit = True
        else:
            self._send_notification('Debugger.resumed', None)

        event_type = event.GetType()
        if event_type == lldb.SBProcess.eBroadcastBitSTDOUT:
            # Read stdout from inferior.
            process_output = ''
            while True:
                output_part = process.GetSTDOUT(1024)
                if not output_part or len(output_part) == 0:
                    break
                process_output += output_part
            self._send_user_output('log', process_output)
Пример #3
0
    def run(self):
        lldb = get_lldb()
        while not self.should_quit:
            event = lldb.SBEvent()
            if self._listener.WaitForEvent(1, event):
                if lldb.SBTarget.EventIsTargetEvent(event):
                    self._handle_target_event(event)
                elif lldb.SBProcess.EventIsProcessEvent(event):
                    self._handle_process_event(event)
                # Even though Breakpoints are registered on SBTarget
                # lldb.SBTarget.EventIsTargetEvent()
                # will return false for breakpoint events so handle them here.
                elif lldb.SBBreakpoint.EventIsBreakpointEvent(event):
                    self._handle_breakpoint_event(event)
                elif lldb.SBWatchpoint.EventIsWatchpointEvent(event):
                    self._handle_watchpoint_event(event)
                else:
                    self._handle_unknown_event(event)

        # Event loop terminates, shutdown chrome server app.
        self._app.shutdown()
        # Detach/Kill inferior.
        if self._debugger_store.is_attach:
            self._debugger_store.debugger.GetSelectedTarget().process.Detach()
        else:
            self._debugger_store.debugger.GetSelectedTarget().process.Kill()
Пример #4
0
    def update(self, process):
        """Update threads status for input process."""
        threads_array = []
        lldb = get_lldb()
        for thread in process.threads:
            description_stream = lldb.SBStream()
            thread.GetDescription(description_stream)

            frame = thread.GetSelectedFrame()
            location = self._debugger_store.location_serializer \
                .get_frame_location(frame)
            threads_array.append({
                'id': thread.GetThreadID(),
                'name': thread.GetName(),
                'address': self._get_frame_name(frame),
                'location': location,
                'hasSource': self._debugger_store.location_serializer.has_source(frame),
                'stopReason': self.get_thread_stop_description(thread),
                'description': description_stream.GetData(),
            })
        stopThreadId = process.GetSelectedThread().GetThreadID()
        if self._previousStopThreadId is not None and self._previousStopThreadId != stopThreadId:
            self._threadSwitchMessage = "Active thread switched from thread {0} to thread {1}" \
                .format(self._previousStopThreadId, stopThreadId)
        else:
            self._threadSwitchMessage = None
        self._previousStopThreadId = stopThreadId
        params = {
            'owningProcessId': process.id,
            'stopThreadId': stopThreadId,
            'threads': threads_array,
        }
        self._debugger_store.chrome_channel.send_notification('Debugger.threadsUpdated', params)
Пример #5
0
 def send_threads_updated(self, process):
     """Update threads status for input process."""
     threads_array = []
     lldb = get_lldb()
     stopThreadId = process.GetSelectedThread().GetThreadID()
     for thread in process.threads:
         description_stream = lldb.SBStream()
         thread.GetDescription(description_stream)
         frame = thread.GetSelectedFrame()
         location = self._debugger_store.location_serializer \
             .get_frame_location(frame)
         threads_array.append({
             'id':
             thread.GetThreadID(),
             'name':
             thread.GetName(),
             'address':
             self._get_frame_name(frame),
             'location':
             location,
             'hasSource':
             self._debugger_store.location_serializer.has_source(frame),
             'stopReason':
             self.get_thread_stop_description(thread),
             'description':
             description_stream.GetData(),
         })
     params = {
         'owningProcessId': process.id,
         'stopThreadId': stopThreadId,
         'threads': threads_array,
     }
     self._debugger_store.chrome_channel.send_notification(
         'Debugger.threadsUpdated', params)
Пример #6
0
    def update(self, process):
        """Update threads status for input process."""
        threads_array = []
        lldb = get_lldb()
        for thread in process.threads:
            description_stream = lldb.SBStream()
            thread.GetDescription(description_stream)

            frame = thread.GetSelectedFrame()
            location = self._debugger_store.location_serializer \
                .get_frame_location(frame)
            threads_array.append({
                'id': thread.GetThreadID(),
                'name': thread.GetName(),
                'address': self._get_frame_name(frame),
                'location': location,
                'hasSource': self._debugger_store.location_serializer.has_source(frame),
                'stopReason': self.get_thread_stop_description(thread),
                'description': description_stream.GetData(),
            })
        stopThreadId = process.GetSelectedThread().GetThreadID()
        if self._previousStopThreadId is not None and self._previousStopThreadId != stopThreadId:
            self._threadSwitchMessage = "Active thread switched from thread {0} to thread {1}" \
                .format(self._previousStopThreadId, stopThreadId)
        else:
            self._threadSwitchMessage = None
        self._previousStopThreadId = stopThreadId
        params = {
            'owningProcessId': process.id,
            'stopThreadId': stopThreadId,
            'threads': threads_array,
        }
        self._debugger_store.chrome_channel.send_notification('Debugger.threadsUpdated', params)
Пример #7
0
def folly_fbstring_core_formatter(valobj, internal_dict):
    '''Type summary formatter for folly fbstring_core.
    Please refer to https://github.com/facebook/folly/blob/master/folly/FBString.h
    for implementation details.
    '''
    lldb = get_lldb()
    target_byte_order = lldb.target.GetByteOrder()
    capacity_sbvalue = valobj.GetValueForExpressionPath('.ml_.capacity_')
    category_extract_mask = 0x3 if target_byte_order == lldb.eByteOrderBig else \
        (0xC0000000 if capacity_sbvalue.size == 4 else 0xC000000000000000)

    class Category:
        Small = 0
        Medium = (0x2 if target_byte_order == lldb.eByteOrderBig else
                  (0x80000000 if capacity_sbvalue.size == 4 else 0x8000000000000000))
        Large = (0x2 if target_byte_order == lldb.eByteOrderBig else
                 (0x40000000 if capacity_sbvalue.size == 4 else 0x4000000000000000))

    category = get_category_value(capacity_sbvalue, category_extract_mask)
    if category == Category.Small:
        return valobj.GetValueForExpressionPath('.small_').GetSummary()
    else:
        assert category == Category.Medium or category == Category.Large, \
            'Unknown category: %d' % category
        return valobj.GetValueForExpressionPath('.ml_.data_').GetSummary()
Пример #8
0
 def send_threads_updated(self, process):
     """Update threads status for input process."""
     threads_array = []
     lldb = get_lldb()
     stopThreadId = process.GetSelectedThread().GetThreadID()
     for thread in process.threads:
         description_stream = lldb.SBStream()
         thread.GetDescription(description_stream)
         frame = thread.GetSelectedFrame()
         location = self._debugger_store.location_serializer \
             .get_frame_location(frame)
         threads_array.append({
             'id': thread.GetThreadID(),
             'name': thread.GetName(),
             'address': self._get_frame_name(frame),
             'location': location,
             'hasSource': self._debugger_store.location_serializer.has_source(frame),
             'stopReason': self.get_thread_stop_description(thread),
             'description': description_stream.GetData(),
         })
     params = {
         'owningProcessId': process.id,
         'stopThreadId': stopThreadId,
         'threads': threads_array,
     }
     self._debugger_store.chrome_channel.send_notification('Debugger.threadsUpdated', params)
Пример #9
0
    def run(self):
        lldb = get_lldb()
        while not self.should_quit:
            event = lldb.SBEvent()
            if self._listener.WaitForEvent(1, event):
                if lldb.SBTarget.EventIsTargetEvent(event):
                    self._handle_target_event(event)
                elif lldb.SBProcess.EventIsProcessEvent(event):
                    self._handle_process_event(event)
                # Even though Breakpoints are registered on SBTarget
                # lldb.SBTarget.EventIsTargetEvent()
                # will return false for breakpoint events so handle them here.
                elif lldb.SBBreakpoint.EventIsBreakpointEvent(event):
                    self._handle_breakpoint_event(event)
                elif lldb.SBWatchpoint.EventIsWatchpointEvent(event):
                    self._handle_watchpoint_event(event)
                else:
                    self._handle_unknown_event(event)

        # Event loop terminates, shutdown chrome server app.
        self._app.shutdown()
        # Detach/Kill inferior.
        if self._debugger_store.is_attach:
            self._debugger_store.debugger.GetSelectedTarget().process.Detach()
        else:
            self._debugger_store.debugger.GetSelectedTarget().process.Kill()
Пример #10
0
    def _handle_process_event(self, event):
        lldb = get_lldb()
        # Ignore non-stopping events.
        if lldb.SBProcess.GetRestartedFromEvent(event):
            log_debug('Non stopping event: %s' % str(event))
            return

        # Reset the object group so old frame variable objects don't linger
        # forever.
        self._debugger_store.thread_manager.release()

        process = lldb.SBProcess.GetProcessFromEvent(event)
        if process.state == lldb.eStateStopped:
            self._send_paused_notification(process)
        elif process.state == lldb.eStateExited:
            exit_message = 'Process(%d) exited with: %u' % (
                process.GetProcessID(), process.GetExitStatus())
            if process.GetExitDescription():
                exit_message += (', ' + process.GetExitDescription())
            self._send_user_output('log', exit_message)
            self.should_quit = True
        else:
            self._send_notification('Debugger.resumed', None)

        event_type = event.GetType()
        if event_type == lldb.SBProcess.eBroadcastBitSTDOUT:
            # Read stdout from inferior.
            process_output = ''
            while True:
                output_part = process.GetSTDOUT(1024)
                if not output_part or len(output_part) == 0:
                    break
                process_output += output_part
            self._send_user_output('log', process_output)
Пример #11
0
 def _send_module_event_notification(self, event, is_load):
     lldb = get_lldb()
     module_count = lldb.SBTarget.GetNumModulesFromEvent(event)
     for i in range(module_count):
         module = lldb.SBTarget.GetModuleAtIndexFromEvent(i, event)
         module_file_name = module.GetPlatformFileSpec().GetFilename()
         output = 'Module(%s) %s' % (module_file_name, 'load' if is_load else 'unload')
         self._send_user_output('log', output)
Пример #12
0
 def handle_stop_debugging_signal(signum, frame):
     log_debug('handle_stop_debugging_signal called')
     if lldb_debugger.GetSelectedTarget() is not None and \
         lldb_debugger.GetSelectedTarget().process is not None and \
             lldb_debugger.GetSelectedTarget().process.state == \
             get_lldb().eStateStopped:
         lldb_debugger.GetSelectedTarget().process.Detach()
     os._exit(0)
Пример #13
0
 def handle(cls, value, add_object_func):
     lldb = get_lldb()
     if (value.type.type == lldb.eTypeClassStruct or
             ((value.type.type == lldb.eTypeClassTypedef) and
              (value.type.GetCanonicalType().type == lldb.eTypeClassStruct))):
         obj = add_object_func(CppStructSBValueRemoteObject(value, add_object_func))
         return obj.serialized_value
     return None
 def _send_module_event_notification(self, event, is_load):
     lldb = get_lldb()
     module_count = lldb.SBTarget.GetNumModulesFromEvent(event)
     for i in range(module_count):
         module = lldb.SBTarget.GetModuleAtIndexFromEvent(i, event)
         module_file_name = module.GetPlatformFileSpec().GetFilename()
         output = 'Module(%s) %s' % (module_file_name, 'load' if is_load else 'unload')
         self._send_user_output('log', output)
Пример #15
0
 def handle_stop_debugging_signal(signum, frame):
     log_debug('handle_stop_debugging_signal called')
     if lldb_debugger.GetSelectedTarget() is not None and \
         lldb_debugger.GetSelectedTarget().process is not None and \
             lldb_debugger.GetSelectedTarget().process.state == \
             get_lldb().eStateStopped:
         lldb_debugger.GetSelectedTarget().process.Detach()
     os._exit(0)
Пример #16
0
    def evaluate(self, params):
        # Cast to string from possible unicode.
        expression = str(params['expression'])

        # `objectGroups` are used by the client to designate remote objects on
        # the server that should stick around (for potential future queries),
        # and eventually released with a `releaseObjectGroup` call.
        #
        # Incidentally, they have names denoting which part of the client made
        # the request. We use these names to disambiguate LLDB commands from
        # C-style expressions.
        if params['objectGroup'] == 'console':
            result = get_lldb().SBCommandReturnObject()
            self.debugger_store.debugger.GetCommandInterpreter().HandleCommand(
                expression, result)

            return {
                'result': {
                    'value': result.GetOutput() + result.GetError(),
                    'type': 'text',
                },
                'wasThrown': False,
            }
        elif params['objectGroup'] == 'watch-group':
            frame = self.debugger_store.debugger.GetSelectedTarget(). \
                process.GetSelectedThread().GetSelectedFrame()
            # TODO: investigate why "EvaluateExpression"
            # is not working for some scenarios on Linux.
            if sys.platform.startswith('linux'):
                value = frame.GetValueForVariablePath(expression)
            else:
                value = frame.EvaluateExpression(expression)
            # `value.error` is an `SBError` instance which captures whether the
            # result had an error. `SBError.success` denotes no error.
            if value.error.success:
                return {
                    'result':
                    value_serializer.serialize_value(
                        value,
                        self.debugger_store.remote_object_manager.
                        get_add_object_func(params['objectGroup'])),
                    'wasThrown':
                    False,
                }
            else:
                return {
                    'result': {
                        'type': 'text',
                    },
                    'wasThrown': True,
                    'exceptionDetails': {
                        'text': value.error.description,
                    }
                }
        return {
            'result': {},
            'wasThrown': False,
        }
Пример #17
0
def start_debugging(debugger, arguments, ipc_channel, is_attach):
    lldb = get_lldb()
    listener = lldb.SBListener('Chrome Dev Tools Listener')
    error = lldb.SBError()
    if getattr(arguments, 'executable_path', None):
        argument_list = map(os.path.expanduser, map(str, arguments.launch_arguments)) \
            if arguments.launch_arguments else None
        environment_variables = [six.binary_type(arg) for arg in
                                 arguments.launch_environment_variables] \
            if arguments.launch_environment_variables else None
        # TODO: should we resolve symbol link?
        executable_path = os.path.expanduser(str(arguments.executable_path)) \
            if arguments.executable_path else None
        working_directory = os.path.expanduser(str(arguments.working_directory)) \
            if arguments.working_directory else None
        stdin_filepath = os.path.expanduser(str(arguments.stdin_filepath)) \
            if arguments.stdin_filepath else None
        target = debugger.CreateTarget(
            executable_path,    # filename
            None,               # target_triple
            None,               # platform_name
            True,               # add_dependent_modules
            error)              # error
        if error.Fail():
            sys.exit(error.description)

        target.Launch(
            listener,
            argument_list,
            environment_variables,
            stdin_filepath,
            None,      # stdout_path
            None,      # stderr_path
            working_directory,
            0,         # launch flags
            True,      # Stop at entry
            error)     # error
    elif getattr(arguments, 'pname', None):
        target = debugger.CreateTarget(None)
        target.AttachToProcessWithName(
            listener,
            str(arguments.pname),
            False,   # does not wait for process to launch.
            error)
    elif getattr(arguments, 'pid', None):
        target = debugger.CreateTarget(None)
        target.AttachToProcessWithID(listener, int(arguments.pid), error)
    else:
        sys.exit('Unknown arguments: %s' % arguments)

    if error.Fail():
        sys.exit(error.description)
    else:
        if is_attach:
            output = 'Successfully attached process.'
        else:
            output = 'Successfully launched process.'
        ipc_channel.send_output_message_async('log', output)
Пример #18
0
def start_debugging(debugger, arguments, ipc_channel, is_attach):
    lldb = get_lldb()
    listener = lldb.SBListener('Chrome Dev Tools Listener')
    error = lldb.SBError()
    if getattr(arguments, 'executable_path', None):
        argument_list = map(os.path.expanduser, map(str, arguments.launch_arguments)) \
            if arguments.launch_arguments else None
        environment_variables = [six.binary_type(arg) for arg in
                                 arguments.launch_environment_variables] \
            if arguments.launch_environment_variables else None
        # TODO: should we resolve symbol link?
        executable_path = os.path.expanduser(str(arguments.executable_path)) \
            if arguments.executable_path else None
        working_directory = os.path.expanduser(str(arguments.working_directory)) \
            if arguments.working_directory else None
        stdin_filepath = os.path.expanduser(str(arguments.stdin_filepath)) \
            if arguments.stdin_filepath else None
        target = debugger.CreateTarget(
            executable_path,  # filename
            None,  # target_triple
            None,  # platform_name
            True,  # add_dependent_modules
            error)  # error
        if error.Fail():
            sys.exit(error.description)

        target.Launch(
            listener,
            argument_list,
            environment_variables,
            stdin_filepath,
            None,  # stdout_path
            None,  # stderr_path
            working_directory,
            0,  # launch flags
            True,  # Stop at entry
            error)  # error
    elif getattr(arguments, 'pname', None):
        target = debugger.CreateTarget(None)
        target.AttachToProcessWithName(
            listener,
            str(arguments.pname),
            False,  # does not wait for process to launch.
            error)
    elif getattr(arguments, 'pid', None):
        target = debugger.CreateTarget(None)
        target.AttachToProcessWithID(listener, int(arguments.pid), error)
    else:
        sys.exit('Unknown arguments: %s' % arguments)

    if error.Fail():
        sys.exit(error.description)
    else:
        if is_attach:
            output = 'Successfully attached process.'
        else:
            output = 'Successfully launched process.'
        ipc_channel.send_output_message_async('log', output)
Пример #19
0
 def _add_listener_to_process(self, process):
     # Listen for process events (Start/Stop/Interrupt/etc).
     broadcaster = process.GetBroadcaster()
     lldb = get_lldb()
     mask = lldb.SBProcess.eBroadcastBitStateChanged | \
         lldb.SBProcess.eBroadcastBitSTDOUT | \
         lldb.SBProcess.eBroadcastBitSTDERR | \
         lldb.SBProcess.eBroadcastBitInterrupt
     broadcaster.AddListener(self._listener, mask)
Пример #20
0
 def _add_listener_to_process(self, process):
     # Listen for process events (Start/Stop/Interrupt/etc).
     broadcaster = process.GetBroadcaster()
     lldb = get_lldb()
     mask = lldb.SBProcess.eBroadcastBitStateChanged | \
         lldb.SBProcess.eBroadcastBitSTDOUT | \
         lldb.SBProcess.eBroadcastBitSTDERR | \
         lldb.SBProcess.eBroadcastBitInterrupt
     broadcaster.AddListener(self._listener, mask)
Пример #21
0
 def handle(cls, value, add_object_func):
     lldb = get_lldb()
     if (value.type.type == lldb.eTypeClassStruct or
         ((value.type.type == lldb.eTypeClassTypedef) and
          (value.type.GetCanonicalType().type == lldb.eTypeClassStruct))):
         obj = add_object_func(
             CppStructSBValueRemoteObject(value, add_object_func))
         return obj.serialized_value
     return None
Пример #22
0
 def _handle_target_event(self, event):
     lldb = get_lldb()
     if event.GetType() == lldb.SBTarget.eBroadcastBitModulesLoaded:
         self._handle_module_load_event(event)
     elif event.GetType() == lldb.SBTarget.eBroadcastBitModulesUnloaded:
         self._handle_module_unload_event(event)
     elif event.GetType() == lldb.SBTarget.eBroadcastBitSymbolsLoaded:
         self._send_user_output('log', 'Symbol loaded')
     else:
         self.self._handle_unknown_event(event)
Пример #23
0
 def _handle_target_event(self, event):
     lldb = get_lldb()
     if event.GetType() == lldb.SBTarget.eBroadcastBitModulesLoaded:
         self._handle_module_load_event(event)
     elif event.GetType() == lldb.SBTarget.eBroadcastBitModulesUnloaded:
         self._handle_module_unload_event(event)
     elif event.GetType() == lldb.SBTarget.eBroadcastBitSymbolsLoaded:
         self._send_user_output('log', 'Symbol loaded')
     else:
         self.self._handle_unknown_event(event)
Пример #24
0
 def _add_listener_to_target(self, target):
     # Listen for breakpoint/watchpoint events (Added/Removed/Disabled/etc).
     broadcaster = target.GetBroadcaster()
     lldb = get_lldb()
     mask = lldb.SBTarget.eBroadcastBitBreakpointChanged | \
         lldb.SBTarget.eBroadcastBitWatchpointChanged | \
         lldb.SBTarget.eBroadcastBitModulesLoaded | \
         lldb.SBTarget.eBroadcastBitModulesUnloaded | \
         lldb.SBTarget.eBroadcastBitSymbolsLoaded
     broadcaster.AddListener(self._listener, mask)
Пример #25
0
 def _add_listener_to_target(self, target):
     # Listen for breakpoint/watchpoint events (Added/Removed/Disabled/etc).
     broadcaster = target.GetBroadcaster()
     lldb = get_lldb()
     mask = lldb.SBTarget.eBroadcastBitBreakpointChanged | \
         lldb.SBTarget.eBroadcastBitWatchpointChanged | \
         lldb.SBTarget.eBroadcastBitModulesLoaded | \
         lldb.SBTarget.eBroadcastBitModulesUnloaded | \
         lldb.SBTarget.eBroadcastBitSymbolsLoaded
     broadcaster.AddListener(self._listener, mask)
Пример #26
0
    def evaluate(self, params):
        # Cast to string from possible unicode.
        expression = str(params['expression'])

        # `objectGroups` are used by the client to designate remote objects on
        # the server that should stick around (for potential future queries),
        # and eventually released with a `releaseObjectGroup` call.
        #
        # Incidentally, they have names denoting which part of the client made
        # the request. We use these names to disambiguate LLDB commands from
        # C-style expressions.
        if params['objectGroup'] == 'console':
            result = get_lldb().SBCommandReturnObject()
            self.debugger_store.debugger.GetCommandInterpreter().HandleCommand(expression, result)

            return {
                'result': {
                    'value': result.GetOutput() + result.GetError(),
                    'type': 'text',
                },
                'wasThrown': False,
            }
        elif params['objectGroup'] == 'watch-group':
            frame = self.debugger_store.debugger.GetSelectedTarget(). \
                process.GetSelectedThread().GetSelectedFrame()
            # TODO: investigate why "EvaluateExpression"
            # is not working for some scenarios on Linux.
            if sys.platform.startswith('linux'):
                value = frame.GetValueForVariablePath(expression)
            else:
                value = frame.EvaluateExpression(expression)
            # `value.error` is an `SBError` instance which captures whether the
            # result had an error. `SBError.success` denotes no error.
            if value.error.success:
                return {
                    'result': value_serializer.serialize_value(
                        value,
                        self.debugger_store.remote_object_manager.
                        get_add_object_func(params['objectGroup'])),
                    'wasThrown': False,
                }
            else:
                return {
                    'result': {
                        'type': 'text',
                    },
                    'wasThrown': True,
                    'exceptionDetails': {
                        'text': value.error.description,
                    }
                }
        return {
            'result': {},
            'wasThrown': False,
        }
 def _should_stop(self, process, thread):
     '''Determine if the thread should be considered stopped.  Arguably
     signals that have been masked as non-stop by `process handle` should not
     stop the thread.
     TODO: Remove this if/when lldb fixes this behavior
     '''
     lldb = get_lldb()
     if thread.GetStopReason() == lldb.eStopReasonSignal:
         signum = thread.GetStopReasonDataAtIndex(0)
         return process.GetUnixSignals().GetShouldStop(signum)
     return thread.GetStopReason() != lldb.eStopReasonNone
Пример #28
0
def StopReason_to_string(reason):
    lldb = get_lldb()
    """Converts lldb.StopReason to a string"""
    return {
      lldb.eStopReasonInvalid: 'invalid',
      lldb.eStopReasonNone: 'none',
      lldb.eStopReasonTrace: 'trace',
      lldb.eStopReasonBreakpoint: 'breakpoint',
      lldb.eStopReasonWatchpoint: 'watchpoint',
      lldb.eStopReasonSignal: 'signal',
      lldb.eStopReasonException: 'exception',
      lldb.eStopReasonPlanComplete: 'plan-complete',
    }[reason]
Пример #29
0
 def _update_stop_thread(self, process):
     '''lldb on Linux has a bug of not setting stop thread correctly.
     This method fixes this issue.
     TODO: remove this when lldb fixes this on Linux.
     '''
     thread = process.GetSelectedThread()
     lldb = get_lldb()
     if thread.GetStopReason() != lldb.eStopReasonNone:
         return
     for thread in process.threads:
         if thread.GetStopReason() != lldb.eStopReasonNone:
             process.SetSelectedThread(thread)
             return
Пример #30
0
 def _update_stop_thread(self, process):
     '''lldb on Linux has a bug of not setting stop thread correctly.
     This method fixes this issue.
     TODO: remove this when lldb fixes this on Linux.
     '''
     thread = process.GetSelectedThread()
     lldb = get_lldb()
     if thread.GetStopReason() != lldb.eStopReasonNone:
         return
     for thread in process.threads:
         if thread.GetStopReason() != lldb.eStopReasonNone:
             process.SetSelectedThread(thread)
             return
Пример #31
0
    def continueToLocation(self, params):
        filelike = self.debugger_store.file_manager.get_by_client_url(params['location']['scriptId'])
        if not filelike or not isinstance(filelike, file_manager.File):
            # Only support setting breakpoints in real files.
            return {}

        lldb = get_lldb()
        path = str(params['location']['scriptId'])
        thread = self.debugger_store.debugger.GetSelectedTarget().GetProcess().GetSelectedThread()
        frame = thread.GetSelectedFrame()
        # atom line numbers a 0-based, while lldb is 1-based
        line = int(params['location']['lineNumber']) + 1
        thread.StepOverUntil(frame, filelike.server_obj, line)
        return {}
Пример #32
0
    def continueToLocation(self, params):
        filelike = self.debugger_store.file_manager.get_by_client_url(params['location']['scriptId'])
        if not filelike or not isinstance(filelike, file_manager.File):
            # Only support setting breakpoints in real files.
            return {}

        lldb = get_lldb()
        path = str(params['location']['scriptId'])
        thread = self.debugger_store.debugger.GetSelectedTarget().GetProcess().GetSelectedThread()
        frame = thread.GetSelectedFrame()
        # atom line numbers a 0-based, while lldb is 1-based
        line = int(params['location']['lineNumber']) + 1
        thread.StepOverUntil(frame, filelike.server_obj, line)
        return {}
Пример #33
0
    def handle(cls, value, add_object_func):
        lldb = get_lldb()
        """ValueHandler for dereferenceable types
        """
        DEREF_TYPE_CLASSES = [
            lldb.eTypeClassPointer,
            # TODO[jeffreytan]: I do not think ObjectC/C++ support reference yet
            # so disable for now(enable it when we support classic C++).
            # lldb.eTypeClassReference,
        ]

        if value.type.type in DEREF_TYPE_CLASSES:
            obj = add_object_func(DereferenceableSBValueRemoteObject(value, add_object_func))
            return obj.serialized_value
        return None
Пример #34
0
def _WatchpointEventType_to_string(event):
    lldb = get_lldb()
    """Converts lldb.BreakpointEventType to a string"""
    return {
        lldb.eWatchpointEventTypeAdded: 'added',
        lldb.eWatchpointEventTypeCommandChanged: 'command-changed',
        lldb.eWatchpointEventTypeConditionChanged: 'condition-changed',
        lldb.eWatchpointEventTypeDisabled: 'disabled',
        lldb.eWatchpointEventTypeEnabled: 'enabled',
        lldb.eWatchpointEventTypeIgnoreChanged: 'ignore-changed',
        lldb.eWatchpointEventTypeInvalidType: 'invalid-type',
        lldb.eWatchpointEventTypeRemoved: 'removed',
        lldb.eWatchpointEventTypeThreadChanged: 'thread-changed',
        lldb.eWatchpointEventTypeTypeChanged: 'type-changed',
    }[event]
Пример #35
0
def _WatchpointEventType_to_string(event):
    lldb = get_lldb()
    """Converts lldb.BreakpointEventType to a string"""
    return {
        lldb.eWatchpointEventTypeAdded: 'added',
        lldb.eWatchpointEventTypeCommandChanged: 'command-changed',
        lldb.eWatchpointEventTypeConditionChanged: 'condition-changed',
        lldb.eWatchpointEventTypeDisabled: 'disabled',
        lldb.eWatchpointEventTypeEnabled: 'enabled',
        lldb.eWatchpointEventTypeIgnoreChanged: 'ignore-changed',
        lldb.eWatchpointEventTypeInvalidType: 'invalid-type',
        lldb.eWatchpointEventTypeRemoved: 'removed',
        lldb.eWatchpointEventTypeThreadChanged: 'thread-changed',
        lldb.eWatchpointEventTypeTypeChanged: 'type-changed',
    }[event]
Пример #36
0
    def handle(cls, value, add_object_func):
        lldb = get_lldb()
        """ValueHandler for dereferenceable types
        """
        DEREF_TYPE_CLASSES = [
            lldb.eTypeClassPointer,
            # TODO[jeffreytan]: I do not think ObjectC/C++ support reference yet
            # so disable for now(enable it when we support classic C++).
            # lldb.eTypeClassReference,
        ]

        if value.type.type in DEREF_TYPE_CLASSES:
            obj = add_object_func(
                DereferenceableSBValueRemoteObject(value, add_object_func))
            return obj.serialized_value
        return None
Пример #37
0
 def setPauseOnExceptions(self, params):
     # First, unhook the old breakpoint exceptions.
     if self.exceptionBreakpointId is not None:
         self.debugger_store.debugger.GetSelectedTarget().BreakpointDelete(
                                                 self.exceptionBreakpointId)
         self.exceptionBreakpointId = None
     # Next, we've been asked to do one of 'none' or 'uncaught' or 'all'.
     # But we'll treat none+uncaught as no-op since that's all LLDB can do.
     if params['state'] == 'all':
         breakpoint = self.debugger_store.debugger.GetSelectedTarget(
                 ).BreakpointCreateForException(get_lldb().eLanguageTypeC_plus_plus,
                                                False,  # don't pause on catch
                                                True    # do pause on throw
                                                )
         self.exceptionBreakpointId = breakpoint.id
     return {}
Пример #38
0
 def setPauseOnExceptions(self, params):
     # First, unhook the old breakpoint exceptions.
     if self.exceptionBreakpointId is not None:
         self.debugger_store.debugger.GetSelectedTarget().BreakpointDelete(
                                                 self.exceptionBreakpointId)
         self.exceptionBreakpointId = None
     # Next, we've been asked to do one of 'none' or 'uncaught' or 'all'.
     # But we'll treat none+uncaught as no-op since that's all LLDB can do.
     if params['state'] == 'all':
         breakpoint = self.debugger_store.debugger.GetSelectedTarget(
                 ).BreakpointCreateForException(get_lldb().eLanguageTypeC_plus_plus,
                                                False,  # don't pause on catch
                                                True    # do pause on throw
                                                )
         self.exceptionBreakpointId = breakpoint.id
     return {}
Пример #39
0
def main():
    arguments = parse_args()
    lldb_python_path = getattr(arguments, 'lldb_python_path', None)
    if lldb_python_path is not None:
        set_custom_lldb_path(os.path.expanduser(lldb_python_path))
    lldb = get_lldb()
    debugger = lldb.SBDebugger.Create()

    is_attach = (getattr(arguments, 'executable_path', None) == None)
    is_interactive = getattr(arguments, 'interactive', False)
    ipc_channel = IpcChannel(is_interactive)

    start_debugging(debugger, arguments, ipc_channel, is_attach)
    register_signal_handler(debugger)

    chrome_channel = ChromeChannel()
    debugger_store = DebuggerStore(
        debugger,
        chrome_channel,
        ipc_channel,
        is_attach,
        str(getattr(arguments, 'basepath', '.')))

    try:
        app = ChromeDevToolsDebuggerApp(debugger_store, getattr(arguments, 'port', 0))

        # Tell IDE server is ready.
        log_debug('Port: %s' % app.debug_server.server_port)

        event_thread = LLDBListenerThread(debugger_store, app)
        event_thread.start()

        if is_interactive:
            app.start_nonblocking()
            interactive_loop(debugger)
        else:
            app.start_blocking()
    except KeyboardInterrupt:  # Force app to exit on Ctrl-C.
        os._exit(1)

    event_thread.join()
    lldb.SBDebugger.Destroy(debugger)
    lldb.SBDebugger.Terminate()
    # TODO: investigate why we need os._exit() to terminate python process.
    os._exit(0)
Пример #40
0
def main():
    arguments = parse_args()
    lldb_python_path = getattr(arguments, 'lldb_python_path', None)
    if lldb_python_path is not None:
        set_custom_lldb_path(os.path.expanduser(lldb_python_path))
    lldb = get_lldb()
    debugger = lldb.SBDebugger.Create()

    is_attach = (getattr(arguments, 'executable_path', None) == None)
    is_interactive = getattr(arguments, 'interactive', False)
    ipc_channel = IpcChannel(is_interactive)

    start_debugging(debugger, arguments, ipc_channel, is_attach)
    register_signal_handler(debugger)

    chrome_channel = ChromeChannel()
    debugger_store = DebuggerStore(
        debugger,
        chrome_channel,
        ipc_channel,
        is_attach,
        str(getattr(arguments, 'basepath', '.')))

    try:
        app = ChromeDevToolsDebuggerApp(debugger_store, getattr(arguments, 'port', 0))

        # Tell IDE server is ready.
        log_debug('Port: %s' % app.debug_server.server_port)

        event_thread = LLDBListenerThread(debugger_store, app)
        event_thread.start()

        if is_interactive:
            app.start_nonblocking()
            interactive_loop(debugger)
        else:
            app.start_blocking()
    except KeyboardInterrupt:  # Force app to exit on Ctrl-C.
        os._exit(1)

    event_thread.join()
    lldb.SBDebugger.Destroy(debugger)
    lldb.SBDebugger.Terminate()
    # TODO: investigate why we need os._exit() to terminate python process.
    os._exit(0)
Пример #41
0
 def _handle_breakpoint_event(self, event):
     lldb = get_lldb()
     breakpoint = lldb.SBBreakpoint.GetBreakpointFromEvent(event)
     event_type = lldb.SBBreakpoint.GetBreakpointEventTypeFromEvent(event)
     log_debug('Breakpoint event: [%s] %s ' %
               (self.breakpoint_event_type_to_name_map[event_type],
                self._get_description_from_object(breakpoint)))
     if event_type == lldb.eBreakpointEventTypeLocationsResolved:
         for location in \
                 self._debugger_store.location_serializer.get_breakpoint_locations(breakpoint):
             params = {
                 'breakpointId': str(breakpoint.id),
                 'location': location,
             }
             self._send_notification('Debugger.breakpointResolved', params)
     else:
         # TODO: handle other breakpoint event types.
         pass
Пример #42
0
 def _handle_breakpoint_event(self, event):
     lldb = get_lldb()
     breakpoint = lldb.SBBreakpoint.GetBreakpointFromEvent(event)
     event_type = lldb.SBBreakpoint.GetBreakpointEventTypeFromEvent(event)
     log_debug('Breakpoint event: [%s] %s ' % (
         self.breakpoint_event_type_to_name_map[event_type],
         self._get_description_from_object(breakpoint)))
     if event_type == lldb.eBreakpointEventTypeLocationsResolved:
         for location in \
                 self._debugger_store.location_serializer.get_breakpoint_locations(breakpoint):
             params = {
                 'breakpointId': str(breakpoint.id),
                 'location': location,
             }
             self._send_notification('Debugger.breakpointResolved', params)
     else:
         # TODO: handle other breakpoint event types.
         pass
Пример #43
0
    def __init__(self, debugger_store, app):
        Thread.__init__(self)
        self.daemon = True
        self._debugger_store = debugger_store
        self._app = app
        self._listener = debugger_store.debugger.GetListener()
        lldb = get_lldb()
        self.breakpoint_event_type_to_name_map = {
            lldb.eBreakpointEventTypeAdded: 'Added',
            lldb.eBreakpointEventTypeCommandChanged: 'Command Changed',
            lldb.eBreakpointEventTypeConditionChanged: 'Condition Changed',
            lldb.eBreakpointEventTypeDisabled: 'Disabled',
            lldb.eBreakpointEventTypeEnabled: 'Enabled',
            lldb.eBreakpointEventTypeIgnoreChanged: 'Ignore Changed',
            lldb.eBreakpointEventTypeInvalidType: 'Invalid Type',
            lldb.eBreakpointEventTypeLocationsAdded: 'Location Added',
            lldb.eBreakpointEventTypeLocationsRemoved: 'Location Removed',
            lldb.eBreakpointEventTypeLocationsResolved: 'Location Resolved',
            lldb.eBreakpointEventTypeRemoved: 'Removed',
            lldb.eBreakpointEventTypeThreadChanged: 'Thread Changed',
        }



        process = debugger_store.debugger.GetSelectedTarget().process
        self._add_listener_to_process(process)

        # LLDB will not emit any stopping event during attach.
        # Linux lldb has a bug of not emitting stopping event during launch.
        if self._debugger_store.is_attach or sys.platform.startswith('linux'):
            if process.state != lldb.eStateStopped:
                # Instead of using assert() which will crash debugger log an error message
                # and tolerate this non-fatal situation.
                log_error('Inferior should be stopped after attach or linux launch')
            self._send_paused_notification(process)
        self._add_listener_to_target(process.target)
Пример #44
0
 def _handle_unknown_event(self, event):
     log_error('Unknown event: %d %s %s' % (
         event.GetType(),
         get_lldb().SBEvent.GetCStringFromEvent(event),
         self._get_description_from_object(event)))
Пример #45
0
 def _get_description_from_object(self, lldb_object):
     description_stream = get_lldb().SBStream()
     lldb_object.GetDescription(description_stream)
     return description_stream.GetData()
Пример #46
0
 def _get_description_from_object(self, lldb_object):
     description_stream = get_lldb().SBStream()
     lldb_object.GetDescription(description_stream)
     return description_stream.GetData()
Пример #47
0
 def _getSteppingFlag(self):
     lldb = get_lldb()
     if self.debugger_store.getDebuggerSettings()['singleThreadStepping']:
         return lldb.eOnlyThisThread
     return lldb.eOnlyDuringStepping
Пример #48
0
 def _handle_unknown_event(self, event):
     log_error(
         'Unknown event: %d %s %s' %
         (event.GetType(), get_lldb().SBEvent.GetCStringFromEvent(event),
          self._get_description_from_object(event)))
Пример #49
0
 def _getSteppingFlag(self):
     lldb = get_lldb()
     if self.debugger_store.getDebuggerSettings()['singleThreadStepping']:
         return lldb.eOnlyThisThread
     return lldb.eOnlyDuringStepping