<div dir="ltr">Weird, I didn't get any buildbot notification of the failure.<div><br></div><div>Yes, we can roll it back.  I've not done that before, so I'll have to learn the process.</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Thu, May 14, 2015 at 6:25 PM, Vince Harron <span dir="ltr"><<a href="mailto:vince@nethacker.com" target="_blank">vince@nethacker.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">There is a new test failure in Linux after this change.  Can we revert to green and help you figure it out?<div><br></div><div><div>======================================================================</div><div>FAIL: test_with_dwarf (TestNumThreads.NumberOfThreadsTestCase)</div><div>   Test number of threads.</div><div>----------------------------------------------------------------------</div><div>Traceback (most recent call last):</div><div>  File "/usr/local/google/home/vharron/bisect/tmp/llvm/tools/lldb/test/lldbtest.py", line 499, in wrapper</div><div>    return func(self, *args, **kwargs)</div><div>  File "/usr/local/google/home/vharron/bisect/tmp/llvm/tools/lldb/test/functionalities/thread/TestNumThreads.py", line 26, in test_with_dwarf</div><div>    self.number_of_threads_test()</div><div>  File "/usr/local/google/home/vharron/bisect/tmp/llvm/tools/lldb/test/functionalities/thread/TestNumThreads.py", line 51, in number_of_threads_test</div><div>    substrs = ["stop reason = breakpoint 1."])</div><div>  File "/usr/local/google/home/vharron/bisect/tmp/llvm/tools/lldb/test/lldbtest.py", line 2344, in expect</div><div>    msg if msg else EXP_MSG(str, exe))</div><div>AssertionError: False is not True : Process should be stopped due to breakpoint</div><div>Config=i386-gcc</div><div>----------------------------------------------------------------------</div></div><div><br></div><div><br></div><div><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Thu, May 14, 2015 at 2:07 PM, Adrian McCarthy <span dir="ltr"><<a href="mailto:amccarth@google.com" target="_blank">amccarth@google.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: amccarth<br>
Date: Thu May 14 16:07:59 2015<br>
New Revision: 237392<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=237392&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=237392&view=rev</a><br>
Log:<br>
Enable multithreaded debugging on Windows.<br>
<br>
Added:<br>
    lldb/trunk/test/functionalities/thread/main.cpp<br>
Removed:<br>
    lldb/trunk/test/functionalities/thread/main.c<br>
Modified:<br>
    lldb/trunk/source/Plugins/Process/Windows/DebuggerThread.cpp<br>
    lldb/trunk/source/Plugins/Process/Windows/ExceptionRecord.h<br>
    lldb/trunk/source/Plugins/Process/Windows/IDebugDelegate.h<br>
    lldb/trunk/source/Plugins/Process/Windows/LocalDebugDelegate.cpp<br>
    lldb/trunk/source/Plugins/Process/Windows/LocalDebugDelegate.h<br>
    lldb/trunk/source/Plugins/Process/Windows/ProcessWindows.cpp<br>
    lldb/trunk/source/Plugins/Process/Windows/ProcessWindows.h<br>
    lldb/trunk/source/Target/ThreadList.cpp<br>
    lldb/trunk/test/functionalities/thread/Makefile<br>
    lldb/trunk/test/functionalities/thread/TestNumThreads.py<br>
