Zachary Turner c6a6653ebb Correctly shutdown when DoDestroy is called with an active exception.
Previously if we got a DoDestroy while stopped at a breakpoint, we
would detach and then say the process had exited.  This is completely
wrong, as it resulted in the python script incorrectly assuming that
the process had actually exited and trying to delete the image, when
in fact it had done no such thing.

The fix employed here is that when we get a DoDestroy, we do 3 steps:

1) initiate a termination sequence on the process
2) If we were stopped handling an exception of any kind, mask it and
   let the program resume, causing the program to see the termination
   request and exit on its own.
3) Let the program exit normally, and close all of our handles before
   returning control back to DoDestroy.

This fixes Bug 21722 and Bug 21723.

llvm-svn: 223272
2014-12-03 22:04:18 +00:00

89 lines
3.1 KiB
C++

//===-- DebuggerThread.h ----------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef liblldb_Plugins_Process_Windows_DebuggerThread_H_
#define liblldb_Plugins_Process_Windows_DebuggerThread_H_
#include "ForwardDecl.h"
#include "lldb/Host/HostProcess.h"
#include "lldb/Host/HostThread.h"
#include "lldb/Host/Predicate.h"
#include "lldb/Host/windows/windows.h"
#include <memory>
namespace lldb_private
{
//----------------------------------------------------------------------
// DebuggerThread
//
// Debugs a single process, notifying listeners as appropriate when interesting
// things occur.
//----------------------------------------------------------------------
class DebuggerThread : public std::enable_shared_from_this<DebuggerThread>
{
public:
DebuggerThread(DebugDelegateSP debug_delegate);
virtual ~DebuggerThread();
Error DebugLaunch(const ProcessLaunchInfo &launch_info);
HostProcess
GetProcess() const
{
return m_process;
}
HostThread
GetMainThread() const
{
return m_main_thread;
}
ExceptionRecord *
GetActiveException()
{
return m_active_exception.get();
}
Error StopDebugging(bool terminate);
void ContinueAsyncException(ExceptionResult result);
private:
void FreeProcessHandles();
void DebugLoop();
ExceptionResult HandleExceptionEvent(const EXCEPTION_DEBUG_INFO &info, DWORD thread_id);
DWORD HandleCreateThreadEvent(const CREATE_THREAD_DEBUG_INFO &info, DWORD thread_id);
DWORD HandleCreateProcessEvent(const CREATE_PROCESS_DEBUG_INFO &info, DWORD thread_id);
DWORD HandleExitThreadEvent(const EXIT_THREAD_DEBUG_INFO &info, DWORD thread_id);
DWORD HandleExitProcessEvent(const EXIT_PROCESS_DEBUG_INFO &info, DWORD thread_id);
DWORD HandleLoadDllEvent(const LOAD_DLL_DEBUG_INFO &info, DWORD thread_id);
DWORD HandleUnloadDllEvent(const UNLOAD_DLL_DEBUG_INFO &info, DWORD thread_id);
DWORD HandleODSEvent(const OUTPUT_DEBUG_STRING_INFO &info, DWORD thread_id);
DWORD HandleRipEvent(const RIP_INFO &info, DWORD thread_id);
DebugDelegateSP m_debug_delegate;
HostProcess m_process; // The process being debugged.
HostThread m_main_thread; // The main thread of the inferior.
HANDLE m_image_file; // The image file of the process being debugged.
ExceptionRecordUP m_active_exception; // The current exception waiting to be handled
Predicate<ExceptionResult> m_exception_pred; // A predicate which gets signalled when an exception
// is finished processing and the debug loop can be
// continued.
static lldb::thread_result_t DebuggerThreadRoutine(void *data);
lldb::thread_result_t DebuggerThreadRoutine(const ProcessLaunchInfo &launch_info);
};
}
#endif