Fix step over breakpoint on Windows (which was detected by TestCreateAfterAttach.py).

llvm-svn: 241475
This commit is contained in:
Adrian McCarthy
2015-07-06 17:42:09 +00:00
parent f3a493638f
commit 5cbef0e79f
4 changed files with 101 additions and 105 deletions

View File

@@ -52,10 +52,6 @@ TargetThreadWindows::RefreshStateAfterStop()
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 @@ TargetThreadWindows::GetUnwinder()
bool
TargetThreadWindows::DoResume()
{
StateType resume_state = GetResumeState();
StateType resume_state = GetTemporaryResumeState();
StateType current_state = GetState();
if (resume_state == current_state)
return true;

View File

@@ -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

View File

@@ -44,9 +44,9 @@ class CreateAfterAttachTestCase(TestBase):
# 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 @@ class CreateAfterAttachTestCase(TestBase):
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 @@ class CreateAfterAttachTestCase(TestBase):
# 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 @@ class CreateAfterAttachTestCase(TestBase):
# 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

View File

@@ -1,79 +1,78 @@
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#if defined(__linux__)
#include <sys/prctl.h>
#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");
}
#include <stdio.h>
#include <chrono>
#include <thread>
using std::chrono::microseconds;
#if defined(__linux__)
#include <sys/prctl.h>
#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");
}