<br>
Modified: lldb/trunk/source/Plugins/Process/Windows/DebuggerThread.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Windows/DebuggerThread.cpp?rev=237392&r1=237391&r2=237392&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Windows/DebuggerThread.cpp?rev=237392&r1=237391&r2=237392&view=diff</a><br>
==============================================================================<br>
--- lldb/trunk/source/Plugins/Process/Windows/DebuggerThread.cpp (original)<br>
+++ lldb/trunk/source/Plugins/Process/Windows/DebuggerThread.cpp Thu May 14 16:07:59 2015<br>
@@ -283,9 +283,9 @@ DebuggerThread::HandleExceptionEvent(con<br>
 {<br>
     bool first_chance = (info.dwFirstChance != 0);<br>
<br>
-    m_active_exception.reset(new ExceptionRecord(info.ExceptionRecord));<br>
+    m_active_exception.reset(new ExceptionRecord(info.ExceptionRecord, thread_id));<br>
     WINLOG_IFANY(WINDOWS_LOG_EVENT | WINDOWS_LOG_EXCEPTION,<br>
-                 "HandleExceptionEvent encountered %s chance exception 0x%x on thread %u",<br>
+                 "HandleExceptionEvent encountered %s chance exception 0x%x on thread 0x%x",<br>
                  first_chance ? "first" : "second", info.ExceptionRecord.ExceptionCode, thread_id);<br>
<br>
     ExceptionResult result = m_debug_delegate->OnDebugException(first_chance,<br>
@@ -308,9 +308,11 @@ DWORD<br>
 DebuggerThread::HandleCreateThreadEvent(const CREATE_THREAD_DEBUG_INFO &info, DWORD thread_id)<br>
 {<br>
     WINLOG_IFANY(WINDOWS_LOG_EVENT|WINDOWS_LOG_THREAD,<br>
-        "HandleCreateThreadEvent Thread %u spawned in process %I64u",<br>
-        m_process.GetProcessId(), thread_id);<br>
-<br>
+        "HandleCreateThreadEvent Thread 0x%x spawned in process %I64u",<br>
+        thread_id, m_process.GetProcessId());<br>
+    HostThread thread(info.hThread);<br>
+    thread.GetNativeThread().SetOwnsHandle(false);<br>
+    m_debug_delegate->OnCreateThread(thread);<br>
     return DBG_CONTINUE;<br>
 }<br>
<br>
@@ -347,7 +349,7 @@ DebuggerThread::HandleExitThreadEvent(co<br>
     WINLOG_IFANY(WINDOWS_LOG_EVENT|WINDOWS_LOG_THREAD,<br>
         "HandleExitThreadEvent Thread %u exited with code %u in process %I64u",<br>
         thread_id, info.dwExitCode, m_process.GetProcessId());<br>
-<br>
+    m_debug_delegate->OnExitThread(thread_id, info.dwExitCode);<br>
     return DBG_CONTINUE;<br>
 }<br>
<br>
@@ -358,9 +360,9 @@ DebuggerThread::HandleExitProcessEvent(c<br>
         "HandleExitProcessEvent process %I64u exited with code %u",<br>
         m_process.GetProcessId(), info.dwExitCode);<br>
<br>
-    FreeProcessHandles();<br>
-<br>
     m_debug_delegate->OnExitProcess(info.dwExitCode);<br>
+<br>
+    FreeProcessHandles();<br>
     return DBG_CONTINUE;<br>
 }<br>
<br>
<br>
Modified: lldb/trunk/source/Plugins/Process/Windows/ExceptionRecord.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Windows/ExceptionRecord.h?rev=237392&r1=237391&r2=237392&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Windows/ExceptionRecord.h?rev=237392&r1=237391&r2=237392&view=diff</a><br>
==============================================================================<br>
--- lldb/trunk/source/Plugins/Process/Windows/ExceptionRecord.h (original)<br>
+++ lldb/trunk/source/Plugins/Process/Windows/ExceptionRecord.h Thu May 14 16:07:59 2015<br>
@@ -30,13 +30,14 @@ namespace lldb_private<br>
 class ExceptionRecord<br>
 {<br>
   public:<br>
-    explicit ExceptionRecord(const EXCEPTION_RECORD &record)<br>
+    ExceptionRecord(const EXCEPTION_RECORD &record, lldb::tid_t thread_id)<br>
     {<br>
         m_code = record.ExceptionCode;<br>
         m_continuable = (record.ExceptionFlags == 0);<br>
         if (record.ExceptionRecord)<br>
-            m_next_exception.reset(new ExceptionRecord(*record.ExceptionRecord));<br>
+            m_next_exception.reset(new ExceptionRecord(*record.ExceptionRecord, thread_id));<br>
         m_exception_addr = reinterpret_cast<lldb::addr_t>(record.ExceptionAddress);<br>
+        m_thread_id = thread_id;<br>
         m_arguments.assign(record.ExceptionInformation, record.ExceptionInformation + record.NumberParameters);<br>
     }<br>
     virtual ~ExceptionRecord() {}<br>
@@ -62,11 +63,18 @@ class ExceptionRecord<br>
         return m_exception_addr;<br>
     }<br>
<br>
+    lldb::tid_t<br>
+    GetThreadID() const<br>
+    {<br>
+        return m_thread_id;<br>
+    }<br>
+<br>
   private:<br>
     DWORD m_code;<br>
     bool m_continuable;<br>
     std::shared_ptr<ExceptionRecord> m_next_exception;<br>
     lldb::addr_t m_exception_addr;<br>
+    lldb::tid_t m_thread_id;<br>
     std::vector<ULONG_PTR> m_arguments;<br>
 };<br>
 }<br>
