When processes are launched for debugging on Windows now, LLDB will detect changes such as DLL loads and unloads, breakpoints, thread creation and deletion, etc. These notifications are not yet propagated to LLDB in a way that LLDB understands what is happening with the process. This only picks up the notifications from the OS in a way that they can be sent to LLDB with subsequent patches. Reviewed by: Scott Graham Differential Revision: http://reviews.llvm.org/D6037 llvm-svn: 221207
215 lines
4.8 KiB
C++
215 lines
4.8 KiB
C++
//===-- ProcessWindows.cpp --------------------------------------*- C++ -*-===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Windows includes
|
|
#include "lldb/Host/windows/windows.h"
|
|
|
|
// C++ Includes
|
|
#include <vector>
|
|
|
|
// Other libraries and framework includes
|
|
#include "lldb/Core/Module.h"
|
|
#include "lldb/Core/PluginManager.h"
|
|
#include "lldb/Core/State.h"
|
|
#include "lldb/Host/Host.h"
|
|
#include "lldb/Host/HostProcess.h"
|
|
#include "lldb/Host/MonitoringProcessLauncher.h"
|
|
#include "lldb/Host/ThreadLauncher.h"
|
|
#include "lldb/Host/windows/ProcessLauncherWindows.h"
|
|
#include "lldb/Symbol/ObjectFile.h"
|
|
#include "lldb/Target/DynamicLoader.h"
|
|
#include "lldb/Target/FileAction.h"
|
|
#include "lldb/Target/Target.h"
|
|
|
|
#include "DebugDriverThread.h"
|
|
#include "DebugProcessLauncher.h"
|
|
#include "ProcessWindows.h"
|
|
|
|
using namespace lldb;
|
|
using namespace lldb_private;
|
|
|
|
//------------------------------------------------------------------------------
|
|
// Static functions.
|
|
|
|
ProcessSP
|
|
ProcessWindows::CreateInstance(Target &target, Listener &listener, const FileSpec *)
|
|
{
|
|
return ProcessSP(new ProcessWindows(target, listener));
|
|
}
|
|
|
|
void
|
|
ProcessWindows::Initialize()
|
|
{
|
|
static bool g_initialized = false;
|
|
|
|
if (!g_initialized)
|
|
{
|
|
g_initialized = true;
|
|
PluginManager::RegisterPlugin(GetPluginNameStatic(),
|
|
GetPluginDescriptionStatic(),
|
|
CreateInstance);
|
|
DebugDriverThread::Initialize();
|
|
}
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
// Constructors and destructors.
|
|
|
|
ProcessWindows::ProcessWindows(Target& target, Listener &listener)
|
|
: lldb_private::Process(target, listener)
|
|
{
|
|
}
|
|
|
|
ProcessWindows::~ProcessWindows()
|
|
{
|
|
}
|
|
|
|
void
|
|
ProcessWindows::Terminate()
|
|
{
|
|
DebugDriverThread::Teardown();
|
|
}
|
|
|
|
lldb_private::ConstString
|
|
ProcessWindows::GetPluginNameStatic()
|
|
{
|
|
static ConstString g_name("windows");
|
|
return g_name;
|
|
}
|
|
|
|
const char *
|
|
ProcessWindows::GetPluginDescriptionStatic()
|
|
{
|
|
return "Process plugin for Windows";
|
|
}
|
|
|
|
|
|
bool
|
|
ProcessWindows::UpdateThreadList(ThreadList &old_thread_list, ThreadList &new_thread_list)
|
|
{
|
|
new_thread_list = old_thread_list;
|
|
return new_thread_list.GetSize(false) > 0;
|
|
}
|
|
|
|
Error
|
|
ProcessWindows::DoLaunch(Module *exe_module,
|
|
ProcessLaunchInfo &launch_info)
|
|
{
|
|
Error result;
|
|
HostProcess process;
|
|
SetPrivateState(eStateLaunching);
|
|
if (launch_info.GetFlags().Test(eLaunchFlagDebug))
|
|
{
|
|
// If we're trying to debug this process, we need to use a
|
|
// DebugProcessLauncher so that we can enter a WaitForDebugEvent loop
|
|
// on the same thread that does the CreateProcess.
|
|
DebugProcessLauncher launcher(shared_from_this());
|
|
process = launcher.LaunchProcess(launch_info, result);
|
|
}
|
|
else
|
|
return Host::LaunchProcess(launch_info);
|
|
|
|
if (!result.Success())
|
|
return result;
|
|
|
|
launch_info.SetProcessID(process.GetProcessId());
|
|
SetID(process.GetProcessId());
|
|
return result;
|
|
}
|
|
|
|
Error
|
|
ProcessWindows::DoResume()
|
|
{
|
|
Error error;
|
|
return error;
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
// ProcessInterface protocol.
|
|
|
|
lldb_private::ConstString
|
|
ProcessWindows::GetPluginName()
|
|
{
|
|
return GetPluginNameStatic();
|
|
}
|
|
|
|
uint32_t
|
|
ProcessWindows::GetPluginVersion()
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
void
|
|
ProcessWindows::GetPluginCommandHelp(const char *command, Stream *strm)
|
|
{
|
|
}
|
|
|
|
Error
|
|
ProcessWindows::ExecutePluginCommand(Args &command, Stream *strm)
|
|
{
|
|
return Error(1, eErrorTypeGeneric);
|
|
}
|
|
|
|
Log *
|
|
ProcessWindows::EnablePluginLogging(Stream *strm, Args &command)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
Error
|
|
ProcessWindows::DoDetach(bool keep_stopped)
|
|
{
|
|
Error error;
|
|
error.SetErrorString("Detaching from processes is not currently supported on Windows.");
|
|
return error;
|
|
}
|
|
|
|
Error
|
|
ProcessWindows::DoDestroy()
|
|
{
|
|
Error error;
|
|
error.SetErrorString("Destroying processes is not currently supported on Windows.");
|
|
return error;
|
|
}
|
|
|
|
void
|
|
ProcessWindows::RefreshStateAfterStop()
|
|
{
|
|
}
|
|
|
|
bool
|
|
ProcessWindows::IsAlive()
|
|
{
|
|
return false;
|
|
}
|
|
|
|
size_t
|
|
ProcessWindows::DoReadMemory(lldb::addr_t vm_addr,
|
|
void *buf,
|
|
size_t size,
|
|
Error &error)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
|
|
bool
|
|
ProcessWindows::CanDebug(Target &target, bool plugin_specified_by_name)
|
|
{
|
|
if (plugin_specified_by_name)
|
|
return true;
|
|
|
|
// For now we are just making sure the file exists for a given module
|
|
ModuleSP exe_module_sp(target.GetExecutableModule());
|
|
if (exe_module_sp.get())
|
|
return exe_module_sp->GetFileSpec().Exists();
|
|
return false;
|
|
}
|