예제 #1
0
Error
ProcessWindows::DoLaunch(Module *exe_module,
                         ProcessLaunchInfo &launch_info)
{
    // Even though m_session_data is accessed here, it is before a debugger thread has been
    // kicked off.  So there's no race conditions, and it shouldn't be necessary to acquire
    // the mutex.

    Error result;
    if (!launch_info.GetFlags().Test(eLaunchFlagDebug))
    {
        StreamString stream;
        stream.Printf("ProcessWindows unable to launch '%s'.  ProcessWindows can only be used for debug launches.",
                      launch_info.GetExecutableFile().GetPath().c_str());
        std::string message = stream.GetString();
        result.SetErrorString(message.c_str());

        WINERR_IFALL(WINDOWS_LOG_PROCESS, message.c_str());
        return result;
    }

    bool stop_at_entry = launch_info.GetFlags().Test(eLaunchFlagStopAtEntry);
    m_session_data.reset(new ProcessWindowsData(stop_at_entry));

    SetPrivateState(eStateLaunching);
    DebugDelegateSP delegate(new LocalDebugDelegate(shared_from_this()));
    m_session_data->m_debugger.reset(new DebuggerThread(delegate));
    DebuggerThreadSP debugger = m_session_data->m_debugger;

    // Kick off the DebugLaunch asynchronously and wait for it to complete.
    result = debugger->DebugLaunch(launch_info);
    if (result.Fail())
    {
        WINERR_IFALL(WINDOWS_LOG_PROCESS, "DoLaunch failed launching '%s'.  %s",
                     launch_info.GetExecutableFile().GetPath().c_str(), result.AsCString());
        return result;
    }

    HostProcess process;
    Error error = WaitForDebuggerConnection(debugger, process);
    if (error.Fail())
    {
        WINERR_IFALL(WINDOWS_LOG_PROCESS, "DoLaunch failed launching '%s'.  %s",
                     launch_info.GetExecutableFile().GetPath().c_str(), error.AsCString());
        return error;
    }

    WINLOG_IFALL(WINDOWS_LOG_PROCESS, "DoLaunch successfully launched '%s'",
                 launch_info.GetExecutableFile().GetPath().c_str());

    // We've hit the initial stop.  If eLaunchFlagsStopAtEntry was specified, the private state
    // should already be set to eStateStopped as a result of hitting the initial breakpoint.  If
    // it was not set, the breakpoint should have already been resumed from and the private state
    // should already be eStateRunning.
    launch_info.SetProcessID(process.GetProcessId());
    SetID(process.GetProcessId());

    return result;
}
예제 #2
0
Error
ProcessWindows::DoLaunch(Module *exe_module,
                         ProcessLaunchInfo &launch_info)
{
    // Even though m_session_data is accessed here, it is before a debugger thread has been
    // kicked off.  So there's no race conditions, and it shouldn't be necessary to acquire
    // the mutex.

    Error result;
    if (!launch_info.GetFlags().Test(eLaunchFlagDebug))
    {
        result.SetErrorString("ProcessWindows can only be used to launch processes for debugging.");
        return result;
    }

    m_session_data.reset(new ProcessWindowsData(launch_info));

    SetPrivateState(eStateLaunching);
    DebugDelegateSP delegate(new LocalDebugDelegate(shared_from_this()));
    m_session_data->m_debugger.reset(new DebuggerThread(delegate));
    DebuggerThreadSP debugger = m_session_data->m_debugger;

    // Kick off the DebugLaunch asynchronously and wait for it to complete.
    result = debugger->DebugLaunch(launch_info);

    HostProcess process;
    if (result.Success())
    {
        // Block this function until we receive the initial stop from the process.
        if (::WaitForSingleObject(m_session_data->m_initial_stop_event, INFINITE) == WAIT_OBJECT_0)
        {
            process = debugger->GetProcess();
            if (m_session_data->m_launch_error.Fail())
                result = m_session_data->m_launch_error;
        }
        else
            result.SetError(::GetLastError(), eErrorTypeWin32);
    }

    if (!result.Success())
        return result;

    // We've hit the initial stop.  The private state should already be set to stopped as a result
    // of encountering the breakpoint exception in ProcessWindows::OnDebugException.
    launch_info.SetProcessID(process.GetProcessId());
    SetID(process.GetProcessId());

    return result;
}
예제 #3
0
파일: Host.cpp 프로젝트: ahoppen/swift-lldb
Error Host::LaunchProcess(ProcessLaunchInfo &launch_info) {
  std::unique_ptr<ProcessLauncher> delegate_launcher;
#if defined(_WIN32)
  delegate_launcher.reset(new ProcessLauncherWindows());
#elif defined(__linux__)
  delegate_launcher.reset(new ProcessLauncherLinux());
#else
  delegate_launcher.reset(new ProcessLauncherPosix());
#endif
  MonitoringProcessLauncher launcher(std::move(delegate_launcher));

  Error error;
  HostProcess process = launcher.LaunchProcess(launch_info, error);

  // TODO(zturner): It would be better if the entire HostProcess were returned
  // instead of writing
  // it into this structure.
  launch_info.SetProcessID(process.GetProcessId());

  return error;
}
예제 #4
0
Error
ProcessWindows::DoAttachToProcessWithID(lldb::pid_t pid, const ProcessAttachInfo &attach_info)
{
    m_session_data.reset(new ProcessWindowsData(!attach_info.GetContinueOnceAttached()));

    DebugDelegateSP delegate(new LocalDebugDelegate(shared_from_this()));
    DebuggerThreadSP debugger(new DebuggerThread(delegate));

    m_session_data->m_debugger = debugger;

    DWORD process_id = static_cast<DWORD>(pid);
    Error error = debugger->DebugAttach(process_id, attach_info);
    if (error.Fail())
    {
        WINLOG_IFALL(WINDOWS_LOG_PROCESS,
                     "DoAttachToProcessWithID encountered an error occurred initiating the asynchronous attach.  %s",
                     error.AsCString());
        return error;
    }

    HostProcess process;
    error = WaitForDebuggerConnection(debugger, process);
    if (error.Fail())
    {
        WINLOG_IFALL(WINDOWS_LOG_PROCESS,
                     "DoAttachToProcessWithID encountered an error waiting for the debugger to connect.  %s",
                     error.AsCString());
        return error;
    }

    WINLOG_IFALL(WINDOWS_LOG_PROCESS, "DoAttachToProcessWithID successfully attached to process with pid=%u",
                 process_id);

    // We've hit the initial stop.  If eLaunchFlagsStopAtEntry was specified, the private state
    // should already be set to eStateStopped as a result of hitting the initial breakpoint.  If
    // it was not set, the breakpoint should have already been resumed from and the private state
    // should already be eStateRunning.
    SetID(process.GetProcessId());
    return error;
}
HostProcess
MonitoringProcessLauncher::LaunchProcess(const ProcessLaunchInfo &launch_info,
                                         Status &error) {
  ProcessLaunchInfo resolved_info(launch_info);

  error.Clear();
  char exe_path[PATH_MAX];

  PlatformSP host_platform_sp(Platform::GetHostPlatform());

  const ArchSpec &arch_spec = resolved_info.GetArchitecture();

  FileSpec exe_spec(resolved_info.GetExecutableFile());

  llvm::sys::fs::file_status stats;
  status(exe_spec.GetPath(), stats);
  if (!is_regular_file(stats)) {
    ModuleSpec module_spec(exe_spec, arch_spec);
    lldb::ModuleSP exe_module_sp;
    error =
        host_platform_sp->ResolveExecutable(module_spec, exe_module_sp, NULL);

    if (error.Fail())
      return HostProcess();

    if (exe_module_sp) {
      exe_spec = exe_module_sp->GetFileSpec();
      status(exe_spec.GetPath(), stats);
    }
  }

  if (exists(stats)) {
    exe_spec.GetPath(exe_path, sizeof(exe_path));
  } else {
    resolved_info.GetExecutableFile().GetPath(exe_path, sizeof(exe_path));
    error.SetErrorStringWithFormat("executable doesn't exist: '%s'", exe_path);
    return HostProcess();
  }

  resolved_info.SetExecutableFile(exe_spec, false);
  assert(!resolved_info.GetFlags().Test(eLaunchFlagLaunchInTTY));

  HostProcess process =
      m_delegate_launcher->LaunchProcess(resolved_info, error);

  if (process.GetProcessId() != LLDB_INVALID_PROCESS_ID) {
    Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));

    Host::MonitorChildProcessCallback callback =
        launch_info.GetMonitorProcessCallback();

    bool monitor_signals = false;
    if (callback) {
      // If the ProcessLaunchInfo specified a callback, use that.
      monitor_signals = launch_info.GetMonitorSignals();
    } else {
      callback = Process::SetProcessExitStatus;
    }

    process.StartMonitoring(callback, monitor_signals);
    if (log)
      log->PutCString("started monitoring child process.");
  } else {
    // Invalid process ID, something didn't go well
    if (error.Success())
      error.SetErrorString("process launch failed for unknown reasons");
  }
  return process;
}