<br>
Modified: lldb/trunk/source/Plugins/Process/Windows/IDebugDelegate.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Windows/IDebugDelegate.h?rev=237392&r1=237391&r2=237392&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Windows/IDebugDelegate.h?rev=237392&r1=237391&r2=237392&view=diff</a><br>
==============================================================================<br>
--- lldb/trunk/source/Plugins/Process/Windows/IDebugDelegate.h (original)<br>
+++ lldb/trunk/source/Plugins/Process/Windows/IDebugDelegate.h Thu May 14 16:07:59 2015<br>
@@ -35,7 +35,7 @@ class IDebugDelegate<br>
     virtual void OnDebuggerConnected(lldb::addr_t image_base) = 0;<br>
     virtual ExceptionResult OnDebugException(bool first_chance, const ExceptionRecord &record) = 0;<br>
     virtual void OnCreateThread(const HostThread &thread) = 0;<br>
-    virtual void OnExitThread(const HostThread &thread) = 0;<br>
+    virtual void OnExitThread(lldb::tid_t thread_id, uint32_t exit_code) = 0;<br>
     virtual void OnLoadDll(const ModuleSpec &module_spec, lldb::addr_t module_addr) = 0;<br>
     virtual void OnUnloadDll(lldb::addr_t module_addr) = 0;<br>
     virtual void OnDebugString(const std::string &string) = 0;<br>
<br>
Modified: lldb/trunk/source/Plugins/Process/Windows/LocalDebugDelegate.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Windows/LocalDebugDelegate.cpp?rev=237392&r1=237391&r2=237392&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Windows/LocalDebugDelegate.cpp?rev=237392&r1=237391&r2=237392&view=diff</a><br>
==============================================================================<br>
--- lldb/trunk/source/Plugins/Process/Windows/LocalDebugDelegate.cpp (original)<br>
+++ lldb/trunk/source/Plugins/Process/Windows/LocalDebugDelegate.cpp Thu May 14 16:07:59 2015<br>
@@ -43,9 +43,9 @@ LocalDebugDelegate::OnCreateThread(const<br>
 }<br>
<br>
 void<br>
-LocalDebugDelegate::OnExitThread(const HostThread &thread)<br>
+LocalDebugDelegate::OnExitThread(lldb::tid_t thread_id, uint32_t exit_code)<br>
 {<br>
-    ((ProcessWindows &)*m_process).OnExitThread(thread);<br>
+    ((ProcessWindows &)*m_process).OnExitThread(thread_id, exit_code);<br>
 }<br>
<br>
 void<br>
<br>
Modified: lldb/trunk/source/Plugins/Process/Windows/LocalDebugDelegate.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Windows/LocalDebugDelegate.h?rev=237392&r1=237391&r2=237392&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Windows/LocalDebugDelegate.h?rev=237392&r1=237391&r2=237392&view=diff</a><br>
==============================================================================<br>
--- lldb/trunk/source/Plugins/Process/Windows/LocalDebugDelegate.h (original)<br>
+++ lldb/trunk/source/Plugins/Process/Windows/LocalDebugDelegate.h Thu May 14 16:07:59 2015<br>
@@ -46,7 +46,7 @@ class LocalDebugDelegate : public IDebug<br>
     void OnDebuggerConnected(lldb::addr_t image_base) override;<br>
     ExceptionResult OnDebugException(bool first_chance, const ExceptionRecord &record) override;<br>
     void OnCreateThread(const HostThread &thread) override;<br>
