parent
1db1ef9ab4
commit
3ae7492b2d
|
@ -7,6 +7,9 @@
|
|||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "lldb/Core/Log.h"
|
||||
#include "lldb/Core/Logging.h"
|
||||
#include "lldb/Core/State.h"
|
||||
#include "lldb/Host/HostInfo.h"
|
||||
#include "lldb/Host/HostNativeThreadBase.h"
|
||||
#include "lldb/Host/windows/HostThreadWindows.h"
|
||||
|
@ -15,6 +18,7 @@
|
|||
|
||||
#include "TargetThreadWindows.h"
|
||||
#include "ProcessWindows.h"
|
||||
#include "ProcessWindowsLog.h"
|
||||
#include "UnwindLLDB.h"
|
||||
|
||||
#if defined(_WIN64)
|
||||
|
@ -41,14 +45,17 @@ void
|
|||
TargetThreadWindows::RefreshStateAfterStop()
|
||||
{
|
||||
::SuspendThread(m_host_thread.GetNativeThread().GetSystemHandle());
|
||||
|
||||
SetState(eStateStopped);
|
||||
GetRegisterContext()->InvalidateIfNeeded(false);
|
||||
}
|
||||
|
||||
void
|
||||
TargetThreadWindows::WillResume(lldb::StateType resume_state)
|
||||
{
|
||||
SetResumeState(resume_state);
|
||||
Log *log(lldb_private::GetLogIfAllCategoriesSet (WINDOWS_LOG_THREAD));
|
||||
if (log)
|
||||
log->Printf ("TargetThreadWindows::WillResume (tid = %" PRIi64 ") setting thread resume state to %s",
|
||||
GetID(), StateAsCString(resume_state));
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
LEVEL = ../../../make
|
||||
|
||||
CXX_SOURCES := main.cpp
|
||||
ENABLE_THREADS := YES
|
||||
ENABLE_STD_THREADS := YES
|
||||
include $(LEVEL)/Makefile.rules
|
||||
|
|
|
@ -45,7 +45,7 @@ class BreakpointAfterJoinTestCase(TestBase):
|
|||
|
||||
# The breakpoint list should show 1 location.
|
||||
self.expect("breakpoint list -f", "Breakpoint location shown correctly",
|
||||
substrs = ["1: file = 'main.cpp', line = %d, locations = 1" % self.breakpoint])
|
||||
substrs = ["1: file = 'main.cpp', line = %d, exact_match = 0, locations = 1" % self.breakpoint])
|
||||
|
||||
# Run the program.
|
||||
self.runCmd("run", RUN_FAILED)
|
||||
|
@ -66,24 +66,13 @@ class BreakpointAfterJoinTestCase(TestBase):
|
|||
# Get the number of threads
|
||||
num_threads = process.GetNumThreads()
|
||||
|
||||
# Make sure we see six threads
|
||||
self.assertTrue(num_threads == 6, 'Number of expected threads and actual threads do not match.')
|
||||
|
||||
# Get the thread objects
|
||||
thread1 = process.GetThreadAtIndex(0)
|
||||
thread2 = process.GetThreadAtIndex(1)
|
||||
thread3 = process.GetThreadAtIndex(2)
|
||||
thread4 = process.GetThreadAtIndex(3)
|
||||
thread5 = process.GetThreadAtIndex(4)
|
||||
thread6 = process.GetThreadAtIndex(5)
|
||||
# Make sure we see at least six threads
|
||||
self.assertTrue(num_threads >= 6, 'Number of expected threads and actual threads do not match.')
|
||||
|
||||
# Make sure all threads are stopped
|
||||
self.assertTrue(thread1.IsStopped(), "Thread 1 didn't stop during breakpoint")
|
||||
self.assertTrue(thread2.IsStopped(), "Thread 2 didn't stop during breakpoint")
|
||||
self.assertTrue(thread3.IsStopped(), "Thread 3 didn't stop during breakpoint")
|
||||
self.assertTrue(thread4.IsStopped(), "Thread 4 didn't stop during breakpoint")
|
||||
self.assertTrue(thread5.IsStopped(), "Thread 5 didn't stop during breakpoint")
|
||||
self.assertTrue(thread6.IsStopped(), "Thread 6 didn't stop during breakpoint")
|
||||
for i in range(0, num_threads):
|
||||
self.assertTrue(process.GetThreadAtIndex(i).IsStopped(),
|
||||
"Thread {0} didn't stop during breakpoint.".format(i))
|
||||
|
||||
# Run to completion
|
||||
self.runCmd("continue")
|
||||
|
|
|
@ -13,9 +13,9 @@
|
|||
// breakpoint is hit. The test case should be flexible enough to treat that
|
||||
// as success.
|
||||
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
#include <atomic>
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
|
||||
volatile int g_test = 0;
|
||||
|
||||
|
@ -39,13 +39,13 @@ std::atomic_int g_barrier1;
|
|||
std::atomic_int g_barrier2;
|
||||
|
||||
void *
|
||||
break_thread_func (void *input)
|
||||
break_thread_func ()
|
||||
{
|
||||
// Wait until all the threads are running
|
||||
pseudo_barrier_wait(g_barrier1);
|
||||
|
||||
// Wait for the join thread to join
|
||||
usleep(50);
|
||||
std::this_thread::sleep_for(std::chrono::microseconds(50));
|
||||
|
||||
// Do something
|
||||
g_test++; // Set breakpoint here
|
||||
|
@ -58,7 +58,7 @@ break_thread_func (void *input)
|
|||
}
|
||||
|
||||
void *
|
||||
wait_thread_func (void *input)
|
||||
wait_thread_func ()
|
||||
{
|
||||
// Wait until the entire first group of threads is running
|
||||
pseudo_barrier_wait(g_barrier1);
|
||||
|
@ -73,13 +73,13 @@ wait_thread_func (void *input)
|
|||
void *
|
||||
join_thread_func (void *input)
|
||||
{
|
||||
pthread_t *thread_to_join = (pthread_t*)input;
|
||||
std::thread *thread_to_join = (std::thread *)input;
|
||||
|
||||
// Sync up with the rest of the threads.
|
||||
pseudo_barrier_wait(g_barrier1);
|
||||
|
||||
// Join the other thread
|
||||
pthread_join(*thread_to_join, NULL);
|
||||
thread_to_join->join();
|
||||
|
||||
// Return
|
||||
return NULL;
|
||||
|
@ -87,12 +87,6 @@ join_thread_func (void *input)
|
|||
|
||||
int main ()
|
||||
{
|
||||
pthread_t thread_1;
|
||||
pthread_t thread_2;
|
||||
pthread_t thread_3;
|
||||
pthread_t thread_4;
|
||||
pthread_t thread_5;
|
||||
|
||||
// The first barrier waits for the non-joining threads to start.
|
||||
// This thread will also participate in that barrier.
|
||||
// The idea here is to guarantee that the joining thread will be
|
||||
|
@ -104,22 +98,21 @@ int main ()
|
|||
pseudo_barrier_init(g_barrier2, 4);
|
||||
|
||||
// Create a thread to hit the breakpoint
|
||||
pthread_create (&thread_1, NULL, break_thread_func, NULL);
|
||||
std::thread thread_1(break_thread_func);
|
||||
|
||||
// Create more threads to slow the debugger down during processing.
|
||||
pthread_create (&thread_2, NULL, wait_thread_func, NULL);
|
||||
pthread_create (&thread_3, NULL, wait_thread_func, NULL);
|
||||
pthread_create (&thread_4, NULL, wait_thread_func, NULL);
|
||||
std::thread thread_2(wait_thread_func);
|
||||
std::thread thread_3(wait_thread_func);
|
||||
std::thread thread_4(wait_thread_func);
|
||||
|
||||
// Create a thread to join the breakpoint thread
|
||||
pthread_create (&thread_5, NULL, join_thread_func, &thread_4);
|
||||
std::thread thread_5(join_thread_func, &thread_1);
|
||||
|
||||
// Wait for the threads to finish
|
||||
pthread_join(thread_5, NULL);
|
||||
pthread_join(thread_4, NULL);
|
||||
pthread_join(thread_3, NULL);
|
||||
pthread_join(thread_2, NULL);
|
||||
pthread_join(thread_1, NULL);
|
||||
thread_5.join(); // implies thread_1 is already finished
|
||||
thread_4.join();
|
||||
thread_3.join();
|
||||
thread_2.join();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue