Summary:
Around a third of our test sources have LLVM license headers. This patch removes those headers from all test
sources and also fixes any tests that depended on the length of the license header.
The reasons for this are:
* A few tests verify line numbers and will start failing if the number of lines in the LLVM license header changes. Once I landed my patch for valid SourceLocations in debug info we will probably have even more tests that verify line numbers.
* No other LLVM project is putting license headers in its test files to my knowledge.
* They make the test sources much more verbose than they have to be. Several tests have longer license headers than the actual test source.
For the record, the following tests had their line numbers changed to pass with the removal of the license header:
lldb-api :: functionalities/breakpoint/breakpoint_by_line_and_column/TestBreakpointByLineAndColumn.py
lldb-shell :: Reproducer/TestGDBRemoteRepro.test
lldb-shell :: Reproducer/TestMultipleTargets.test
lldb-shell :: Reproducer/TestReuseDirectory.test
lldb-shell :: ExecControl/StopHook/stop-hook-threads.test
lldb-shell :: ExecControl/StopHook/stop-hook.test
lldb-api :: lang/objc/exceptions/TestObjCExceptions.py
Reviewers: #lldb, espindola, JDevlieghere
Reviewed By: #lldb, JDevlieghere
Subscribers: emaste, aprantl, arphaman, JDevlieghere, lldb-commits
Tags: #lldb
Differential Revision: https://reviews.llvm.org/D74839
98 lines
2.5 KiB
C++
98 lines
2.5 KiB
C++
// This test is intended to create a situation in which one thread will exit
|
|
// while a breakpoint is being handled in another thread. This may not always
|
|
// happen because it's possible that the exiting thread will exit before the
|
|
// breakpoint is hit. The test case should be flexible enough to treat that
|
|
// as success.
|
|
|
|
#include "pseudo_barrier.h"
|
|
#include <chrono>
|
|
#include <thread>
|
|
|
|
volatile int g_test = 0;
|
|
|
|
// A barrier to synchronize all the threads.
|
|
pseudo_barrier_t g_barrier1;
|
|
|
|
// A barrier to keep the threads from exiting until after the breakpoint has
|
|
// been passed.
|
|
pseudo_barrier_t g_barrier2;
|
|
|
|
void *
|
|
break_thread_func ()
|
|
{
|
|
// Wait until all the threads are running
|
|
pseudo_barrier_wait(g_barrier1);
|
|
|
|
// Wait for the join thread to join
|
|
std::this_thread::sleep_for(std::chrono::microseconds(50));
|
|
|
|
// Do something
|
|
g_test++; // Set breakpoint here
|
|
|
|
// Synchronize after the breakpoint
|
|
pseudo_barrier_wait(g_barrier2);
|
|
|
|
// Return
|
|
return NULL;
|
|
}
|
|
|
|
void *
|
|
wait_thread_func ()
|
|
{
|
|
// Wait until the entire first group of threads is running
|
|
pseudo_barrier_wait(g_barrier1);
|
|
|
|
// Wait until the breakpoint has been passed
|
|
pseudo_barrier_wait(g_barrier2);
|
|
|
|
// Return
|
|
return NULL;
|
|
}
|
|
|
|
void *
|
|
join_thread_func (void *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
|
|
thread_to_join->join();
|
|
|
|
// Return
|
|
return NULL;
|
|
}
|
|
|
|
int main ()
|
|
{
|
|
// 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
|
|
// last in the internal list maintained by the debugger.
|
|
pseudo_barrier_init(g_barrier1, 5);
|
|
|
|
// The second barrier keeps the waiting threads around until the breakpoint
|
|
// has been passed.
|
|
pseudo_barrier_init(g_barrier2, 4);
|
|
|
|
// Create a thread to hit the breakpoint
|
|
std::thread thread_1(break_thread_func);
|
|
|
|
// Create more threads to slow the debugger down during processing.
|
|
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
|
|
std::thread thread_5(join_thread_func, &thread_1);
|
|
|
|
// Wait for the threads to finish
|
|
thread_5.join(); // implies thread_1 is already finished
|
|
thread_4.join();
|
|
thread_3.join();
|
|
thread_2.join();
|
|
|
|
return 0;
|
|
}
|