-    void OnExitThread(const HostThread &thread) override;<br>
+    void OnExitThread(lldb::tid_t thread_id, uint32_t exit_code) override;<br>
     void OnLoadDll(const lldb_private::ModuleSpec &module_spec, lldb::addr_t module_addr) override;<br>
     void OnUnloadDll(lldb::addr_t module_addr) override;<br>
     void OnDebugString(const std::string &message) override;<br>
<br>
Modified: lldb/trunk/source/Plugins/Process/Windows/ProcessWindows.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Windows/ProcessWindows.cpp?rev=237392&r1=237391&r2=237392&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Windows/ProcessWindows.cpp?rev=237392&r1=237391&r2=237392&view=diff</a><br>
==============================================================================<br>
--- lldb/trunk/source/Plugins/Process/Windows/ProcessWindows.cpp (original)<br>
+++ lldb/trunk/source/Plugins/Process/Windows/ProcessWindows.cpp Thu May 14 16:07:59 2015<br>
@@ -13,6 +13,7 @@<br>
 // C++ Includes<br>
 #include <list><br>
 #include <mutex><br>
+#include <set><br>
 #include <vector><br>
<br>
 // Other libraries and framework includes<br>
@@ -78,7 +79,7 @@ class ProcessWindowsData<br>
     HANDLE m_initial_stop_event;<br>
     bool m_initial_stop_received;<br>
     std::map<lldb::tid_t, HostThread> m_new_threads;<br>
-    std::map<lldb::tid_t, HostThread> m_exited_threads;<br>
+    std::set<lldb::tid_t> m_exited_threads;<br>
 };<br>
 }<br>
 //------------------------------------------------------------------------------<br>
@@ -425,11 +426,11 @@ ProcessWindows::RefreshStateAfterStop()<br>
     }<br>
<br>
     StopInfoSP stop_info;<br>
+    m_thread_list.SetSelectedThreadByID(active_exception->GetThreadID());<br>
     ThreadSP stop_thread = m_thread_list.GetSelectedThread();<br>
     RegisterContextSP register_context = stop_thread->GetRegisterContext();<br>
<br>
     // The current EIP is AFTER the BP opcode, which is one byte.<br>
