[ProcessWindows] Notify process plugin when the launch succeeds.

llvm-svn: 221637
This commit is contained in:
Zachary Turner 2014-11-10 22:32:18 +00:00
parent ba80da60c8
commit 3985f891a3
9 changed files with 89 additions and 53 deletions

View File

@ -43,28 +43,22 @@ struct DebugLaunchContext
DebuggerThread::DebuggerThread(DebugDelegateSP debug_delegate) DebuggerThread::DebuggerThread(DebugDelegateSP debug_delegate)
: m_debug_delegate(debug_delegate) : m_debug_delegate(debug_delegate)
, m_image_file(nullptr) , m_image_file(nullptr)
, m_launched_event(nullptr)
{ {
m_launched_event = ::CreateEvent(nullptr, TRUE, FALSE, nullptr);
} }
DebuggerThread::~DebuggerThread() DebuggerThread::~DebuggerThread()
{ {
if (m_launched_event != nullptr)
::CloseHandle(m_launched_event);
} }
HostProcess Error
DebuggerThread::DebugLaunch(const ProcessLaunchInfo &launch_info) DebuggerThread::DebugLaunch(const ProcessLaunchInfo &launch_info)
{ {
Error error; Error error;
DebugLaunchContext *context = new DebugLaunchContext(this, launch_info); DebugLaunchContext *context = new DebugLaunchContext(this, launch_info);
HostThread slave_thread(ThreadLauncher::LaunchThread("lldb.plugin.process-windows.slave[?]", DebuggerThreadRoutine, context, &error)); HostThread slave_thread(ThreadLauncher::LaunchThread("lldb.plugin.process-windows.slave[?]", DebuggerThreadRoutine, context, &error));
if (error.Success())
::WaitForSingleObject(m_launched_event, INFINITE);
return m_process; return error;
} }
lldb::thread_result_t lldb::thread_result_t
@ -95,7 +89,10 @@ DebuggerThread::DebuggerThreadRoutine(const ProcessLaunchInfo &launch_info)
if (error.Success()) if (error.Success())
DebugLoop(); DebugLoop();
else else
SetEvent(m_launched_event); {
ProcessMessageDebuggerError message(m_process, error, 0);
m_debug_delegate->OnDebuggerError(message);
}
return 0; return 0;
} }
@ -175,7 +172,8 @@ DebuggerThread::HandleCreateProcessEvent(const CREATE_PROCESS_DEBUG_INFO &info,
((HostThreadWindows &)m_main_thread.GetNativeThread()).SetOwnsHandle(false); ((HostThreadWindows &)m_main_thread.GetNativeThread()).SetOwnsHandle(false);
m_image_file = info.hFile; m_image_file = info.hFile;
SetEvent(m_launched_event); ProcessMessageDebuggerConnected message(m_process);
m_debug_delegate->OnDebuggerConnected(message);
return DBG_CONTINUE; return DBG_CONTINUE;
} }

View File

@ -32,7 +32,18 @@ class DebuggerThread : public std::enable_shared_from_this<DebuggerThread>
DebuggerThread(DebugDelegateSP debug_delegate); DebuggerThread(DebugDelegateSP debug_delegate);
virtual ~DebuggerThread(); virtual ~DebuggerThread();
HostProcess DebugLaunch(const ProcessLaunchInfo &launch_info); Error DebugLaunch(const ProcessLaunchInfo &launch_info);
HostProcess
GetProcess() const
{
return m_process;
}
HostThread
GetMainThread() const
{
return m_main_thread;
}
private: private:
void DebugLoop(); void DebugLoop();
@ -48,9 +59,6 @@ class DebuggerThread : public std::enable_shared_from_this<DebuggerThread>
DebugDelegateSP m_debug_delegate; DebugDelegateSP m_debug_delegate;
HANDLE m_launched_event; // Signalled when the process is finished launching, either
// successfully or with an error.
HostProcess m_process; // The process being debugged. HostProcess m_process; // The process being debugged.
HostThread m_main_thread; // The main thread of the inferior. HostThread m_main_thread; // The main thread of the inferior.
HANDLE m_image_file; // The image file of the process being debugged. HANDLE m_image_file; // The image file of the process being debugged.

