diff options
-rw-r--r-- | lldb/source/Plugins/Process/Windows/DebuggerThread.cpp | 18 | ||||
-rw-r--r-- | lldb/source/Plugins/Process/Windows/ExceptionRecord.h | 12 | ||||
-rw-r--r-- | lldb/source/Plugins/Process/Windows/IDebugDelegate.h | 2 | ||||
-rw-r--r-- | lldb/source/Plugins/Process/Windows/LocalDebugDelegate.cpp | 4 | ||||
-rw-r--r-- | lldb/source/Plugins/Process/Windows/LocalDebugDelegate.h | 2 | ||||
-rw-r--r-- | lldb/source/Plugins/Process/Windows/ProcessWindows.cpp | 28 | ||||
-rw-r--r-- | lldb/source/Plugins/Process/Windows/ProcessWindows.h | 2 | ||||
-rw-r--r-- | lldb/source/Target/ThreadList.cpp | 4 | ||||
-rw-r--r-- | lldb/test/functionalities/thread/Makefile | 2 | ||||
-rw-r--r-- | lldb/test/functionalities/thread/TestNumThreads.py | 10 | ||||
-rw-r--r-- | lldb/test/functionalities/thread/main.c | 57 | ||||
-rw-r--r-- | lldb/test/functionalities/thread/main.cpp | 50 |
12 files changed, 90 insertions, 101 deletions
diff --git a/lldb/source/Plugins/Process/Windows/DebuggerThread.cpp b/lldb/source/Plugins/Process/Windows/DebuggerThread.cpp index 0959fc28489..dfc4924f1d0 100644 --- a/lldb/source/Plugins/Process/Windows/DebuggerThread.cpp +++ b/lldb/source/Plugins/Process/Windows/DebuggerThread.cpp @@ -283,9 +283,9 @@ DebuggerThread::HandleExceptionEvent(const EXCEPTION_DEBUG_INFO &info, DWORD thr { bool first_chance = (info.dwFirstChance != 0); - m_active_exception.reset(new ExceptionRecord(info.ExceptionRecord, thread_id)); + m_active_exception.reset(new ExceptionRecord(info.ExceptionRecord)); WINLOG_IFANY(WINDOWS_LOG_EVENT | WINDOWS_LOG_EXCEPTION, - "HandleExceptionEvent encountered %s chance exception 0x%x on thread 0x%x", + "HandleExceptionEvent encountered %s chance exception 0x%x on thread %u", first_chance ? "first" : "second", info.ExceptionRecord.ExceptionCode, thread_id); ExceptionResult result = m_debug_delegate->OnDebugException(first_chance, @@ -308,11 +308,9 @@ DWORD DebuggerThread::HandleCreateThreadEvent(const CREATE_THREAD_DEBUG_INFO &info, DWORD thread_id) { WINLOG_IFANY(WINDOWS_LOG_EVENT|WINDOWS_LOG_THREAD, - "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); + "HandleCreateThreadEvent Thread %u spawned in process %I64u", + m_process.GetProcessId(), thread_id); + return DBG_CONTINUE; } @@ -349,7 +347,7 @@ DebuggerThread::HandleExitThreadEvent(const EXIT_THREAD_DEBUG_INFO &info, DWORD 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; } @@ -360,9 +358,9 @@ DebuggerThread::HandleExitProcessEvent(const EXIT_PROCESS_DEBUG_INFO &info, DWOR "HandleExitProcessEvent process %I64u exited with code %u", m_process.GetProcessId(), info.dwExitCode); - m_debug_delegate->OnExitProcess(info.dwExitCode); - FreeProcessHandles(); + + m_debug_delegate->OnExitProcess(info.dwExitCode); return DBG_CONTINUE; } diff --git a/lldb/source/Plugins/Process/Windows/ExceptionRecord.h b/lldb/source/Plugins/Process/Windows/ExceptionRecord.h index 6532aa78bff..3b29f97d4a0 100644 --- a/lldb/source/Plugins/Process/Windows/ExceptionRecord.h +++ b/lldb/source/Plugins/Process/Windows/ExceptionRecord.h @@ -30,14 +30,13 @@ namespace lldb_private class ExceptionRecord { public: - ExceptionRecord(const EXCEPTION_RECORD &record, lldb::tid_t thread_id) + explicit ExceptionRecord(const EXCEPTION_RECORD &record) { m_code = record.ExceptionCode; m_continuable = (record.ExceptionFlags == 0); if (record.ExceptionRecord) - m_next_exception.reset(new ExceptionRecord(*record.ExceptionRecord, thread_id)); + m_next_exception.reset(new ExceptionRecord(*record.ExceptionRecord)); 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() {} @@ -63,18 +62,11 @@ 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; }; } diff --git a/lldb/source/Plugins/Process/Windows/IDebugDelegate.h b/lldb/source/Plugins/Process/Windows/IDebugDelegate.h index 6d864de7ed4..4efe1932919 100644 --- a/lldb/source/Plugins/Process/Windows/IDebugDelegate.h +++ b/lldb/source/Plugins/Process/Windows/IDebugDelegate.h @@ -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(lldb::tid_t thread_id, uint32_t exit_code) = 0; + virtual void OnExitThread(const HostThread &thread) = 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; diff --git a/lldb/source/Plugins/Process/Windows/LocalDebugDelegate.cpp b/lldb/source/Plugins/Process/Windows/LocalDebugDelegate.cpp index d1fb51b3f08..09bacf05ae9 100644 --- a/lldb/source/Plugins/Process/Windows/LocalDebugDelegate.cpp +++ b/lldb/source/Plugins/Process/Windows/LocalDebugDelegate.cpp @@ -43,9 +43,9 @@ LocalDebugDelegate::OnCreateThread(const HostThread &thread) } void -LocalDebugDelegate::OnExitThread(lldb::tid_t thread_id, uint32_t exit_code) +LocalDebugDelegate::OnExitThread(const HostThread &thread) { - ((ProcessWindows &)*m_process).OnExitThread(thread_id, exit_code); + ((ProcessWindows &)*m_process).OnExitThread(thread); } void diff --git a/lldb/source/Plugins/Process/Windows/LocalDebugDelegate.h b/lldb/source/Plugins/Process/Windows/LocalDebugDelegate.h index a14352d113a..c557fae2bbc 100644 --- a/lldb/source/Plugins/Process/Windows/LocalDebugDelegate.h +++ b/lldb/source/Plugins/Process/Windows/LocalDebugDelegate.h @@ -46,7 +46,7 @@ class LocalDebugDelegate : public IDebugDelegate 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(lldb::tid_t thread_id, uint32_t exit_code) override; + void OnExitThread(const HostThread &thread) 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; diff --git a/lldb/source/Plugins/Process/Windows/ProcessWindows.cpp b/lldb/source/Plugins/Process/Windows/ProcessWindows.cpp index c44dd82cd9f..177ff5da72d 100644 --- a/lldb/source/Plugins/Process/Windows/ProcessWindows.cpp +++ b/lldb/source/Plugins/Process/Windows/ProcessWindows.cpp @@ -13,7 +13,6 @@ // C++ Includes #include <list> #include <mutex> -#include <set> #include <vector> // Other libraries and framework includes @@ -79,7 +78,7 @@ class ProcessWindowsData HANDLE m_initial_stop_event; bool m_initial_stop_received; std::map<lldb::tid_t, HostThread> m_new_threads; - std::set<lldb::tid_t> m_exited_threads; + std::map<lldb::tid_t, HostThread> m_exited_threads; }; } //------------------------------------------------------------------------------ @@ -426,11 +425,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) { @@ -446,8 +445,7 @@ ProcessWindows::RefreshStateAfterStop() if (site->ValidForThisThread(stop_thread.get())) { WINLOG_IFALL(WINDOWS_LOG_BREAKPOINTS | WINDOWS_LOG_EXCEPTION, - "Breakpoint site %d is valid for this thread (0x%I64x), creating stop info.", - site->GetID(), stop_thread->GetID()); + "Breakpoint site %d is valid for this thread, creating stop info.", site->GetID()); stop_info = StopInfo::CreateStopReasonWithBreakpointSiteID( *stop_thread, site->GetID()); @@ -473,8 +471,8 @@ ProcessWindows::RefreshStateAfterStop() { std::string desc; llvm::raw_string_ostream desc_stream(desc); - desc_stream << "Exception " << llvm::format_hex(active_exception->GetExceptionCode(), 8) - << " encountered at address " << llvm::format_hex(pc, 8); + desc_stream << "Exception 0x" << llvm::format_hex(active_exception->GetExceptionCode(), 8) + << " encountered at address 0x" << 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()); @@ -703,7 +701,7 @@ ProcessWindows::OnDebugException(bool first_chance, const ExceptionRecord &recor if (!m_session_data) { WINERR_IFANY(WINDOWS_LOG_EXCEPTION, - "Debugger thread reported exception 0x%x at address 0x%I64x, but there is no session.", + "Debugger thread reported exception 0x%u at address 0x%I64x, but there is no session.", record.GetExceptionCode(), record.GetExceptionAddress()); return ExceptionResult::SendToApplication; } @@ -734,7 +732,7 @@ ProcessWindows::OnDebugException(bool first_chance, const ExceptionRecord &recor break; default: WINLOG_IFANY(WINDOWS_LOG_EXCEPTION, - "Debugger thread reported exception 0x%x at address 0x%I64x (first_chance=%s)", + "Debugger thread reported exception 0x%u 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) @@ -755,22 +753,18 @@ ProcessWindows::OnCreateThread(const HostThread &new_thread) } void -ProcessWindows::OnExitThread(lldb::tid_t thread_id, uint32_t exit_code) +ProcessWindows::OnExitThread(const HostThread &exited_thread) { 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. - auto iter = m_session_data->m_new_threads.find(thread_id); + const HostThreadWindows &wexited_thread = exited_thread.GetNativeThread(); + auto iter = m_session_data->m_new_threads.find(wexited_thread.GetThreadId()); if (iter != m_session_data->m_new_threads.end()) m_session_data->m_new_threads.erase(iter); else - m_session_data->m_exited_threads.insert(thread_id); + m_session_data->m_exited_threads[wexited_thread.GetThreadId()] = exited_thread; } void diff --git a/lldb/source/Plugins/Process/Windows/ProcessWindows.h b/lldb/source/Plugins/Process/Windows/ProcessWindows.h index b370a4007a2..180ecaec9cb 100644 --- a/lldb/source/Plugins/Process/Windows/ProcessWindows.h +++ b/lldb/source/Plugins/Process/Windows/ProcessWindows.h @@ -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(lldb::tid_t thread_id, uint32_t exit_code) override; + void OnExitThread(const lldb_private::HostThread &thread) 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; diff --git a/lldb/source/Target/ThreadList.cpp b/lldb/source/Target/ThreadList.cpp index d2d7abe3699..b175859f2f2 100644 --- a/lldb/source/Target/ThreadList.cpp +++ b/lldb/source/Target/ThreadList.cpp @@ -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 - // they 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 + // then 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; diff --git a/lldb/test/functionalities/thread/Makefile b/lldb/test/functionalities/thread/Makefile index 644e2971a2c..dcbe9b37437 100644 --- a/lldb/test/functionalities/thread/Makefile +++ b/lldb/test/functionalities/thread/Makefile @@ -1,5 +1,5 @@ LEVEL = ../../make -CXX_SOURCES := main.cpp +C_SOURCES := main.c ENABLE_THREADS := YES include $(LEVEL)/Makefile.rules diff --git a/lldb/test/functionalities/thread/TestNumThreads.py b/lldb/test/functionalities/thread/TestNumThreads.py index 824956be8d4..d2156399d61 100644 --- a/lldb/test/functionalities/thread/TestNumThreads.py +++ b/lldb/test/functionalities/thread/TestNumThreads.py @@ -29,7 +29,7 @@ class NumberOfThreadsTestCase(TestBase): # Call super's setUp(). TestBase.setUp(self) # Find the line number to break inside main(). - self.line = line_number('main.cpp', '// Set break point at this line.') + self.line = line_number('main.c', '// Set break point at this line.') def number_of_threads_test(self): """Test number of threads.""" @@ -37,11 +37,11 @@ class NumberOfThreadsTestCase(TestBase): self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) # This should create a breakpoint with 1 location. - lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line, num_expected_locations=1) + lldbutil.run_break_set_by_file_and_line (self, "main.c", self.line, num_expected_locations=1) # The breakpoint list should show 3 locations. self.expect("breakpoint list -f", "Breakpoint location shown correctly", - substrs = ["1: file = 'main.cpp', line = %d, locations = 1" % self.line]) + substrs = ["1: file = 'main.c', line = %d, locations = 1" % self.line]) # Run the program. self.runCmd("run", RUN_SUCCEEDED) @@ -57,9 +57,7 @@ class NumberOfThreadsTestCase(TestBase): # Get the number of threads num_threads = process.GetNumThreads() - # Using std::thread may involve extra threads, so we assert that there are - # at least 4 rather than exactly 4. - self.assertTrue(num_threads >= 4, 'Number of expected threads and actual threads do not match.') + self.assertTrue(num_threads == 4, 'Number of expected threads and actual threads do not match.') if __name__ == '__main__': import atexit diff --git a/lldb/test/functionalities/thread/main.c b/lldb/test/functionalities/thread/main.c new file mode 100644 index 00000000000..b1fec81c11b --- /dev/null +++ b/lldb/test/functionalities/thread/main.c @@ -0,0 +1,57 @@ +#include <pthread.h> + +pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; +pthread_cond_t cond = PTHREAD_COND_INITIALIZER; + +void * +thread3 (void *input) +{ + pthread_mutex_lock(&mutex); + pthread_cond_signal(&cond); // Set break point at this line. + pthread_mutex_unlock(&mutex); + return NULL; +} + +void * +thread2 (void *input) +{ + pthread_mutex_lock(&mutex); + pthread_cond_signal(&cond); + pthread_cond_wait(&cond, &mutex); + pthread_mutex_unlock(&mutex); + return NULL; +} + +void * +thread1 (void *input) +{ + pthread_t thread_2; + pthread_create (&thread_2, NULL, thread2, NULL); + + pthread_join(thread_2, NULL); + + return NULL; +} + +int main () +{ + pthread_t thread_1; + pthread_t thread_3; + + pthread_mutex_lock (&mutex); + + pthread_create (&thread_1, NULL, thread1, NULL); + + pthread_cond_wait (&cond, &mutex); + + pthread_create (&thread_3, NULL, thread3, NULL); + + pthread_cond_wait (&cond, &mutex); + + pthread_mutex_unlock (&mutex); + + pthread_join (thread_1, NULL); + pthread_join (thread_3, NULL); + + return 0; +} diff --git a/lldb/test/functionalities/thread/main.cpp b/lldb/test/functionalities/thread/main.cpp deleted file mode 100644 index 6a0ea4e0d11..00000000000 --- a/lldb/test/functionalities/thread/main.cpp +++ /dev/null @@ -1,50 +0,0 @@ -#include <condition_variable> -#include <mutex> -#include <thread> - -std::mutex mutex; -std::condition_variable cond; - -void * -thread3(void *input) -{ - std::unique_lock<std::mutex> lock(mutex); - cond.notify_all(); // Set break point at this line. - return NULL; -} - -void * -thread2(void *input) -{ - std::unique_lock<std::mutex> lock(mutex); - cond.notify_all(); - cond.wait(lock); - return NULL; -} - -void * -thread1(void *input) -{ - std::thread thread_2(thread2, nullptr); - thread_2.join(); - - return NULL; -} - -int main() -{ - std::unique_lock<std::mutex> lock(mutex); - - std::thread thread_1(thread1, nullptr); - cond.wait(lock); - - std::thread thread_3(thread3, nullptr); - cond.wait(lock); - - lock.unlock(); - - thread_1.join(); - thread_3.join(); - - return 0; -} |