-    // TODO(zturner): Can't we just use active_exception->GetExceptionAddress()?<br>
     uint64_t pc = register_context->GetPC() - 1;<br>
     if (active_exception->GetExceptionCode() == EXCEPTION_BREAKPOINT)<br>
     {<br>
@@ -445,7 +446,8 @@ ProcessWindows::RefreshStateAfterStop()<br>
             if (site->ValidForThisThread(stop_thread.get()))<br>
             {<br>
                 WINLOG_IFALL(WINDOWS_LOG_BREAKPOINTS | WINDOWS_LOG_EXCEPTION,<br>
-                             "Breakpoint site %d is valid for this thread, creating stop info.", site->GetID());<br>
+                             "Breakpoint site %d is valid for this thread (0x%I64x), creating stop info.",<br>
+                             site->GetID(), stop_thread->GetID());<br>
<br>
                 stop_info = StopInfo::CreateStopReasonWithBreakpointSiteID(<br>
                     *stop_thread, site->GetID());<br>
@@ -471,8 +473,8 @@ ProcessWindows::RefreshStateAfterStop()<br>
     {<br>
         std::string desc;<br>
         llvm::raw_string_ostream desc_stream(desc);<br>
-        desc_stream << "Exception 0x" << llvm::format_hex(active_exception->GetExceptionCode(), 8)<br>
-                    << " encountered at address 0x" << llvm::format_hex(pc, 8);<br>
+        desc_stream << "Exception " << llvm::format_hex(active_exception->GetExceptionCode(), 8)<br>
+                    << " encountered at address " << llvm::format_hex(pc, 8);<br>
         stop_info = StopInfo::CreateStopReasonWithException(*stop_thread, desc_stream.str().c_str());<br>
         stop_thread->SetStopInfo(stop_info);<br>
         WINLOG_IFALL(WINDOWS_LOG_EXCEPTION, desc_stream.str().c_str());<br>
@@ -701,7 +703,7 @@ ProcessWindows::OnDebugException(bool fi<br>
     if (!m_session_data)<br>
     {<br>
         WINERR_IFANY(WINDOWS_LOG_EXCEPTION,<br>
-                     "Debugger thread reported exception 0x%u at address 0x%I64x, but there is no session.",<br>
+                     "Debugger thread reported exception 0x%x at address 0x%I64x, but there is no session.",<br>
                      record.GetExceptionCode(), record.GetExceptionAddress());<br>
         return ExceptionResult::SendToApplication;<br>
     }<br>
@@ -732,7 +734,7 @@ ProcessWindows::OnDebugException(bool fi<br>
             break;<br>
         default:<br>
             WINLOG_IFANY(WINDOWS_LOG_EXCEPTION,<br>
-                         "Debugger thread reported exception 0x%u at address 0x%I64x (first_chance=%s)",<br>
+                         "Debugger thread reported exception 0x%x at address 0x%I64x (first_chance=%s)",<br>
                          record.GetExceptionCode(), record.GetExceptionAddress(), BOOL_STR(first_chance));<br>
             // For non-breakpoints, give the application a chance to handle the exception first.<br>
             if (first_chance)<br>
@@ -753,18 +755,22 @@ ProcessWindows::OnCreateThread(const Hos<br>
 }<br>
<br>
 void<br>
-ProcessWindows::OnExitThread(const HostThread &exited_thread)<br>
+ProcessWindows::OnExitThread(lldb::tid_t thread_id, uint32_t exit_code)<br>
 {<br>
     llvm::sys::ScopedLock lock(m_mutex);<br>
<br>
+    // On a forced termination, we may get exit thread events after the session<br>
+    // data has been cleaned up.<br>
+    if (!m_session_data)<br>
+        return;<br>
+<br>
     // A thread may have started and exited before the debugger stopped allowing a refresh.<br>
     // Just remove it from the new threads list in that case.<br>
-    const HostThreadWindows &wexited_thread = exited_thread.GetNativeThread();<br>
-    auto iter = m_session_data->m_new_threads.find(wexited_thread.GetThreadId());<br>
+    auto iter = m_session_data->m_new_threads.find(thread_id);<br>
     if (iter != m_session_data->m_new_threads.end())<br>
         m_session_data->m_new_threads.erase(iter);<br>
     else<br>
-        m_session_data->m_exited_threads[wexited_thread.GetThreadId()] = exited_thread;<br>
+        m_session_data->m_exited_threads.insert(thread_id);<br>
 }<br>
<br>
 void<br>
<br>
Modified: lldb/trunk/source/Plugins/Process/Windows/ProcessWindows.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Windows/ProcessWindows.h?rev=237392&r1=237391&r2=237392&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Windows/ProcessWindows.h?rev=237392&r1=237391&r2=237392&view=diff</a><br>
==============================================================================<br>
--- lldb/trunk/source/Plugins/Process/Windows/ProcessWindows.h (original)<br>
+++ lldb/trunk/source/Plugins/Process/Windows/ProcessWindows.h Thu May 14 16:07:59 2015<br>
@@ -109,7 +109,7 @@ public:<br>
     void OnDebuggerConnected(lldb::addr_t image_base) override;<br>
     ExceptionResult OnDebugException(bool first_chance, const lldb_private::ExceptionRecord &record) override;<br>
     void OnCreateThread(const lldb_private::HostThread &thread) override;<br>
-    void OnExitThread(const lldb_private::HostThread &thread) override;<br>
+    void OnExitThread(lldb::tid_t thread_id, uint32_t exit_code) override;<br>
     void OnLoadDll(const lldb_private::ModuleSpec &module_spec, lldb::addr_t module_addr) override;<br>
     void OnUnloadDll(lldb::addr_t module_addr) override;<br>
     void OnDebugString(const std::string &string) override;<br>
<br>
Modified: lldb/trunk/source/Target/ThreadList.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/ThreadList.cpp?rev=237392&r1=237391&r2=237392&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/ThreadList.cpp?rev=237392&r1=237391&r2=237392&view=diff</a><br>
==============================================================================<br>
--- lldb/trunk/source/Target/ThreadList.cpp (original)<br>
+++ lldb/trunk/source/Target/ThreadList.cpp Thu May 14 16:07:59 2015<br>
@@ -247,8 +247,8 @@ ThreadList::ShouldStop (Event *event_ptr<br>
     // figuring out whether the thread plan conditions are met.  So we don't want<br>
     // to keep the ThreadList locked the whole time we are doing this.<br>
     // FIXME: It is possible that running code could cause new threads<br>
-    // to be created.  If that happens we will miss asking them whether<br>
-    // then should stop.  This is not a big deal, since we haven't had<br>
+    // to be created.  If that happens, we will miss asking them whether<br>
+    // they should stop.  This is not a big deal since we haven't had<br>
     // a chance to hang any interesting operations on those threads yet.<br>
<br>
     collection threads_copy;<br>
<br>
Modified: lldb/trunk/test/functionalities/thread/Makefile<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/thread/Makefile?rev=237392&r1=237391&r2=237392&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/thread/Makefile?rev=237392&r1=237391&r2=237392&view=diff</a><br>
==============================================================================<br>
--- lldb/trunk/test/functionalities/thread/Makefile (original)<br>
+++ lldb/trunk/test/functionalities/thread/Makefile Thu May 14 16:07:59 2015<br>
@@ -1,5 +1,5 @@<br>
 LEVEL = ../../make<br>
<br>
-C_SOURCES := main.c<br>
+CXX_SOURCES := main.cpp<br>
 ENABLE_THREADS := YES<br>
 include $(LEVEL)/Makefile.rules<br>
<br>
Modified: lldb/trunk/test/functionalities/thread/TestNumThreads.py<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/thread/TestNumThreads.py?rev=237392&r1=237391&r2=237392&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/thread/TestNumThreads.py?rev=237392&r1=237391&r2=237392&view=diff</a><br>
==============================================================================<br>
--- lldb/trunk/test/functionalities/thread/TestNumThreads.py (original)<br>
+++ lldb/trunk/test/functionalities/thread/TestNumThreads.py Thu May 14 16:07:59 2015<br>
@@ -29,7 +29,7 @@ class NumberOfThreadsTestCase(TestBase):<br>
         # Call super's setUp().<br>
         TestBase.setUp(self)<br>
         # Find the line number to break inside main().<br>
-        self.line = line_number('main.c', '// Set break point at this line.')<br>
+        self.line = line_number('main.cpp', '// Set break point at this line.')<br>
<br>
     def number_of_threads_test(self):<br>
         """Test number of threads."""<br>
@@ -37,11 +37,11 @@ class NumberOfThreadsTestCase(TestBase):<br>
         self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)<br>
<br>
         # This should create a breakpoint with 1 location.<br>
-        lldbutil.run_break_set_by_file_and_line (self, "main.c", self.line, num_expected_locations=1)<br>
+        lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line, num_expected_locations=1)<br>
<br>
         # The breakpoint list should show 3 locations.<br>
         self.expect("breakpoint list -f", "Breakpoint location shown correctly",<br>
-            substrs = ["1: file = 'main.c', line = %d, locations = 1" % self.line])<br>
+            substrs = ["1: file = 'main.cpp', line = %d, locations = 1" % self.line])<br>
<br>
         # Run the program.<br>
         self.runCmd("run", RUN_SUCCEEDED)<br>
@@ -57,7 +57,9 @@ class NumberOfThreadsTestCase(TestBase):<br>
         # Get the number of threads<br>
         num_threads = process.GetNumThreads()<br>
<br>
-        self.assertTrue(num_threads == 4, 'Number of expected threads and actual threads do not match.')<br>
+        # Using std::thread may involve extra threads, so we assert that there are<br>
+        # at least 4 rather than exactly 4.<br>
+        self.assertTrue(num_threads >= 4, 'Number of expected threads and actual threads do not match.')<br>
<br>
 if __name__ == '__main__':<br>
     import atexit<br>
<br>
Removed: lldb/trunk/test/functionalities/thread/main.c<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/thread/main.c?rev=237391&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/thread/main.c?rev=237391&view=auto</a><br>
==============================================================================<br>
--- lldb/trunk/test/functionalities/thread/main.c (original)<br>
+++ lldb/trunk/test/functionalities/thread/main.c (removed)<br>
@@ -1,57 +0,0 @@<br>
-#include <pthread.h><br>
-<br>
-pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;<br>
-pthread_cond_t cond = PTHREAD_COND_INITIALIZER;<br>
-<br>
-void *<br>
-thread3 (void *input)<br>
-{<br>
-    pthread_mutex_lock(&mutex);<br>
-    pthread_cond_signal(&cond); // Set break point at this line.<br>
-    pthread_mutex_unlock(&mutex);<br>
-    return NULL;<br>
-}<br>
-<br>
-void *<br>
-thread2 (void *input)<br>
-{<br>
-    pthread_mutex_lock(&mutex);<br>
-    pthread_cond_signal(&cond);<br>
-    pthread_cond_wait(&cond, &mutex);<br>
-    pthread_mutex_unlock(&mutex);<br>
-    return NULL;<br>
-}<br>
-<br>
-void *<br>
-thread1 (void *input)<br>
-{<br>
-    pthread_t thread_2;<br>
-    pthread_create (&thread_2, NULL, thread2, NULL);<br>
-<br>
-    pthread_join(thread_2, NULL);<br>
-<br>
-    return NULL;<br>
-}<br>
-<br>
-int main ()<br>
-{<br>
-    pthread_t thread_1;<br>
-    pthread_t thread_3;<br>
-<br>
-    pthread_mutex_lock (&mutex);<br>
-<br>
-    pthread_create (&thread_1, NULL, thread1, NULL);<br>
-<br>
-    pthread_cond_wait (&cond, &mutex);<br>
-<br>
-    pthread_create (&thread_3, NULL, thread3, NULL);<br>
-<br>
-    pthread_cond_wait (&cond, &mutex);<br>
-<br>
-    pthread_mutex_unlock (&mutex);<br>
-<br>
-    pthread_join (thread_1, NULL);<br>
-    pthread_join (thread_3, NULL);<br>
-<br>
-    return 0;<br>
-}<br>
<br>
Added: lldb/trunk/test/functionalities/thread/main.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/thread/main.cpp?rev=237392&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/thread/main.cpp?rev=237392&view=auto</a><br>
==============================================================================<br>
--- lldb/trunk/test/functionalities/thread/main.cpp (added)<br>
+++ lldb/trunk/test/functionalities/thread/main.cpp Thu May 14 16:07:59 2015<br>
@@ -0,0 +1,50 @@<br>
+#include <condition_variable><br>
+#include <mutex><br>
+#include <thread><br>
+<br>
+std::mutex mutex;<br>
+std::condition_variable cond;<br>
+<br>
+void *<br>
+thread3(void *input)<br>
+{<br>
+    std::unique_lock<std::mutex> lock(mutex);<br>
+    cond.notify_all(); // Set break point at this line.<br>
+    return NULL;<br>
+}<br>
+<br>
+void *<br>
+thread2(void *input)<br>
+{<br>
+    std::unique_lock<std::mutex> lock(mutex);<br>
+    cond.notify_all();<br>
+    cond.wait(lock);<br>
+    return NULL;<br>
+}<br>
+<br>
+void *<br>
+thread1(void *input)<br>
+{<br>
+    std::thread thread_2(thread2, nullptr);<br>
+    thread_2.join();<br>
+<br>
+    return NULL;<br>
+}<br>
+<br>
+int main()<br>
+{<br>
+    std::unique_lock<std::mutex> lock(mutex);<br>
+<br>
+    std::thread thread_1(thread1, nullptr);<br>
+    cond.wait(lock);<br>
+<br>
+    std::thread thread_3(thread3, nullptr);<br>
+    cond.wait(lock);<br>
+<br>
+    lock.unlock();<br>
+<br>
+    thread_1.join();<br>
+    thread_3.join();<br>
+<br>
+    return 0;<br>
+}<br>
<br>
<br>
_______________________________________________<br>
lldb-commits mailing list<br>
<a href="mailto:lldb-commits@cs.uiuc.edu" target="_blank">lldb-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/lldb-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/lldb-commits</a><br>
</blockquote></div><br></div>
</blockquote></div><br></div>