View File

@ -22,7 +22,6 @@ class DebuggerThread;
// Process message forward declarations. // Process message forward declarations.
class ProcessMessageBase; class ProcessMessageBase;
class ProcessMessageCreateProcess;
class ProcessMessageExitProcess; class ProcessMessageExitProcess;
class ProcessMessageDebuggerConnected; class ProcessMessageDebuggerConnected;
class ProcessMessageException; class ProcessMessageException;
@ -34,7 +33,7 @@ class ProcessMessageDebugString;
class ProcessMessageDebuggerError; class ProcessMessageDebuggerError;
typedef std::shared_ptr<IDebugDelegate> DebugDelegateSP; typedef std::shared_ptr<IDebugDelegate> DebugDelegateSP;
typedef std::unique_ptr<DebuggerThread> DebuggerThreadUP; typedef std::shared_ptr<DebuggerThread> DebuggerThreadSP;
} }
#endif #endif

View File

@ -10,20 +10,11 @@
#ifndef liblldb_Plugins_Process_Windows_IDebugDelegate_H_ #ifndef liblldb_Plugins_Process_Windows_IDebugDelegate_H_
#define liblldb_Plugins_Process_Windows_IDebugDelegate_H_ #define liblldb_Plugins_Process_Windows_IDebugDelegate_H_
#include "ForwardDecl.h"
namespace lldb_private namespace lldb_private
{ {
class ProcessMessageCreateProcess;
class ProcessMessageExitProcess;
class ProcessMessageDebuggerConnected;
class ProcessMessageException;
class ProcessMessageCreateThread;
class ProcessMessageExitThread;
class ProcessMessageLoadDll;
class ProcessMessageUnloadDll;
class ProcessMessageDebugString;
class ProcessMessageDebuggerError;
//---------------------------------------------------------------------- //----------------------------------------------------------------------
// IDebugDelegate // IDebugDelegate
// //
@ -35,7 +26,6 @@ class IDebugDelegate
public: public:
virtual ~IDebugDelegate() {} virtual ~IDebugDelegate() {}
virtual void OnProcessLaunched(const ProcessMessageCreateProcess &message) = 0;
virtual void OnExitProcess(const ProcessMessageExitProcess &message) = 0; virtual void OnExitProcess(const ProcessMessageExitProcess &message) = 0;
virtual void OnDebuggerConnected(const ProcessMessageDebuggerConnected &message) = 0; virtual void OnDebuggerConnected(const ProcessMessageDebuggerConnected &message) = 0;
virtual void OnDebugException(const ProcessMessageException &message) = 0; virtual void OnDebugException(const ProcessMessageException &message) = 0;

View File

@ -18,12 +18,6 @@ LocalDebugDelegate::LocalDebugDelegate(ProcessSP process)
{ {
} }
void
LocalDebugDelegate::OnProcessLaunched(const ProcessMessageCreateProcess &message)
{
((ProcessWindows &)*m_process).OnProcessLaunched(message);
}
void void
LocalDebugDelegate::OnExitProcess(const ProcessMessageExitProcess &message) LocalDebugDelegate::OnExitProcess(const ProcessMessageExitProcess &message)
{ {

View File

@ -42,16 +42,15 @@ class LocalDebugDelegate : public IDebugDelegate
public: public:
explicit LocalDebugDelegate::LocalDebugDelegate(lldb::ProcessSP process); explicit LocalDebugDelegate::LocalDebugDelegate(lldb::ProcessSP process);
void OnProcessLaunched(const ProcessMessageCreateProcess &message); void OnExitProcess(const ProcessMessageExitProcess &message) override;
void OnExitProcess(const ProcessMessageExitProcess &message); void OnDebuggerConnected(const ProcessMessageDebuggerConnected &message) override;
void OnDebuggerConnected(const ProcessMessageDebuggerConnected &message); void OnDebugException(const ProcessMessageException &message) override;
void OnDebugException(const ProcessMessageException &message); void OnCreateThread(const ProcessMessageCreateThread &message) override;
void OnCreateThread(const ProcessMessageCreateThread &message); void OnExitThread(const ProcessMessageExitThread &message) override;
void OnExitThread(const ProcessMessageExitThread &message); void OnLoadDll(const ProcessMessageLoadDll &message) override;
void OnLoadDll(const ProcessMessageLoadDll &message); void OnUnloadDll(const ProcessMessageUnloadDll &message) override;
void OnUnloadDll(const ProcessMessageUnloadDll &message); void OnDebugString(const ProcessMessageDebugString &message) override;
void OnDebugString(const ProcessMessageDebugString &message); void OnDebuggerError(const ProcessMessageDebuggerError &message) override;
void OnDebuggerError(const ProcessMessageDebuggerError &message);
private: private:
lldb::ProcessSP m_process; lldb::ProcessSP m_process;

View File

@ -42,6 +42,15 @@ class ProcessMessageBase
HostProcess m_process; HostProcess m_process;
}; };
class ProcessMessageDebuggerConnected : public ProcessMessageBase
{
public:
ProcessMessageDebuggerConnected(const HostProcess &process)
: ProcessMessageBase(process)
{
}
};
class ProcessMessageExitProcess : public ProcessMessageBase class ProcessMessageExitProcess : public ProcessMessageBase
{ {
public: public:

View File

@ -35,6 +35,24 @@
using namespace lldb; using namespace lldb;
using namespace lldb_private; using namespace lldb_private;
namespace lldb_private
{
// We store a pointer to this class in the ProcessWindows, so that we don't expose Windows
// OS specific types and implementation details from a public header file.
class ProcessWindowsData
{
public:
ProcessWindowsData()
: m_launched_event(nullptr)
{
m_launched_event = ::CreateEvent(nullptr, TRUE, FALSE, nullptr);
}
~ProcessWindowsData() { ::CloseHandle(m_launched_event); }
HANDLE m_launched_event;
};
}
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// Static functions. // Static functions.
@ -61,8 +79,9 @@ ProcessWindows::Initialize()
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// Constructors and destructors. // Constructors and destructors.
ProcessWindows::ProcessWindows(Target& target, Listener &listener) ProcessWindows::ProcessWindows(Target &target, Listener &listener)
: lldb_private::Process(target, listener) : lldb_private::Process(target, listener)
, m_data_up(new ProcessWindowsData())
{ {
} }
@ -107,7 +126,15 @@ ProcessWindows::DoLaunch(Module *exe_module,
{ {
DebugDelegateSP delegate(new LocalDebugDelegate(shared_from_this())); DebugDelegateSP delegate(new LocalDebugDelegate(shared_from_this()));
m_debugger.reset(new DebuggerThread(delegate)); m_debugger.reset(new DebuggerThread(delegate));
process = m_debugger->DebugLaunch(launch_info); // Kick off the DebugLaunch asynchronously and wait for it to complete.
result = m_debugger->DebugLaunch(launch_info);
if (result.Success())
{
if (::WaitForSingleObject(m_data_up->m_launched_event, INFINITE) == WAIT_OBJECT_0)
process = m_debugger->GetProcess();
else
result.SetError(::GetLastError(), eErrorTypeWin32);
}
} }
else else
return Host::LaunchProcess(launch_info); return Host::LaunchProcess(launch_info);
@ -209,11 +236,6 @@ ProcessWindows::CanDebug(Target &target, bool plugin_specified_by_name)
return false; return false;
} }
void
ProcessWindows::OnProcessLaunched(const ProcessMessageCreateProcess &message)
{
}
void void
ProcessWindows::OnExitProcess(const ProcessMessageExitProcess &message) ProcessWindows::OnExitProcess(const ProcessMessageExitProcess &message)
{ {
@ -223,6 +245,7 @@ ProcessWindows::OnExitProcess(const ProcessMessageExitProcess &message)
void void
ProcessWindows::OnDebuggerConnected(const ProcessMessageDebuggerConnected &message) ProcessWindows::OnDebuggerConnected(const ProcessMessageDebuggerConnected &message)
{ {
::SetEvent(m_data_up->m_launched_event);
} }
void void
@ -258,4 +281,16 @@ ProcessWindows::OnDebugString(const ProcessMessageDebugString &message)
void void
ProcessWindows::OnDebuggerError(const ProcessMessageDebuggerError &message) ProcessWindows::OnDebuggerError(const ProcessMessageDebuggerError &message)
{ {
DWORD result = ::WaitForSingleObject(m_data_up->m_launched_event, 0);
if (result == WAIT_TIMEOUT)
{
// If we haven't actually launched the process yet, this was an error
// launching the process. Set the internal error and signal.
m_launch_error = message.GetError();
::SetEvent(m_data_up->m_launched_event);
return;
}
// This happened while debugging.
// TODO: Implement this.
} }

View File

@ -14,11 +14,13 @@
// C++ Includes // C++ Includes
#include <map> #include <map>
#include <memory>
#include <queue> #include <queue>
// Other libraries and framework includes // Other libraries and framework includes
#include "ForwardDecl.h" #include "ForwardDecl.h"
#include "IDebugDelegate.h" #include "IDebugDelegate.h"
#include "lldb/Core/Error.h"
#include "lldb/Host/HostThread.h" #include "lldb/Host/HostThread.h"
#include "lldb/Target/Process.h" #include "lldb/Target/Process.h"
@ -27,6 +29,7 @@ class ProcessMonitor;
namespace lldb_private namespace lldb_private
{ {
class HostProcess; class HostProcess;
class ProcessWindowsData;
} }
class ProcessWindows : public lldb_private::Process, public lldb_private::IDebugDelegate class ProcessWindows : public lldb_private::Process, public lldb_private::IDebugDelegate
@ -112,7 +115,6 @@ public:
virtual size_t DoReadMemory(lldb::addr_t vm_addr, void *buf, size_t size, lldb_private::Error &error); virtual size_t DoReadMemory(lldb::addr_t vm_addr, void *buf, size_t size, lldb_private::Error &error);
// IDebugDelegate overrides. // IDebugDelegate overrides.
virtual void OnProcessLaunched(const lldb_private::ProcessMessageCreateProcess &message) override;
virtual void OnExitProcess(const lldb_private::ProcessMessageExitProcess &message) override; virtual void OnExitProcess(const lldb_private::ProcessMessageExitProcess &message) override;
virtual void OnDebuggerConnected(const lldb_private::ProcessMessageDebuggerConnected &message) override; virtual void OnDebuggerConnected(const lldb_private::ProcessMessageDebuggerConnected &message) override;
virtual void OnDebugException(const lldb_private::ProcessMessageException &message) override; virtual void OnDebugException(const lldb_private::ProcessMessageException &message) override;
@ -124,7 +126,9 @@ public:
virtual void OnDebuggerError(const lldb_private::ProcessMessageDebuggerError &message) override; virtual void OnDebuggerError(const lldb_private::ProcessMessageDebuggerError &message) override;
private: private:
lldb_private::DebuggerThreadUP m_debugger; std::unique_ptr<lldb_private::ProcessWindowsData> m_data_up;
lldb_private::Error m_launch_error;
lldb_private::DebuggerThreadSP m_debugger;
}; };
#endif // liblldb_Plugins_Process_Windows_ProcessWindows_H_ #endif // liblldb_Plugins_Process_Windows_ProcessWindows_H_