[Lldb-commits] [lldb] r237637 - Enable debugging of multithreaded programs on Windows.
Adrian McCarthy
amccarth at google.com
Mon May 18 16:24:32 PDT 2015
Author: amccarth
Date: Mon May 18 18:24:32 2015
New Revision: 237637
URL: http://llvm.org/viewvc/llvm-project?rev=237637&view=rev
Log:
Enable debugging of multithreaded programs on Windows.
Modified:
lldb/trunk/source/Plugins/Process/Windows/DebuggerThread.cpp
lldb/trunk/source/Plugins/Process/Windows/ExceptionRecord.h
lldb/trunk/source/Plugins/Process/Windows/IDebugDelegate.h
lldb/trunk/source/Plugins/Process/Windows/LocalDebugDelegate.cpp
lldb/trunk/source/Plugins/Process/Windows/LocalDebugDelegate.h
lldb/trunk/source/Plugins/Process/Windows/ProcessWindows.cpp
lldb/trunk/source/Plugins/Process/Windows/ProcessWindows.h
lldb/trunk/source/Target/ThreadList.cpp
Modified: lldb/trunk/source/Plugins/Process/Windows/DebuggerThread.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Windows/DebuggerThread.cpp?rev=237637&r1=237636&r2=237637&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Windows/DebuggerThread.cpp (original)
+++ lldb/trunk/source/Plugins/Process/Windows/DebuggerThread.cpp Mon May 18 18:24:32 2015
@@ -283,9 +283,9 @@ DebuggerThread::HandleExceptionEvent(con
{
bool first_chance = (info.dwFirstChance != 0);
- m_active_exception.reset(new ExceptionRecord(info.ExceptionRecord));
+ m_active_exception.reset(new ExceptionRecord(info.ExceptionRecord, thread_id));
WINLOG_IFANY(WINDOWS_LOG_EVENT | WINDOWS_LOG_EXCEPTION,
- "HandleExceptionEvent encountered %s chance exception 0x%x on thread %u",
+ "HandleExceptionEvent encountered %s chance exception 0x%x on thread 0x%x",
first_chance ? "first" : "second", info.ExceptionRecord.ExceptionCode, thread_id);
ExceptionResult result = m_debug_delegate->OnDebugException(first_chance,
@@ -308,9 +308,11 @@ DWORD
DebuggerThread::HandleCreateThreadEvent(const CREATE_THREAD_DEBUG_INFO &info, DWORD thread_id)
{
WINLOG_IFANY(WINDOWS_LOG_EVENT|WINDOWS_LOG_THREAD,
- "HandleCreateThreadEvent Thread %u spawned in process %I64u",
- m_process.GetProcessId(), thread_id);
-
+ "HandleCreateThreadEvent Thread 0x%x spawned in process %I64u",
+ thread_id, m_process.GetProcessId());
+ HostThread thread(info.hThread);
+ thread.GetNativeThread().SetOwnsHandle(false);
+ m_debug_delegate->OnCreateThread(thread);
return DBG_CONTINUE;
}
@@ -347,7 +349,7 @@ DebuggerThread::HandleExitThreadEvent(co
WINLOG_IFANY(WINDOWS_LOG_EVENT|WINDOWS_LOG_THREAD,
"HandleExitThreadEvent Thread %u exited with code %u in process %I64u",
thread_id, info.dwExitCode, m_process.GetProcessId());
-
+ m_debug_delegate->OnExitThread(thread_id, info.dwExitCode);
return DBG_CONTINUE;
}
@@ -358,9 +360,9 @@ DebuggerThread::HandleExitProcessEvent(c
"HandleExitProcessEvent process %I64u exited with code %u",
m_process.GetProcessId(), info.dwExitCode);
- FreeProcessHandles();
-
m_debug_delegate->OnExitProcess(info.dwExitCode);
+
+ FreeProcessHandles();
return DBG_CONTINUE;
}
Modified: lldb/trunk/source/Plugins/Process/Windows/ExceptionRecord.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Windows/ExceptionRecord.h?rev=237637&r1=237636&r2=237637&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Windows/ExceptionRecord.h (original)
+++ lldb/trunk/source/Plugins/Process/Windows/ExceptionRecord.h Mon May 18 18:24:32 2015
@@ -30,13 +30,14 @@ namespace lldb_private
class ExceptionRecord
{
public:
- explicit ExceptionRecord(const EXCEPTION_RECORD &record)
+ ExceptionRecord(const EXCEPTION_RECORD &record, lldb::tid_t thread_id)
{
m_code = record.ExceptionCode;
m_continuable = (record.ExceptionFlags == 0);
if (record.ExceptionRecord)
- m_next_exception.reset(new ExceptionRecord(*record.ExceptionRecord));
+ m_next_exception.reset(new ExceptionRecord(*record.ExceptionRecord, thread_id));
m_exception_addr = reinterpret_cast<lldb::addr_t>(record.ExceptionAddress);
+ m_thread_id = thread_id;
m_arguments.assign(record.ExceptionInformation, record.ExceptionInformation + record.NumberParameters);
}
virtual ~ExceptionRecord() {}
@@ -62,11 +63,18 @@ class ExceptionRecord
return m_exception_addr;
}
+ lldb::tid_t
+ GetThreadID() const
+ {
+ return m_thread_id;
+ }
+
private:
DWORD m_code;
bool m_continuable;
std::shared_ptr<ExceptionRecord> m_next_exception;
lldb::addr_t m_exception_addr;
+ lldb::tid_t m_thread_id;
std::vector<ULONG_PTR> m_arguments;
};
}
Modified: lldb/trunk/source/Plugins/Process/Windows/IDebugDelegate.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Windows/IDebugDelegate.h?rev=237637&r1=237636&r2=237637&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Windows/IDebugDelegate.h (original)
+++ lldb/trunk/source/Plugins/Process/Windows/IDebugDelegate.h Mon May 18 18:24:32 2015
@@ -35,7 +35,7 @@ class IDebugDelegate
virtual void OnDebuggerConnected(lldb::addr_t image_base) = 0;
virtual ExceptionResult OnDebugException(bool first_chance, const ExceptionRecord &record) = 0;
virtual void OnCreateThread(const HostThread &thread) = 0;
- virtual void OnExitThread(const HostThread &thread) = 0;
+ virtual void OnExitThread(lldb::tid_t thread_id, uint32_t exit_code) = 0;
virtual void OnLoadDll(const ModuleSpec &module_spec, lldb::addr_t module_addr) = 0;
virtual void OnUnloadDll(lldb::addr_t module_addr) = 0;
virtual void OnDebugString(const std::string &string) = 0;
Modified: lldb/trunk/source/Plugins/Process/Windows/LocalDebugDelegate.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Windows/LocalDebugDelegate.cpp?rev=237637&r1=237636&r2=237637&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Windows/LocalDebugDelegate.cpp (original)
+++ lldb/trunk/source/Plugins/Process/Windows/LocalDebugDelegate.cpp Mon May 18 18:24:32 2015
@@ -43,9 +43,9 @@ LocalDebugDelegate::OnCreateThread(const
}
void
-LocalDebugDelegate::OnExitThread(const HostThread &thread)
+LocalDebugDelegate::OnExitThread(lldb::tid_t thread_id, uint32_t exit_code)
{
- ((ProcessWindows &)*m_process).OnExitThread(thread);
+ ((ProcessWindows &)*m_process).OnExitThread(thread_id, exit_code);
}
void
Modified: lldb/trunk/source/Plugins/Process/Windows/LocalDebugDelegate.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Windows/LocalDebugDelegate.h?rev=237637&r1=237636&r2=237637&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Windows/LocalDebugDelegate.h (original)
+++ lldb/trunk/source/Plugins/Process/Windows/LocalDebugDelegate.h Mon May 18 18:24:32 2015
@@ -46,7 +46,7 @@ class LocalDebugDelegate : public IDebug
void OnDebuggerConnected(lldb::addr_t image_base) override;
ExceptionResult OnDebugException(bool first_chance, const ExceptionRecord &record) override;
void OnCreateThread(const HostThread &thread) override;
- void OnExitThread(const HostThread &thread) override;
+ void OnExitThread(lldb::tid_t thread_id, uint32_t exit_code) override;
void OnLoadDll(const lldb_private::ModuleSpec &module_spec, lldb::addr_t module_addr) override;
void OnUnloadDll(lldb::addr_t module_addr) override;
void OnDebugString(const std::string &message) override;
Modified: lldb/trunk/source/Plugins/Process/Windows/ProcessWindows.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Windows/ProcessWindows.cpp?rev=237637&r1=237636&r2=237637&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Windows/ProcessWindows.cpp (original)
+++ lldb/trunk/source/Plugins/Process/Windows/ProcessWindows.cpp Mon May 18 18:24:32 2015
@@ -13,6 +13,7 @@
// C++ Includes
#include <list>
#include <mutex>
+#include <set>
#include <vector>
// Other libraries and framework includes
@@ -78,7 +79,7 @@ class ProcessWindowsData
HANDLE m_initial_stop_event;
bool m_initial_stop_received;
std::map<lldb::tid_t, HostThread> m_new_threads;
- std::map<lldb::tid_t, HostThread> m_exited_threads;
+ std::set<lldb::tid_t> m_exited_threads;
};
}
//------------------------------------------------------------------------------
@@ -425,11 +426,11 @@ ProcessWindows::RefreshStateAfterStop()
}
StopInfoSP stop_info;
+ m_thread_list.SetSelectedThreadByID(active_exception->GetThreadID());
ThreadSP stop_thread = m_thread_list.GetSelectedThread();
RegisterContextSP register_context = stop_thread->GetRegisterContext();
// The current EIP is AFTER the BP opcode, which is one byte.
- // TODO(zturner): Can't we just use active_exception->GetExceptionAddress()?
uint64_t pc = register_context->GetPC() - 1;
if (active_exception->GetExceptionCode() == EXCEPTION_BREAKPOINT)
{
@@ -445,7 +446,8 @@ ProcessWindows::RefreshStateAfterStop()
if (site->ValidForThisThread(stop_thread.get()))
{
WINLOG_IFALL(WINDOWS_LOG_BREAKPOINTS | WINDOWS_LOG_EXCEPTION,
- "Breakpoint site %d is valid for this thread, creating stop info.", site->GetID());
+ "Breakpoint site %d is valid for this thread (0x%I64x), creating stop info.",
+ site->GetID(), stop_thread->GetID());
stop_info = StopInfo::CreateStopReasonWithBreakpointSiteID(
*stop_thread, site->GetID());
@@ -471,8 +473,8 @@ ProcessWindows::RefreshStateAfterStop()
{
std::string desc;
llvm::raw_string_ostream desc_stream(desc);
- desc_stream << "Exception 0x" << llvm::format_hex(active_exception->GetExceptionCode(), 8)
- << " encountered at address 0x" << llvm::format_hex(pc, 8);
+ desc_stream << "Exception " << llvm::format_hex(active_exception->GetExceptionCode(), 8)
+ << " encountered at address " << llvm::format_hex(pc, 8);
stop_info = StopInfo::CreateStopReasonWithException(*stop_thread, desc_stream.str().c_str());
stop_thread->SetStopInfo(stop_info);
WINLOG_IFALL(WINDOWS_LOG_EXCEPTION, desc_stream.str().c_str());
@@ -701,7 +703,7 @@ ProcessWindows::OnDebugException(bool fi
if (!m_session_data)
{
WINERR_IFANY(WINDOWS_LOG_EXCEPTION,
- "Debugger thread reported exception 0x%u at address 0x%I64x, but there is no session.",
+ "Debugger thread reported exception 0x%x at address 0x%I64x, but there is no session.",
record.GetExceptionCode(), record.GetExceptionAddress());
return ExceptionResult::SendToApplication;
}
@@ -732,7 +734,7 @@ ProcessWindows::OnDebugException(bool fi
break;
default:
WINLOG_IFANY(WINDOWS_LOG_EXCEPTION,
- "Debugger thread reported exception 0x%u at address 0x%I64x (first_chance=%s)",
+ "Debugger thread reported exception 0x%x at address 0x%I64x (first_chance=%s)",
record.GetExceptionCode(), record.GetExceptionAddress(), BOOL_STR(first_chance));
// For non-breakpoints, give the application a chance to handle the exception first.
if (first_chance)
@@ -753,18 +755,22 @@ ProcessWindows::OnCreateThread(const Hos
}
void
-ProcessWindows::OnExitThread(const HostThread &exited_thread)
+ProcessWindows::OnExitThread(lldb::tid_t thread_id, uint32_t exit_code)
{
llvm::sys::ScopedLock lock(m_mutex);
+ // On a forced termination, we may get exit thread events after the session
+ // data has been cleaned up.
+ if (!m_session_data)
+ return;
+
// A thread may have started and exited before the debugger stopped allowing a refresh.
// Just remove it from the new threads list in that case.
- const HostThreadWindows &wexited_thread = exited_thread.GetNativeThread();
- auto iter = m_session_data->m_new_threads.find(wexited_thread.GetThreadId());
+ auto iter = m_session_data->m_new_threads.find(thread_id);
if (iter != m_session_data->m_new_threads.end())
m_session_data->m_new_threads.erase(iter);
else
- m_session_data->m_exited_threads[wexited_thread.GetThreadId()] = exited_thread;
+ m_session_data->m_exited_threads.insert(thread_id);
}
void
Modified: lldb/trunk/source/Plugins/Process/Windows/ProcessWindows.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Windows/ProcessWindows.h?rev=237637&r1=237636&r2=237637&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Windows/ProcessWindows.h (original)
+++ lldb/trunk/source/Plugins/Process/Windows/ProcessWindows.h Mon May 18 18:24:32 2015
@@ -109,7 +109,7 @@ public:
void OnDebuggerConnected(lldb::addr_t image_base) override;
ExceptionResult OnDebugException(bool first_chance, const lldb_private::ExceptionRecord &record) override;
void OnCreateThread(const lldb_private::HostThread &thread) override;
- void OnExitThread(const lldb_private::HostThread &thread) override;
+ void OnExitThread(lldb::tid_t thread_id, uint32_t exit_code) override;
void OnLoadDll(const lldb_private::ModuleSpec &module_spec, lldb::addr_t module_addr) override;
void OnUnloadDll(lldb::addr_t module_addr) override;
void OnDebugString(const std::string &string) override;
Modified: lldb/trunk/source/Target/ThreadList.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/ThreadList.cpp?rev=237637&r1=237636&r2=237637&view=diff
==============================================================================
--- lldb/trunk/source/Target/ThreadList.cpp (original)
+++ lldb/trunk/source/Target/ThreadList.cpp Mon May 18 18:24:32 2015
@@ -247,8 +247,8 @@ ThreadList::ShouldStop (Event *event_ptr
// figuring out whether the thread plan conditions are met. So we don't want
// to keep the ThreadList locked the whole time we are doing this.
// FIXME: It is possible that running code could cause new threads
- // to be created. If that happens we will miss asking them whether
- // then should stop. This is not a big deal, since we haven't had
+ // to be created. If that happens, we will miss asking them whether
+ // they should stop. This is not a big deal since we haven't had
// a chance to hang any interesting operations on those threads yet.
collection threads_copy;
More information about the lldb-commits
mailing list