[Lldb-commits] [lldb] r237392 - Enable multithreaded debugging on Windows.

Adrian McCarthy amccarth at google.com
Fri May 15 09:15:20 PDT 2015


Weird, I didn't get any buildbot notification of the failure.

Yes, we can roll it back.  I've not done that before, so I'll have to learn
the process.

On Thu, May 14, 2015 at 6:25 PM, Vince Harron <vince at nethacker.com> wrote:

> There is a new test failure in Linux after this change.  Can we revert to
> green and help you figure it out?
>
> ======================================================================
> FAIL: test_with_dwarf (TestNumThreads.NumberOfThreadsTestCase)
>    Test number of threads.
> ----------------------------------------------------------------------
> Traceback (most recent call last):
>   File
> "/usr/local/google/home/vharron/bisect/tmp/llvm/tools/lldb/test/lldbtest.py",
> line 499, in wrapper
>     return func(self, *args, **kwargs)
>   File
> "/usr/local/google/home/vharron/bisect/tmp/llvm/tools/lldb/test/functionalities/thread/TestNumThreads.py",
> line 26, in test_with_dwarf
>     self.number_of_threads_test()
>   File
> "/usr/local/google/home/vharron/bisect/tmp/llvm/tools/lldb/test/functionalities/thread/TestNumThreads.py",
> line 51, in number_of_threads_test
>     substrs = ["stop reason = breakpoint 1."])
>   File
> "/usr/local/google/home/vharron/bisect/tmp/llvm/tools/lldb/test/lldbtest.py",
> line 2344, in expect
>     msg if msg else EXP_MSG(str, exe))
> AssertionError: False is not True : Process should be stopped due to
> breakpoint
> Config=i386-gcc
> ----------------------------------------------------------------------
>
>
>
>
> On Thu, May 14, 2015 at 2:07 PM, Adrian McCarthy <amccarth at google.com>
> wrote:
>
>> Author: amccarth
>> Date: Thu May 14 16:07:59 2015
>> New Revision: 237392
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=237392&view=rev
>> Log:
>> Enable multithreaded debugging on Windows.
>>
>> Added:
>>     lldb/trunk/test/functionalities/thread/main.cpp
>> Removed:
>>     lldb/trunk/test/functionalities/thread/main.c
>> 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
>>     lldb/trunk/test/functionalities/thread/Makefile
>>     lldb/trunk/test/functionalities/thread/TestNumThreads.py
>>
>> 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=237392&r1=237391&r2=237392&view=diff
>>
>> ==============================================================================
>> --- lldb/trunk/source/Plugins/Process/Windows/DebuggerThread.cpp
>> (original)
>> +++ lldb/trunk/source/Plugins/Process/Windows/DebuggerThread.cpp Thu May
>> 14 16:07:59 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=237392&r1=237391&r2=237392&view=diff
>>
>> ==============================================================================
>> --- lldb/trunk/source/Plugins/Process/Windows/ExceptionRecord.h (original)
>> +++ lldb/trunk/source/Plugins/Process/Windows/ExceptionRecord.h Thu May
>> 14 16:07:59 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=237392&r1=237391&r2=237392&view=diff
>>
>> ==============================================================================
>> --- lldb/trunk/source/Plugins/Process/Windows/IDebugDelegate.h (original)
>> +++ lldb/trunk/source/Plugins/Process/Windows/IDebugDelegate.h Thu May 14
>> 16:07:59 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=237392&r1=237391&r2=237392&view=diff
>>
>> ==============================================================================
>> --- lldb/trunk/source/Plugins/Process/Windows/LocalDebugDelegate.cpp
>> (original)
>> +++ lldb/trunk/source/Plugins/Process/Windows/LocalDebugDelegate.cpp Thu
>> May 14 16:07:59 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=237392&r1=237391&r2=237392&view=diff
>>
>> ==============================================================================
>> --- lldb/trunk/source/Plugins/Process/Windows/LocalDebugDelegate.h
>> (original)
>> +++ lldb/trunk/source/Plugins/Process/Windows/LocalDebugDelegate.h Thu
>> May 14 16:07:59 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=237392&r1=237391&r2=237392&view=diff
>>
>> ==============================================================================
>> --- lldb/trunk/source/Plugins/Process/Windows/ProcessWindows.cpp
>> (original)
>> +++ lldb/trunk/source/Plugins/Process/Windows/ProcessWindows.cpp Thu May
>> 14 16:07:59 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=237392&r1=237391&r2=237392&view=diff
>>
>> ==============================================================================
>> --- lldb/trunk/source/Plugins/Process/Windows/ProcessWindows.h (original)
>> +++ lldb/trunk/source/Plugins/Process/Windows/ProcessWindows.h Thu May 14
>> 16:07:59 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=237392&r1=237391&r2=237392&view=diff
>>
>> ==============================================================================
>> --- lldb/trunk/source/Target/ThreadList.cpp (original)
>> +++ lldb/trunk/source/Target/ThreadList.cpp Thu May 14 16:07:59 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;
>>
>> Modified: lldb/trunk/test/functionalities/thread/Makefile
>> URL:
>> http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/thread/Makefile?rev=237392&r1=237391&r2=237392&view=diff
>>
>> ==============================================================================
>> --- lldb/trunk/test/functionalities/thread/Makefile (original)
>> +++ lldb/trunk/test/functionalities/thread/Makefile Thu May 14 16:07:59
>> 2015
>> @@ -1,5 +1,5 @@
>>  LEVEL = ../../make
>>
>> -C_SOURCES := main.c
>> +CXX_SOURCES := main.cpp
>>  ENABLE_THREADS := YES
>>  include $(LEVEL)/Makefile.rules
>>
>> Modified: lldb/trunk/test/functionalities/thread/TestNumThreads.py
>> URL:
>> http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/thread/TestNumThreads.py?rev=237392&r1=237391&r2=237392&view=diff
>>
>> ==============================================================================
>> --- lldb/trunk/test/functionalities/thread/TestNumThreads.py (original)
>> +++ lldb/trunk/test/functionalities/thread/TestNumThreads.py Thu May 14
>> 16:07:59 2015
>> @@ -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.c', '// Set break point at this
>> line.')
>> +        self.line = line_number('main.cpp', '// 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.c",
>> self.line, num_expected_locations=1)
>> +        lldbutil.run_break_set_by_file_and_line (self, "main.cpp",
>> 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.c', line = %d, locations = 1" %
>> self.line])
>> +            substrs = ["1: file = 'main.cpp', line = %d, locations = 1"
>> % self.line])
>>
>>          # Run the program.
>>          self.runCmd("run", RUN_SUCCEEDED)
>> @@ -57,7 +57,9 @@ class NumberOfThreadsTestCase(TestBase):
>>          # Get the number of threads
>>          num_threads = process.GetNumThreads()
>>
>> -        self.assertTrue(num_threads == 4, 'Number of expected threads
>> and actual threads do not match.')
>> +        # 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.')
>>
>>  if __name__ == '__main__':
>>      import atexit
>>
>> Removed: lldb/trunk/test/functionalities/thread/main.c
>> URL:
>> http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/thread/main.c?rev=237391&view=auto
>>
>> ==============================================================================
>> --- lldb/trunk/test/functionalities/thread/main.c (original)
>> +++ lldb/trunk/test/functionalities/thread/main.c (removed)
>> @@ -1,57 +0,0 @@
>> -#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;
>> -}
>>
>> Added: lldb/trunk/test/functionalities/thread/main.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/thread/main.cpp?rev=237392&view=auto
>>
>> ==============================================================================
>> --- lldb/trunk/test/functionalities/thread/main.cpp (added)
>> +++ lldb/trunk/test/functionalities/thread/main.cpp Thu May 14 16:07:59
>> 2015
>> @@ -0,0 +1,50 @@
>> +#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;
>> +}
>>
>>
>> _______________________________________________
>> lldb-commits mailing list
>> lldb-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/lldb-commits
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/lldb-commits/attachments/20150515/96fc3bee/attachment.html>


More information about the lldb-commits mailing list