lldb::ProcessSP PlatformRemoteGDBServer::Attach(
    ProcessAttachInfo &attach_info, Debugger &debugger,
    Target *target, // Can be NULL, if NULL create a new target, else use
                    // existing one
    Error &error) {
  lldb::ProcessSP process_sp;
  if (IsRemote()) {
    if (IsConnected()) {
      lldb::pid_t debugserver_pid = LLDB_INVALID_PROCESS_ID;
      std::string connect_url;
      if (!LaunchGDBServer(debugserver_pid, connect_url)) {
        error.SetErrorStringWithFormat("unable to launch a GDB server on '%s'",
                                       GetHostname());
      } else {
        if (target == NULL) {
          TargetSP new_target_sp;

          error = debugger.GetTargetList().CreateTarget(
              debugger, NULL, NULL, false, NULL, new_target_sp);
          target = new_target_sp.get();
        } else
          error.Clear();

        if (target && error.Success()) {
          debugger.GetTargetList().SetSelectedTarget(target);

          // The darwin always currently uses the GDB remote debugger plug-in
          // so even when debugging locally we are debugging remotely!
          process_sp = target->CreateProcess(
              attach_info.GetListenerForProcess(debugger), "gdb-remote", NULL);
          if (process_sp) {
            error = process_sp->ConnectRemote(nullptr, connect_url.c_str());
            if (error.Success()) {
              ListenerSP listener_sp = attach_info.GetHijackListener();
              if (listener_sp)
                process_sp->HijackProcessEvents(listener_sp);
              error = process_sp->Attach(attach_info);
            }

            if (error.Fail() && debugserver_pid != LLDB_INVALID_PROCESS_ID) {
              KillSpawnedProcess(debugserver_pid);
            }
          }
        }
      }
    } else {
      error.SetErrorString("not connected to remote gdb server");
    }
  }
  return process_sp;
}
lldb::ProcessSP
PlatformWindows::Attach(ProcessAttachInfo &attach_info,
                        Debugger &debugger,
                        Target *target,
                        Error &error)
{
    error.Clear();
    lldb::ProcessSP process_sp;
    if (!IsHost())
    {
        if (m_remote_platform_sp)
            process_sp = m_remote_platform_sp->Attach (attach_info, debugger, target, error);
        else
            error.SetErrorString ("the platform is not currently connected");
        return process_sp;
    }

    if (target == nullptr)
    {
        TargetSP new_target_sp;
        FileSpec emptyFileSpec;
        ArchSpec emptyArchSpec;

        error = debugger.GetTargetList().CreateTarget(debugger,
                                                      nullptr,
                                                      nullptr,
                                                      false,
                                                      nullptr,
                                                      new_target_sp);
        target = new_target_sp.get();
    }

    if (!target || error.Fail())
        return process_sp;

    debugger.GetTargetList().SetSelectedTarget(target);

    const char *plugin_name = attach_info.GetProcessPluginName();
    process_sp = target->CreateProcess(attach_info.GetListenerForProcess(debugger), plugin_name, nullptr);

    process_sp->HijackProcessEvents(attach_info.GetHijackListener());
    if (process_sp)
        error = process_sp->Attach (attach_info);

    return process_sp;
}
Example #3
0
lldb::ProcessSP
PlatformLinux::Attach(ProcessAttachInfo &attach_info,
                      Debugger &debugger,
                      Target *target,
                      Listener &listener,
                      Error &error)
{
    lldb::ProcessSP process_sp;
    if (IsHost())
    {
        if (target == NULL)
        {
            TargetSP new_target_sp;
            FileSpec emptyFileSpec;
            ArchSpec emptyArchSpec;

            error = debugger.GetTargetList().CreateTarget (debugger,
                                                           emptyFileSpec,
                                                           emptyArchSpec,
                                                           false,
                                                           m_remote_platform_sp,
                                                           new_target_sp);
            target = new_target_sp.get();
        }
        else
            error.Clear();

        if (target && error.Success())
        {
            debugger.GetTargetList().SetSelectedTarget(target);

            process_sp = target->CreateProcess (listener,
                                                attach_info.GetProcessPluginName(),
                                                NULL);

            if (process_sp)
                error = process_sp->Attach (attach_info);
        }
    }
    else
    {
        if (m_remote_platform_sp)
            process_sp = m_remote_platform_sp->Attach (attach_info, debugger, target, listener, error);
        else
            error.SetErrorString ("the platform is not currently connected");
    }
    return process_sp;
}
Example #4
0
lldb::ProcessSP
PlatformFreeBSD::Attach(ProcessAttachInfo &attach_info,
                        Debugger &debugger,
                        Target *target,
                        Error &error)
{
    lldb::ProcessSP process_sp;
    if (IsHost())
    {
        if (target == NULL)
        {
            TargetSP new_target_sp;
            ArchSpec emptyArchSpec;

            error = debugger.GetTargetList().CreateTarget (debugger,
                                                           NULL,
                                                           emptyArchSpec,
                                                           false,
                                                           m_remote_platform_sp,
                                                           new_target_sp);
            target = new_target_sp.get();
        }
        else
            error.Clear();

        if (target && error.Success())
        {
            debugger.GetTargetList().SetSelectedTarget(target);
            // The freebsd always currently uses the GDB remote debugger plug-in
            // so even when debugging locally we are debugging remotely!
            // Just like the darwin plugin.
            process_sp = target->CreateProcess (attach_info.GetListenerForProcess(debugger), "gdb-remote", NULL);

            if (process_sp)
                error = process_sp->Attach (attach_info);
        }
    }
    else
    {
        if (m_remote_platform_sp)
            process_sp = m_remote_platform_sp->Attach (attach_info, debugger, target, error);
        else
            error.SetErrorString ("the platform is not currently connected");
    }
    return process_sp;
}
Example #5
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;
}
Example #6
0
lldb::ProcessSP
PlatformPOSIX::Attach (ProcessAttachInfo &attach_info,
                       Debugger &debugger,
                       Target *target,
                       Error &error)
{
    lldb::ProcessSP process_sp;
    Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM));

    if (IsHost())
    {
        if (target == NULL)
        {
            TargetSP new_target_sp;

            error = debugger.GetTargetList().CreateTarget (debugger,
                                                           NULL,
                                                           NULL,
                                                           false,
                                                           NULL,
                                                           new_target_sp);
            target = new_target_sp.get();
            if (log)
                log->Printf ("PlatformPOSIX::%s created new target", __FUNCTION__);
        }
        else
        {
            error.Clear();
            if (log)
                log->Printf ("PlatformPOSIX::%s target already existed, setting target", __FUNCTION__);
        }

        if (target && error.Success())
        {
            debugger.GetTargetList().SetSelectedTarget(target);
            if (log)
            {
                ModuleSP exe_module_sp = target->GetExecutableModule ();
                log->Printf("PlatformPOSIX::%s set selected target to %p %s", __FUNCTION__, (void *)target,
                            exe_module_sp ? exe_module_sp->GetFileSpec().GetPath().c_str() : "<null>");
            }


            process_sp = target->CreateProcess (attach_info.GetListenerForProcess(debugger), attach_info.GetProcessPluginName(), NULL);

            if (process_sp)
            {
                // Set UnixSignals appropriately.
                process_sp->SetUnixSignals (Host::GetUnixSignals ());

                auto listener_sp = attach_info.GetHijackListener();
                if (listener_sp == nullptr)
                {
                    listener_sp.reset(new Listener("lldb.PlatformPOSIX.attach.hijack"));
                    attach_info.SetHijackListener(listener_sp);
                }
                process_sp->HijackProcessEvents(listener_sp.get());
                error = process_sp->Attach (attach_info);
            }
        }
    }
    else
    {
        if (m_remote_platform_sp)
            process_sp = m_remote_platform_sp->Attach (attach_info, debugger, target, error);
        else
            error.SetErrorString ("the platform is not currently connected");
    }
    return process_sp;
}