Index: source/Plugins/Process/Windows/TargetThreadWindows.cpp =================================================================== --- source/Plugins/Process/Windows/TargetThreadWindows.cpp +++ source/Plugins/Process/Windows/TargetThreadWindows.cpp @@ -52,10 +52,6 @@ void TargetThreadWindows::WillResume(lldb::StateType 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 @@ -125,7 +121,7 @@ bool TargetThreadWindows::DoResume() { - StateType resume_state = GetResumeState(); + StateType resume_state = GetTemporaryResumeState(); StateType current_state = GetState(); if (resume_state == current_state) return true; Index: test/functionalities/thread/create_after_attach/Makefile =================================================================== --- test/functionalities/thread/create_after_attach/Makefile +++ test/functionalities/thread/create_after_attach/Makefile @@ -1,5 +1,5 @@ -LEVEL = ../../../make - -ENABLE_THREADS := YES -C_SOURCES := main.c -include $(LEVEL)/Makefile.rules +LEVEL = ../../../make + +CXX_SOURCES := main.cpp +ENABLE_STD_THREADS := YES +include $(LEVEL)/Makefile.rules Index: test/functionalities/thread/create_after_attach/TestCreateAfterAttach.py =================================================================== --- test/functionalities/thread/create_after_attach/TestCreateAfterAttach.py +++ test/functionalities/thread/create_after_attach/TestCreateAfterAttach.py @@ -44,9 +44,9 @@ # Call super's setUp(). TestBase.setUp(self) # Find the line numbers for our breakpoints. - self.break_1 = line_number('main.c', '// Set first breakpoint here') - self.break_2 = line_number('main.c', '// Set second breakpoint here') - self.break_3 = line_number('main.c', '// Set third breakpoint here') + self.break_1 = line_number('main.cpp', '// Set first breakpoint here') + self.break_2 = line_number('main.cpp', '// Set second breakpoint here') + self.break_3 = line_number('main.cpp', '// Set third breakpoint here') def create_after_attach(self, use_fork): """Test thread creation after process attach.""" @@ -70,13 +70,17 @@ self.assertTrue(process, PROCESS_IS_VALID) # This should create a breakpoint in the main thread. - lldbutil.run_break_set_by_file_and_line (self, "main.c", self.break_1, num_expected_locations=1) + lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.break_1, num_expected_locations=1) # This should create a breakpoint in the second child thread. - lldbutil.run_break_set_by_file_and_line (self, "main.c", self.break_2, num_expected_locations=1) + lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.break_2, num_expected_locations=1) # This should create a breakpoint in the first child thread. - lldbutil.run_break_set_by_file_and_line (self, "main.c", self.break_3, num_expected_locations=1) + lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.break_3, num_expected_locations=1) + + # Note: With std::thread, we cannot rely on particular thread numbers. Using + # std::thread may cause the program to spin up a thread pool (and it does on + # Windows), so the thread numbers are non-deterministic. # Run to the first breakpoint self.runCmd("continue") @@ -84,23 +88,21 @@ # The stop reason of the thread should be breakpoint. self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, substrs = ['stopped', - '* thread #1', - 'stop reason = breakpoint', - 'thread #2']) + '* thread #', + 'main', + 'stop reason = breakpoint']) # Change a variable to escape the loop self.runCmd("expression main_thread_continue = 1") # Run to the second breakpoint self.runCmd("continue") - self.runCmd("thread select 3") # The stop reason of the thread should be breakpoint. self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, substrs = ['stopped', - 'thread #1', - 'thread #2', - '* thread #3', + '* thread #', + 'thread_2_func', 'stop reason = breakpoint']) # Change a variable to escape the loop @@ -108,14 +110,13 @@ # Run to the third breakpoint self.runCmd("continue") - self.runCmd("thread select 2") # The stop reason of the thread should be breakpoint. # Thread 3 may or may not have already exited. self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, substrs = ['stopped', - 'thread #1', - '* thread #2', + '* thread #', + 'thread_1_func', 'stop reason = breakpoint']) # Run to completion Index: test/functionalities/thread/create_after_attach/main.c =================================================================== --- test/functionalities/thread/create_after_attach/main.c +++ /dev/null @@ -1,79 +0,0 @@ -#include -#include -#include - -#if defined(__linux__) -#include -#endif - -volatile int g_thread_2_continuing = 0; - -void * -thread_1_func (void *input) -{ - // Waiting to be released by the debugger. - while (!g_thread_2_continuing) // The debugger will change this value - { - usleep(1); - } - - // Return - return NULL; // Set third breakpoint here -} - -void * -thread_2_func (void *input) -{ - // Waiting to be released by the debugger. - int child_thread_continue = 0; - while (!child_thread_continue) // The debugger will change this value - { - usleep(1); // Set second breakpoint here - } - - // Release thread 1 - g_thread_2_continuing = 1; - - // Return - return NULL; -} - -int main(int argc, char const *argv[]) -{ - pthread_t thread_1; - pthread_t thread_2; - -#if defined(__linux__) - // Immediately enable any ptracer so that we can allow the stub attach - // operation to succeed. Some Linux kernels are locked down so that - // only an ancestor process can be a ptracer of a process. This disables that - // restriction. Without it, attach-related stub tests will fail. -#if defined(PR_SET_PTRACER) && defined(PR_SET_PTRACER_ANY) - int prctl_result; - - // For now we execute on best effort basis. If this fails for - // some reason, so be it. - prctl_result = prctl(PR_SET_PTRACER, PR_SET_PTRACER_ANY, 0, 0, 0); - (void) prctl_result; -#endif -#endif - - // Create a new thread - pthread_create (&thread_1, NULL, thread_1_func, NULL); - - // Waiting to be attached by the debugger. - int main_thread_continue = 0; - while (!main_thread_continue) // The debugger will change this value - { - usleep(1); // Set first breakpoint here - } - - // Create another new thread - pthread_create (&thread_2, NULL, thread_2_func, NULL); - - // Wait for the threads to finish. - pthread_join(thread_1, NULL); - pthread_join(thread_2, NULL); - - printf("Exiting now\n"); -} Index: test/functionalities/thread/create_after_attach/main.cpp =================================================================== --- /dev/null +++ test/functionalities/thread/create_after_attach/main.cpp @@ -0,0 +1,78 @@ +#include +#include +#include + +using std::chrono::microseconds; + +#if defined(__linux__) +#include +#endif + +volatile int g_thread_2_continuing = 0; + +void * +thread_1_func (void *input) +{ + // Waiting to be released by the debugger. + while (!g_thread_2_continuing) // Another thread will change this value + { + std::this_thread::sleep_for(microseconds(1)); + } + + // Return + return NULL; // Set third breakpoint here +} + +void * +thread_2_func (void *input) +{ + // Waiting to be released by the debugger. + int child_thread_continue = 0; + while (!child_thread_continue) // The debugger will change this value + { + std::this_thread::sleep_for(microseconds(1)); // Set second breakpoint here + } + + // Release thread 1 + g_thread_2_continuing = 1; + + // Return + return NULL; +} + +int main(int argc, char const *argv[]) +{ +#if defined(__linux__) + // Immediately enable any ptracer so that we can allow the stub attach + // operation to succeed. Some Linux kernels are locked down so that + // only an ancestor process can be a ptracer of a process. This disables that + // restriction. Without it, attach-related stub tests will fail. +#if defined(PR_SET_PTRACER) && defined(PR_SET_PTRACER_ANY) + int prctl_result; + + // For now we execute on best effort basis. If this fails for + // some reason, so be it. + prctl_result = prctl(PR_SET_PTRACER, PR_SET_PTRACER_ANY, 0, 0, 0); + (void) prctl_result; +#endif +#endif + + // Create a new thread + std::thread thread_1(thread_1_func, nullptr); + + // Waiting to be attached by the debugger. + int main_thread_continue = 0; + while (!main_thread_continue) // The debugger will change this value + { + std::this_thread::sleep_for(microseconds(1)); // Set first breakpoint here + } + + // Create another new thread + std::thread thread_2(thread_2_func, nullptr); + + // Wait for the threads to finish. + thread_1.join(); + thread_2.join(); + + printf("Exiting now\n"); +}