diff options
author | 2020-08-03 14:33:06 +0000 | |
---|---|---|
committer | 2020-08-03 14:33:06 +0000 | |
commit | 061da546b983eb767bad15e67af1174fb0bcf31c (patch) | |
tree | 83c78b820819d70aa40c36d90447978b300078c5 /gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread | |
parent | Import LLVM 10.0.0 release including clang, lld and lldb. (diff) | |
download | wireguard-openbsd-061da546b983eb767bad15e67af1174fb0bcf31c.tar.xz wireguard-openbsd-061da546b983eb767bad15e67af1174fb0bcf31c.zip |
Import LLVM 10.0.0 release including clang, lld and lldb.
ok hackroom
tested by plenty
Diffstat (limited to 'gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread')
90 files changed, 3927 insertions, 0 deletions
diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/backtrace_all/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/backtrace_all/Makefile new file mode 100644 index 00000000000..cd092b77256 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/backtrace_all/Makefile @@ -0,0 +1,5 @@ +CXXFLAGS_EXTRAS := -std=c++11 +CXX_SOURCES := ParallelTask.cpp +ENABLE_THREADS := YES + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/backtrace_all/ParallelTask.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/backtrace_all/ParallelTask.cpp new file mode 100644 index 00000000000..8e0f76f691b --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/backtrace_all/ParallelTask.cpp @@ -0,0 +1,152 @@ +#include <cstdint> +#include <thread> +#include <vector> +#include <queue> +#include <functional> +#include <future> +#include <iostream> +#include <cassert> + +class TaskPoolImpl +{ +public: + TaskPoolImpl(uint32_t num_threads) : + m_stop(false) + { + for (uint32_t i = 0; i < num_threads; ++i) + m_threads.emplace_back(Worker, this); + } + + ~TaskPoolImpl() + { + Stop(); + } + + template<typename F, typename... Args> + std::future<typename std::result_of<F(Args...)>::type> + AddTask(F&& f, Args&&... args) + { + auto task = std::make_shared<std::packaged_task<typename std::result_of<F(Args...)>::type()>>( + std::bind(std::forward<F>(f), std::forward<Args>(args)...)); + + std::unique_lock<std::mutex> lock(m_tasks_mutex); + assert(!m_stop && "Can't add task to TaskPool after it is stopped"); + m_tasks.emplace([task](){ (*task)(); }); + lock.unlock(); + m_tasks_cv.notify_one(); + + return task->get_future(); + } + + void + Stop() + { + std::unique_lock<std::mutex> lock(m_tasks_mutex); + m_stop = true; + m_tasks_mutex.unlock(); + m_tasks_cv.notify_all(); + for (auto& t : m_threads) + t.join(); + } + +private: + static void + Worker(TaskPoolImpl* pool) + { + while (true) + { + std::unique_lock<std::mutex> lock(pool->m_tasks_mutex); + if (pool->m_tasks.empty()) + pool->m_tasks_cv.wait(lock, [pool](){ return !pool->m_tasks.empty() || pool->m_stop; }); + if (pool->m_tasks.empty()) + break; + + std::function<void()> f = pool->m_tasks.front(); + pool->m_tasks.pop(); + lock.unlock(); + + f(); + } + } + + std::queue<std::function<void()>> m_tasks; + std::mutex m_tasks_mutex; + std::condition_variable m_tasks_cv; + bool m_stop; + std::vector<std::thread> m_threads; +}; + +class TaskPool +{ +public: + // Add a new task to the thread pool and return a std::future belongs for the newly created task. + // The caller of this function have to wait on the future for this task to complete. + template<typename F, typename... Args> + static std::future<typename std::result_of<F(Args...)>::type> + AddTask(F&& f, Args&&... args) + { + return GetImplementation().AddTask(std::forward<F>(f), std::forward<Args>(args)...); + } + + // Run all of the specified tasks on the thread pool and wait until all of them are finished + // before returning + template<typename... T> + static void + RunTasks(T&&... t) + { + RunTaskImpl<T...>::Run(std::forward<T>(t)...); + } + +private: + static TaskPoolImpl& + GetImplementation() + { + static TaskPoolImpl g_task_pool_impl(std::thread::hardware_concurrency()); + return g_task_pool_impl; + } + + template<typename... T> + struct RunTaskImpl; +}; + +template<typename H, typename... T> +struct TaskPool::RunTaskImpl<H, T...> +{ + static void + Run(H&& h, T&&... t) + { + auto f = AddTask(std::forward<H>(h)); + RunTaskImpl<T...>::Run(std::forward<T>(t)...); + f.wait(); + } +}; + +template<> +struct TaskPool::RunTaskImpl<> +{ + static void + Run() {} +}; + +int main() +{ + std::vector<std::future<uint32_t>> tasks; + for (int i = 0; i < 100000; ++i) + { + tasks.emplace_back(TaskPool::AddTask([](int i){ + uint32_t s = 0; + for (int j = 0; j <= i; ++j) + s += j; + return s; + }, + i)); + } + + for (auto& it : tasks) // Set breakpoint here + it.wait(); + + TaskPool::RunTasks( + []() { return 1; }, + []() { return "aaaa"; } + ); +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/backtrace_all/TestBacktraceAll.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/backtrace_all/TestBacktraceAll.py new file mode 100644 index 00000000000..870b6b223c8 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/backtrace_all/TestBacktraceAll.py @@ -0,0 +1,65 @@ +""" +Test regression for Bug 25251. +""" + +import unittest2 +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class BacktraceAllTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line number for our breakpoint. + self.breakpoint = line_number( + 'ParallelTask.cpp', '// Set breakpoint here') + + # The android-arm compiler can't compile the inferior + @skipIfTargetAndroid(archs=["arm"]) + # because of an issue around std::future. + # TODO: Change the test to don't depend on std::future<T> + def test(self): + """Test breakpoint handling after a thread join.""" + self.build(dictionary=self.getBuildFlags()) + + exe = self.getBuildArtifact("a.out") + self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) + + # This should create a breakpoint + lldbutil.run_break_set_by_file_and_line( + self, "ParallelTask.cpp", self.breakpoint, num_expected_locations=-1) + + # The breakpoint list should show 1 location. + self.expect( + "breakpoint list -f", + "Breakpoint location shown correctly", + substrs=[ + "1: file = 'ParallelTask.cpp', line = %d, exact_match = 0" % + self.breakpoint]) + + # Run the program. + self.runCmd("run", RUN_SUCCEEDED) + + # The stop reason of the thread should be breakpoint. + self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, + substrs=['stopped', + 'stop reason = breakpoint']) + + # This should not result in a segmentation fault + self.expect("thread backtrace all", STOPPED_DUE_TO_BREAKPOINT, + substrs=["stop reason = breakpoint 1."]) + + # Run to completion + self.runCmd("continue") + +if __name__ == '__main__': + import atexit + lldb.SBDebugger.Initialize() + atexit.register(lambda: lldb.SBDebugger.Terminate()) + unittest2.main() diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/backtrace_limit/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/backtrace_limit/Makefile new file mode 100644 index 00000000000..5fd720c6d06 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/backtrace_limit/Makefile @@ -0,0 +1,5 @@ +CXXFLAGS_EXTRAS := -std=c++11 +CXX_SOURCES := main.cpp +ENABLE_THREADS := YES + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/backtrace_limit/TestBacktraceLimit.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/backtrace_limit/TestBacktraceLimit.py new file mode 100644 index 00000000000..6dbb3e30ee7 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/backtrace_limit/TestBacktraceLimit.py @@ -0,0 +1,27 @@ +""" +Test that the target.process.thread.max-backtrace-depth setting works. +""" + +import unittest2 +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class BacktraceLimitSettingTest(TestBase): + + mydir = TestBase.compute_mydir(__file__) + NO_DEBUG_INFO_TESTCASE = True + + def test_backtrace_depth(self): + """Test that the max-backtrace-depth setting limits backtraces.""" + self.build() + self.main_source_file = lldb.SBFileSpec("main.cpp") + (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(self, + "Set a breakpoint here", self.main_source_file) + interp = self.dbg.GetCommandInterpreter() + result = lldb.SBCommandReturnObject() + interp.HandleCommand("settings set target.process.thread.max-backtrace-depth 30", result) + self.assertEqual(True, result.Succeeded()) + self.assertEqual(30, thread.GetNumFrames()) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/backtrace_limit/main.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/backtrace_limit/main.cpp new file mode 100644 index 00000000000..eca1eadc8e4 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/backtrace_limit/main.cpp @@ -0,0 +1,13 @@ +int bottom () { + return 1; // Set a breakpoint here +} +int foo(int in) { + if (in > 0) + return foo(--in) + 5; + else + return bottom(); +} +int main() +{ + return foo(500); +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/break_after_join/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/break_after_join/Makefile new file mode 100644 index 00000000000..566938ca0cc --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/break_after_join/Makefile @@ -0,0 +1,3 @@ +CXX_SOURCES := main.cpp +ENABLE_THREADS := YES +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/break_after_join/TestBreakAfterJoin.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/break_after_join/TestBreakAfterJoin.py new file mode 100644 index 00000000000..391f9d96597 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/break_after_join/TestBreakAfterJoin.py @@ -0,0 +1,93 @@ +""" +Test number of threads. +""" + + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class BreakpointAfterJoinTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line number for our breakpoint. + self.breakpoint = line_number('main.cpp', '// Set breakpoint here') + + @expectedFailureAll( + oslist=["linux"], + bugnumber="llvm.org/pr15824 thread states not properly maintained") + @expectedFailureAll( + oslist=lldbplatformutil.getDarwinOSTriples(), + bugnumber="llvm.org/pr15824 thread states not properly maintained and <rdar://problem/28557237>") + @expectedFailureAll( + oslist=["freebsd"], + bugnumber="llvm.org/pr18190 thread states not properly maintained") + @expectedFailureNetBSD + def test(self): + """Test breakpoint handling after a thread join.""" + self.build(dictionary=self.getBuildFlags()) + + exe = self.getBuildArtifact("a.out") + self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) + + # This should create a breakpoint in the main thread. + lldbutil.run_break_set_by_file_and_line( + self, "main.cpp", self.breakpoint, num_expected_locations=1) + + # The breakpoint list should show 1 location. + self.expect( + "breakpoint list -f", + "Breakpoint location shown correctly", + substrs=[ + "1: file = 'main.cpp', line = %d, exact_match = 0, locations = 1" % + self.breakpoint]) + + # Run the program. + self.runCmd("run", RUN_SUCCEEDED) + + # The stop reason of the thread should be breakpoint. + self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, + substrs=['stopped', + 'stop reason = breakpoint']) + + # Get the target process + target = self.dbg.GetSelectedTarget() + process = target.GetProcess() + + # The exit probably occurred during breakpoint handling, but it isn't + # guaranteed. The main thing we're testing here is that the debugger + # handles this cleanly is some way. + + # Get the number of threads + num_threads = process.GetNumThreads() + + # 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 + 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") + + # If the process hasn't exited, collect some information + if process.GetState() != lldb.eStateExited: + self.runCmd("thread list") + self.runCmd("process status") + + # At this point, the inferior process should have exited. + self.assertTrue( + process.GetState() == lldb.eStateExited, + PROCESS_EXITED) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/break_after_join/main.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/break_after_join/main.cpp new file mode 100644 index 00000000000..a589d979003 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/break_after_join/main.cpp @@ -0,0 +1,105 @@ +//===-- main.cpp ------------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// 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; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/Makefile new file mode 100644 index 00000000000..c33ae5685ef --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/Makefile @@ -0,0 +1,5 @@ +CXX_SOURCES := main.cpp + +ENABLE_THREADS := YES + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentBreakpointDelayBreakpointOneSignal.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentBreakpointDelayBreakpointOneSignal.py new file mode 100644 index 00000000000..a0c1da8dad1 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentBreakpointDelayBreakpointOneSignal.py @@ -0,0 +1,23 @@ + +import unittest2 + +from lldbsuite.test.decorators import * +from lldbsuite.test.concurrent_base import ConcurrentEventsBase +from lldbsuite.test.lldbtest import TestBase + + +@skipIfWindows +class ConcurrentBreakpointDelayBreakpointOneSignal(ConcurrentEventsBase): + + mydir = ConcurrentEventsBase.compute_mydir(__file__) + + @skipIfFreeBSD # timing out on buildbot + # Atomic sequences are not supported yet for MIPS in LLDB. + @skipIf(triple='^mips') + @expectedFailureNetBSD + def test(self): + """Test two threads that trigger a breakpoint (one with a 1 second delay) and one signal thread. """ + self.build(dictionary=self.getBuildFlags()) + self.do_thread_actions(num_breakpoint_threads=1, + num_delay_breakpoint_threads=1, + num_signal_threads=1) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentBreakpointOneDelayBreakpointThreads.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentBreakpointOneDelayBreakpointThreads.py new file mode 100644 index 00000000000..bcee1c54e76 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentBreakpointOneDelayBreakpointThreads.py @@ -0,0 +1,21 @@ + +import unittest2 + +from lldbsuite.test.decorators import * +from lldbsuite.test.concurrent_base import ConcurrentEventsBase +from lldbsuite.test.lldbtest import TestBase + + +@skipIfWindows +class ConcurrentBreakpointOneDelayBreakpointThreads(ConcurrentEventsBase): + + mydir = ConcurrentEventsBase.compute_mydir(__file__) + + @skipIfFreeBSD # timing out on buildbot + # Atomic sequences are not supported yet for MIPS in LLDB. + @skipIf(triple='^mips') + def test(self): + """Test threads that trigger a breakpoint where one thread has a 1 second delay. """ + self.build(dictionary=self.getBuildFlags()) + self.do_thread_actions(num_breakpoint_threads=1, + num_delay_breakpoint_threads=1) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentBreakpointsDelayedBreakpointOneWatchpoint.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentBreakpointsDelayedBreakpointOneWatchpoint.py new file mode 100644 index 00000000000..dfe2cb7d23e --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentBreakpointsDelayedBreakpointOneWatchpoint.py @@ -0,0 +1,24 @@ + +import unittest2 + +from lldbsuite.test.decorators import * +from lldbsuite.test.concurrent_base import ConcurrentEventsBase +from lldbsuite.test.lldbtest import TestBase + + +@skipIfWindows +class ConcurrentBreakpointsDelayedBreakpointOneWatchpoint( + ConcurrentEventsBase): + + mydir = ConcurrentEventsBase.compute_mydir(__file__) + + @skipIfFreeBSD # timing out on buildbot + # Atomic sequences are not supported yet for MIPS in LLDB. + @skipIf(triple='^mips') + @add_test_categories(["watchpoint"]) + def test(self): + """Test a breakpoint, a delayed breakpoint, and one watchpoint thread. """ + self.build(dictionary=self.getBuildFlags()) + self.do_thread_actions(num_breakpoint_threads=1, + num_delay_breakpoint_threads=1, + num_watchpoint_threads=1) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentCrashWithBreak.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentCrashWithBreak.py new file mode 100644 index 00000000000..9083c3838bc --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentCrashWithBreak.py @@ -0,0 +1,20 @@ + +import unittest2 + +from lldbsuite.test.decorators import * +from lldbsuite.test.concurrent_base import ConcurrentEventsBase +from lldbsuite.test.lldbtest import TestBase + + +@skipIfWindows +class ConcurrentCrashWithBreak(ConcurrentEventsBase): + + mydir = ConcurrentEventsBase.compute_mydir(__file__) + + @skipIfFreeBSD # timing out on buildbot + # Atomic sequences are not supported yet for MIPS in LLDB. + @skipIf(triple='^mips') + def test(self): + """ Test a thread that crashes while another thread hits a breakpoint.""" + self.build(dictionary=self.getBuildFlags()) + self.do_thread_actions(num_crash_threads=1, num_breakpoint_threads=1) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentCrashWithSignal.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentCrashWithSignal.py new file mode 100644 index 00000000000..37795be849d --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentCrashWithSignal.py @@ -0,0 +1,20 @@ + +import unittest2 + +from lldbsuite.test.decorators import * +from lldbsuite.test.concurrent_base import ConcurrentEventsBase +from lldbsuite.test.lldbtest import TestBase + + +@skipIfWindows +class ConcurrentCrashWithSignal(ConcurrentEventsBase): + + mydir = ConcurrentEventsBase.compute_mydir(__file__) + + @skipIfFreeBSD # timing out on buildbot + # Atomic sequences are not supported yet for MIPS in LLDB. + @skipIf(triple='^mips') + def test(self): + """ Test a thread that crashes while another thread generates a signal.""" + self.build(dictionary=self.getBuildFlags()) + self.do_thread_actions(num_crash_threads=1, num_signal_threads=1) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentCrashWithWatchpoint.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentCrashWithWatchpoint.py new file mode 100644 index 00000000000..13f5b4ad35e --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentCrashWithWatchpoint.py @@ -0,0 +1,21 @@ + +import unittest2 + +from lldbsuite.test.decorators import * +from lldbsuite.test.concurrent_base import ConcurrentEventsBase +from lldbsuite.test.lldbtest import TestBase + + +@skipIfWindows +class ConcurrentCrashWithWatchpoint(ConcurrentEventsBase): + + mydir = ConcurrentEventsBase.compute_mydir(__file__) + + @skipIfFreeBSD # timing out on buildbot + # Atomic sequences are not supported yet for MIPS in LLDB. + @skipIf(triple='^mips') + @add_test_categories(["watchpoint"]) + def test(self): + """ Test a thread that crashes while another thread hits a watchpoint.""" + self.build(dictionary=self.getBuildFlags()) + self.do_thread_actions(num_crash_threads=1, num_watchpoint_threads=1) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentCrashWithWatchpointBreakpointSignal.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentCrashWithWatchpointBreakpointSignal.py new file mode 100644 index 00000000000..3de0850abe2 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentCrashWithWatchpointBreakpointSignal.py @@ -0,0 +1,24 @@ + +import unittest2 + +from lldbsuite.test.decorators import * +from lldbsuite.test.concurrent_base import ConcurrentEventsBase +from lldbsuite.test.lldbtest import TestBase + + +@skipIfWindows +class ConcurrentCrashWithWatchpointBreakpointSignal(ConcurrentEventsBase): + + mydir = ConcurrentEventsBase.compute_mydir(__file__) + + @skipIfFreeBSD # timing out on buildbot + # Atomic sequences are not supported yet for MIPS in LLDB. + @skipIf(triple='^mips') + @add_test_categories(["watchpoint"]) + def test(self): + """ Test a thread that crashes while other threads generate a signal and hit a watchpoint and breakpoint. """ + self.build(dictionary=self.getBuildFlags()) + self.do_thread_actions(num_crash_threads=1, + num_breakpoint_threads=1, + num_signal_threads=1, + num_watchpoint_threads=1) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentDelaySignalBreak.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentDelaySignalBreak.py new file mode 100644 index 00000000000..af9c6c994ab --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentDelaySignalBreak.py @@ -0,0 +1,22 @@ + +import unittest2 + +from lldbsuite.test.decorators import * +from lldbsuite.test.concurrent_base import ConcurrentEventsBase +from lldbsuite.test.lldbtest import TestBase + + +@skipIfWindows +class ConcurrentDelaySignalBreak(ConcurrentEventsBase): + + mydir = ConcurrentEventsBase.compute_mydir(__file__) + + @skipIfFreeBSD # timing out on buildbot + # Atomic sequences are not supported yet for MIPS in LLDB. + @skipIf(triple='^mips') + def test(self): + """Test (1-second delay) signal and a breakpoint in multiple threads.""" + self.build(dictionary=self.getBuildFlags()) + self.do_thread_actions( + num_breakpoint_threads=1, + num_delay_signal_threads=1) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentDelaySignalWatch.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentDelaySignalWatch.py new file mode 100644 index 00000000000..91358f34676 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentDelaySignalWatch.py @@ -0,0 +1,23 @@ + +import unittest2 + +from lldbsuite.test.decorators import * +from lldbsuite.test.concurrent_base import ConcurrentEventsBase +from lldbsuite.test.lldbtest import TestBase + + +@skipIfWindows +class ConcurrentDelaySignalWatch(ConcurrentEventsBase): + + mydir = ConcurrentEventsBase.compute_mydir(__file__) + + @skipIfFreeBSD # timing out on buildbot + # Atomic sequences are not supported yet for MIPS in LLDB. + @skipIf(triple='^mips') + @add_test_categories(["watchpoint"]) + def test(self): + """Test a watchpoint and a (1 second delay) signal in multiple threads.""" + self.build(dictionary=self.getBuildFlags()) + self.do_thread_actions( + num_delay_signal_threads=1, + num_watchpoint_threads=1) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentDelayWatchBreak.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentDelayWatchBreak.py new file mode 100644 index 00000000000..8f7a8ba6a08 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentDelayWatchBreak.py @@ -0,0 +1,23 @@ + +import unittest2 + +from lldbsuite.test.decorators import * +from lldbsuite.test.concurrent_base import ConcurrentEventsBase +from lldbsuite.test.lldbtest import TestBase + + +@skipIfWindows +class ConcurrentDelayWatchBreak(ConcurrentEventsBase): + + mydir = ConcurrentEventsBase.compute_mydir(__file__) + + @skipIfFreeBSD # timing out on buildbot + # Atomic sequences are not supported yet for MIPS in LLDB. + @skipIf(triple='^mips') + @add_test_categories(["watchpoint"]) + def test(self): + """Test (1-second delay) watchpoint and a breakpoint in multiple threads.""" + self.build(dictionary=self.getBuildFlags()) + self.do_thread_actions( + num_breakpoint_threads=1, + num_delay_watchpoint_threads=1) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentDelayedCrashWithBreakpointSignal.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentDelayedCrashWithBreakpointSignal.py new file mode 100644 index 00000000000..9c1ac90423c --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentDelayedCrashWithBreakpointSignal.py @@ -0,0 +1,22 @@ + +import unittest2 + +from lldbsuite.test.decorators import * +from lldbsuite.test.concurrent_base import ConcurrentEventsBase +from lldbsuite.test.lldbtest import TestBase + + +@skipIfWindows +class ConcurrentDelayedCrashWithBreakpointSignal(ConcurrentEventsBase): + + mydir = ConcurrentEventsBase.compute_mydir(__file__) + + @skipIfFreeBSD # timing out on buildbot + # Atomic sequences are not supported yet for MIPS in LLDB. + @skipIf(triple='^mips') + def test(self): + """ Test a thread with a delayed crash while other threads generate a signal and hit a breakpoint. """ + self.build(dictionary=self.getBuildFlags()) + self.do_thread_actions(num_delay_crash_threads=1, + num_breakpoint_threads=1, + num_signal_threads=1) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentDelayedCrashWithBreakpointWatchpoint.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentDelayedCrashWithBreakpointWatchpoint.py new file mode 100644 index 00000000000..12344ffb061 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentDelayedCrashWithBreakpointWatchpoint.py @@ -0,0 +1,23 @@ + +import unittest2 + +from lldbsuite.test.decorators import * +from lldbsuite.test.concurrent_base import ConcurrentEventsBase +from lldbsuite.test.lldbtest import TestBase + + +@skipIfWindows +class ConcurrentDelayedCrashWithBreakpointWatchpoint(ConcurrentEventsBase): + + mydir = ConcurrentEventsBase.compute_mydir(__file__) + + @skipIfFreeBSD # timing out on buildbot + # Atomic sequences are not supported yet for MIPS in LLDB. + @skipIf(triple='^mips') + @add_test_categories(["watchpoint"]) + def test(self): + """ Test a thread with a delayed crash while other threads hit a watchpoint and a breakpoint. """ + self.build(dictionary=self.getBuildFlags()) + self.do_thread_actions(num_delay_crash_threads=1, + num_breakpoint_threads=1, + num_watchpoint_threads=1) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentManyBreakpoints.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentManyBreakpoints.py new file mode 100644 index 00000000000..bbbfbdb0958 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentManyBreakpoints.py @@ -0,0 +1,20 @@ + +import unittest2 + +from lldbsuite.test.decorators import * +from lldbsuite.test.concurrent_base import ConcurrentEventsBase +from lldbsuite.test.lldbtest import TestBase + + +@skipIfWindows +class ConcurrentManyBreakpoints(ConcurrentEventsBase): + + mydir = ConcurrentEventsBase.compute_mydir(__file__) + + # Atomic sequences are not supported yet for MIPS in LLDB. + @skipIf(triple='^mips') + @skipIfOutOfTreeDebugserver + def test(self): + """Test 100 breakpoints from 100 threads.""" + self.build(dictionary=self.getBuildFlags()) + self.do_thread_actions(num_breakpoint_threads=100) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentManyCrash.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentManyCrash.py new file mode 100644 index 00000000000..0530728b6ac --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentManyCrash.py @@ -0,0 +1,20 @@ + +import unittest2 + +from lldbsuite.test.decorators import * +from lldbsuite.test.concurrent_base import ConcurrentEventsBase +from lldbsuite.test.lldbtest import TestBase + + +@skipIfWindows +class ConcurrentManyCrash(ConcurrentEventsBase): + + mydir = ConcurrentEventsBase.compute_mydir(__file__) + + # Atomic sequences are not supported yet for MIPS in LLDB. + @skipIf(triple='^mips') + @skipIfOutOfTreeDebugserver + def test(self): + """Test 100 threads that cause a segfault.""" + self.build(dictionary=self.getBuildFlags()) + self.do_thread_actions(num_crash_threads=100) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentManySignals.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentManySignals.py new file mode 100644 index 00000000000..ec06227ec54 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentManySignals.py @@ -0,0 +1,23 @@ + +import unittest2 + +from lldbsuite.test.decorators import * +from lldbsuite.test.concurrent_base import ConcurrentEventsBase +from lldbsuite.test.lldbtest import TestBase + + +@skipIfWindows +class ConcurrentManySignals(ConcurrentEventsBase): + + mydir = ConcurrentEventsBase.compute_mydir(__file__) + + # Atomic sequences are not supported yet for MIPS in LLDB. + @skipIf(triple='^mips') + # This test is flaky on Darwin. + @skipIfDarwin + @expectedFailureNetBSD + @skipIfOutOfTreeDebugserver + def test(self): + """Test 100 signals from 100 threads.""" + self.build(dictionary=self.getBuildFlags()) + self.do_thread_actions(num_signal_threads=100) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentManyWatchpoints.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentManyWatchpoints.py new file mode 100644 index 00000000000..2274fbb6d4a --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentManyWatchpoints.py @@ -0,0 +1,21 @@ + +import unittest2 + +from lldbsuite.test.decorators import * +from lldbsuite.test.concurrent_base import ConcurrentEventsBase +from lldbsuite.test.lldbtest import TestBase + + +@skipIfWindows +class ConcurrentManyWatchpoints(ConcurrentEventsBase): + + mydir = ConcurrentEventsBase.compute_mydir(__file__) + + # Atomic sequences are not supported yet for MIPS in LLDB. + @skipIf(triple='^mips') + @add_test_categories(["watchpoint"]) + @skipIfOutOfTreeDebugserver + def test(self): + """Test 100 watchpoints from 100 threads.""" + self.build(dictionary=self.getBuildFlags()) + self.do_thread_actions(num_watchpoint_threads=100) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentNWatchNBreak.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentNWatchNBreak.py new file mode 100644 index 00000000000..2c5205fc49f --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentNWatchNBreak.py @@ -0,0 +1,22 @@ + +import unittest2 + +from lldbsuite.test.decorators import * +from lldbsuite.test.concurrent_base import ConcurrentEventsBase +from lldbsuite.test.lldbtest import TestBase + + +@skipIfWindows +class ConcurrentNWatchNBreak(ConcurrentEventsBase): + + mydir = ConcurrentEventsBase.compute_mydir(__file__) + + @skipIfFreeBSD # timing out on buildbot + # Atomic sequences are not supported yet for MIPS in LLDB. + @skipIf(triple='^mips') + @add_test_categories(["watchpoint"]) + def test(self): + """Test with 5 watchpoint and breakpoint threads.""" + self.build(dictionary=self.getBuildFlags()) + self.do_thread_actions(num_watchpoint_threads=5, + num_breakpoint_threads=5) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentSignalBreak.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentSignalBreak.py new file mode 100644 index 00000000000..6c18cb2e965 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentSignalBreak.py @@ -0,0 +1,20 @@ + +import unittest2 + +from lldbsuite.test.decorators import * +from lldbsuite.test.concurrent_base import ConcurrentEventsBase +from lldbsuite.test.lldbtest import TestBase + + +@skipIfWindows +class ConcurrentSignalBreak(ConcurrentEventsBase): + + mydir = ConcurrentEventsBase.compute_mydir(__file__) + + @skipIfFreeBSD # timing out on buildbot + # Atomic sequences are not supported yet for MIPS in LLDB. + @skipIf(triple='^mips') + def test(self): + """Test signal and a breakpoint in multiple threads.""" + self.build(dictionary=self.getBuildFlags()) + self.do_thread_actions(num_breakpoint_threads=1, num_signal_threads=1) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentSignalDelayBreak.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentSignalDelayBreak.py new file mode 100644 index 00000000000..e1779b44f7c --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentSignalDelayBreak.py @@ -0,0 +1,23 @@ + +import unittest2 + +from lldbsuite.test.decorators import * +from lldbsuite.test.concurrent_base import ConcurrentEventsBase +from lldbsuite.test.lldbtest import TestBase + + +@skipIfWindows +class ConcurrentSignalDelayBreak(ConcurrentEventsBase): + + mydir = ConcurrentEventsBase.compute_mydir(__file__) + + @skipIfFreeBSD # timing out on buildbot + # Atomic sequences are not supported yet for MIPS in LLDB. + @skipIf(triple='^mips') + @expectedFailureNetBSD + def test(self): + """Test signal and a (1 second delay) breakpoint in multiple threads.""" + self.build(dictionary=self.getBuildFlags()) + self.do_thread_actions( + num_delay_breakpoint_threads=1, + num_signal_threads=1) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentSignalDelayWatch.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentSignalDelayWatch.py new file mode 100644 index 00000000000..d932d5f847b --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentSignalDelayWatch.py @@ -0,0 +1,24 @@ + +import unittest2 + +from lldbsuite.test.decorators import * +from lldbsuite.test.concurrent_base import ConcurrentEventsBase +from lldbsuite.test.lldbtest import TestBase + + +@skipIfWindows +class ConcurrentSignalDelayWatch(ConcurrentEventsBase): + + mydir = ConcurrentEventsBase.compute_mydir(__file__) + + @skipIfFreeBSD # timing out on buildbot + # Atomic sequences are not supported yet for MIPS in LLDB. + @skipIf(triple='^mips') + @expectedFailureNetBSD + @add_test_categories(["watchpoint"]) + def test(self): + """Test a (1 second delay) watchpoint and a signal in multiple threads.""" + self.build(dictionary=self.getBuildFlags()) + self.do_thread_actions( + num_signal_threads=1, + num_delay_watchpoint_threads=1) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentSignalNWatchNBreak.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentSignalNWatchNBreak.py new file mode 100644 index 00000000000..3b005e559a4 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentSignalNWatchNBreak.py @@ -0,0 +1,24 @@ + +import unittest2 + +from lldbsuite.test.decorators import * +from lldbsuite.test.concurrent_base import ConcurrentEventsBase +from lldbsuite.test.lldbtest import TestBase + + +@skipIfWindows +class ConcurrentSignalNWatchNBreak(ConcurrentEventsBase): + + mydir = ConcurrentEventsBase.compute_mydir(__file__) + + @skipIfFreeBSD # timing out on buildbot + # Atomic sequences are not supported yet for MIPS in LLDB. + @skipIf(triple='^mips') + @expectedFailureNetBSD + @add_test_categories(["watchpoint"]) + def test(self): + """Test one signal thread with 5 watchpoint and breakpoint threads.""" + self.build(dictionary=self.getBuildFlags()) + self.do_thread_actions(num_signal_threads=1, + num_watchpoint_threads=5, + num_breakpoint_threads=5) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentSignalWatch.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentSignalWatch.py new file mode 100644 index 00000000000..6cf26aea9e2 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentSignalWatch.py @@ -0,0 +1,21 @@ + +import unittest2 + +from lldbsuite.test.decorators import * +from lldbsuite.test.concurrent_base import ConcurrentEventsBase +from lldbsuite.test.lldbtest import TestBase + + +@skipIfWindows +class ConcurrentSignalWatch(ConcurrentEventsBase): + + mydir = ConcurrentEventsBase.compute_mydir(__file__) + + @skipIfFreeBSD # timing out on buildbot + # Atomic sequences are not supported yet for MIPS in LLDB. + @skipIf(triple='^mips') + @add_test_categories(["watchpoint"]) + def test(self): + """Test a watchpoint and a signal in multiple threads.""" + self.build(dictionary=self.getBuildFlags()) + self.do_thread_actions(num_signal_threads=1, num_watchpoint_threads=1) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentSignalWatchBreak.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentSignalWatchBreak.py new file mode 100644 index 00000000000..38a51258853 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentSignalWatchBreak.py @@ -0,0 +1,24 @@ + +import unittest2 + +from lldbsuite.test.decorators import * +from lldbsuite.test.concurrent_base import ConcurrentEventsBase +from lldbsuite.test.lldbtest import TestBase + + +@skipIfWindows +class ConcurrentSignalWatchBreak(ConcurrentEventsBase): + + mydir = ConcurrentEventsBase.compute_mydir(__file__) + + @skipIfFreeBSD # timing out on buildbot + # Atomic sequences are not supported yet for MIPS in LLDB. + @skipIf(triple='^mips') + @expectedFailureNetBSD + @add_test_categories(["watchpoint"]) + def test(self): + """Test a signal/watchpoint/breakpoint in multiple threads.""" + self.build(dictionary=self.getBuildFlags()) + self.do_thread_actions(num_signal_threads=1, + num_watchpoint_threads=1, + num_breakpoint_threads=1) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentTwoBreakpointThreads.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentTwoBreakpointThreads.py new file mode 100644 index 00000000000..5ddc15bd964 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentTwoBreakpointThreads.py @@ -0,0 +1,20 @@ + +import unittest2 + +from lldbsuite.test.decorators import * +from lldbsuite.test.concurrent_base import ConcurrentEventsBase +from lldbsuite.test.lldbtest import TestBase + + +@skipIfWindows +class ConcurrentTwoBreakpointThreads(ConcurrentEventsBase): + + mydir = ConcurrentEventsBase.compute_mydir(__file__) + + @skipIfFreeBSD # timing out on buildbot + # Atomic sequences are not supported yet for MIPS in LLDB. + @skipIf(triple='^mips') + def test(self): + """Test two threads that trigger a breakpoint. """ + self.build(dictionary=self.getBuildFlags()) + self.do_thread_actions(num_breakpoint_threads=2) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentTwoBreakpointsOneDelaySignal.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentTwoBreakpointsOneDelaySignal.py new file mode 100644 index 00000000000..07f99b0f82e --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentTwoBreakpointsOneDelaySignal.py @@ -0,0 +1,23 @@ + +import unittest2 + +from lldbsuite.test.decorators import * +from lldbsuite.test.concurrent_base import ConcurrentEventsBase +from lldbsuite.test.lldbtest import TestBase + + +@skipIfWindows +class ConcurrentTwoBreakpointsOneDelaySignal(ConcurrentEventsBase): + + mydir = ConcurrentEventsBase.compute_mydir(__file__) + + @skipIfFreeBSD # timing out on buildbot + # Atomic sequences are not supported yet for MIPS in LLDB. + @skipIf(triple='^mips') + @expectedFailureNetBSD + def test(self): + """Test two threads that trigger a breakpoint and one (1 second delay) signal thread. """ + self.build(dictionary=self.getBuildFlags()) + self.do_thread_actions( + num_breakpoint_threads=2, + num_delay_signal_threads=1) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentTwoBreakpointsOneSignal.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentTwoBreakpointsOneSignal.py new file mode 100644 index 00000000000..1ad1c591c7e --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentTwoBreakpointsOneSignal.py @@ -0,0 +1,21 @@ + +import unittest2 + +from lldbsuite.test.decorators import * +from lldbsuite.test.concurrent_base import ConcurrentEventsBase +from lldbsuite.test.lldbtest import TestBase + + +@skipIfWindows +class ConcurrentTwoBreakpointsOneSignal(ConcurrentEventsBase): + + mydir = ConcurrentEventsBase.compute_mydir(__file__) + + @skipIfFreeBSD # timing out on buildbot + # Atomic sequences are not supported yet for MIPS in LLDB. + @skipIf(triple='^mips') + @expectedFailureNetBSD + def test(self): + """Test two threads that trigger a breakpoint and one signal thread. """ + self.build(dictionary=self.getBuildFlags()) + self.do_thread_actions(num_breakpoint_threads=2, num_signal_threads=1) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentTwoBreakpointsOneWatchpoint.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentTwoBreakpointsOneWatchpoint.py new file mode 100644 index 00000000000..47e973a4871 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentTwoBreakpointsOneWatchpoint.py @@ -0,0 +1,23 @@ + +import unittest2 + +from lldbsuite.test.decorators import * +from lldbsuite.test.concurrent_base import ConcurrentEventsBase +from lldbsuite.test.lldbtest import TestBase + + +@skipIfWindows +class ConcurrentTwoBreakpointsOneWatchpoint(ConcurrentEventsBase): + + mydir = ConcurrentEventsBase.compute_mydir(__file__) + + @skipIfFreeBSD # timing out on buildbot + # Atomic sequences are not supported yet for MIPS in LLDB. + @skipIf(triple='^mips') + @add_test_categories(["watchpoint"]) + def test(self): + """Test two threads that trigger a breakpoint and one watchpoint thread. """ + self.build(dictionary=self.getBuildFlags()) + self.do_thread_actions( + num_breakpoint_threads=2, + num_watchpoint_threads=1) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentTwoWatchpointThreads.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentTwoWatchpointThreads.py new file mode 100644 index 00000000000..bdc6f8ef87e --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentTwoWatchpointThreads.py @@ -0,0 +1,21 @@ + +import unittest2 + +from lldbsuite.test.decorators import * +from lldbsuite.test.concurrent_base import ConcurrentEventsBase +from lldbsuite.test.lldbtest import TestBase + + +@skipIfWindows +class ConcurrentTwoWatchpointThreads(ConcurrentEventsBase): + + mydir = ConcurrentEventsBase.compute_mydir(__file__) + + @skipIfFreeBSD # timing out on buildbot + # Atomic sequences are not supported yet for MIPS in LLDB. + @skipIf(triple='^mips') + @add_test_categories(["watchpoint"]) + def test(self): + """Test two threads that trigger a watchpoint. """ + self.build(dictionary=self.getBuildFlags()) + self.do_thread_actions(num_watchpoint_threads=2) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentTwoWatchpointsOneBreakpoint.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentTwoWatchpointsOneBreakpoint.py new file mode 100644 index 00000000000..163f76d189b --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentTwoWatchpointsOneBreakpoint.py @@ -0,0 +1,23 @@ + +import unittest2 + +from lldbsuite.test.decorators import * +from lldbsuite.test.concurrent_base import ConcurrentEventsBase +from lldbsuite.test.lldbtest import TestBase + + +@skipIfWindows +class ConcurrentTwoWatchpointsOneBreakpoint(ConcurrentEventsBase): + + mydir = ConcurrentEventsBase.compute_mydir(__file__) + + @skipIfFreeBSD # timing out on buildbot + # Atomic sequences are not supported yet for MIPS in LLDB. + @skipIf(triple='^mips') + @add_test_categories(["watchpoint"]) + def test(self): + """Test two threads that trigger a watchpoint and one breakpoint thread. """ + self.build(dictionary=self.getBuildFlags()) + self.do_thread_actions( + num_watchpoint_threads=2, + num_breakpoint_threads=1) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentTwoWatchpointsOneDelayBreakpoint.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentTwoWatchpointsOneDelayBreakpoint.py new file mode 100644 index 00000000000..1ec5e065dc4 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentTwoWatchpointsOneDelayBreakpoint.py @@ -0,0 +1,23 @@ + +import unittest2 + +from lldbsuite.test.decorators import * +from lldbsuite.test.concurrent_base import ConcurrentEventsBase +from lldbsuite.test.lldbtest import TestBase + + +@skipIfWindows +class ConcurrentTwoWatchpointsOneDelayBreakpoint(ConcurrentEventsBase): + + mydir = ConcurrentEventsBase.compute_mydir(__file__) + + @skipIfFreeBSD # timing out on buildbot + # Atomic sequences are not supported yet for MIPS in LLDB. + @skipIf(triple='^mips') + @add_test_categories(["watchpoint"]) + def test(self): + """Test two threads that trigger a watchpoint and one (1 second delay) breakpoint thread. """ + self.build(dictionary=self.getBuildFlags()) + self.do_thread_actions( + num_watchpoint_threads=2, + num_delay_breakpoint_threads=1) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentTwoWatchpointsOneSignal.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentTwoWatchpointsOneSignal.py new file mode 100644 index 00000000000..8f044badf5e --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentTwoWatchpointsOneSignal.py @@ -0,0 +1,22 @@ + +import unittest2 + +from lldbsuite.test.decorators import * +from lldbsuite.test.concurrent_base import ConcurrentEventsBase +from lldbsuite.test.lldbtest import TestBase + + +@skipIfWindows +class ConcurrentTwoWatchpointsOneSignal(ConcurrentEventsBase): + + mydir = ConcurrentEventsBase.compute_mydir(__file__) + + @skipIfFreeBSD # timing out on buildbot + # Atomic sequences are not supported yet for MIPS in LLDB. + @skipIf(triple='^mips') + @expectedFailureNetBSD + @add_test_categories(["watchpoint"]) + def test(self): + """Test two threads that trigger a watchpoint and one signal thread. """ + self.build(dictionary=self.getBuildFlags()) + self.do_thread_actions(num_watchpoint_threads=2, num_signal_threads=1) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentWatchBreak.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentWatchBreak.py new file mode 100644 index 00000000000..4a418082ff0 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentWatchBreak.py @@ -0,0 +1,23 @@ + +import unittest2 + +from lldbsuite.test.decorators import * +from lldbsuite.test.concurrent_base import ConcurrentEventsBase +from lldbsuite.test.lldbtest import TestBase + + +@skipIfWindows +class ConcurrentWatchBreak(ConcurrentEventsBase): + + mydir = ConcurrentEventsBase.compute_mydir(__file__) + + @skipIfFreeBSD # timing out on buildbot + # Atomic sequences are not supported yet for MIPS in LLDB. + @skipIf(triple='^mips') + @add_test_categories(["watchpoint"]) + def test(self): + """Test watchpoint and a breakpoint in multiple threads.""" + self.build(dictionary=self.getBuildFlags()) + self.do_thread_actions( + num_breakpoint_threads=1, + num_watchpoint_threads=1) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentWatchBreakDelay.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentWatchBreakDelay.py new file mode 100644 index 00000000000..2bc08399322 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentWatchBreakDelay.py @@ -0,0 +1,23 @@ + +import unittest2 + +from lldbsuite.test.decorators import * +from lldbsuite.test.concurrent_base import ConcurrentEventsBase +from lldbsuite.test.lldbtest import TestBase + + +@skipIfWindows +class ConcurrentWatchBreakDelay(ConcurrentEventsBase): + + mydir = ConcurrentEventsBase.compute_mydir(__file__) + + @skipIfFreeBSD # timing out on buildbot + # Atomic sequences are not supported yet for MIPS in LLDB. + @skipIf(triple='^mips') + @add_test_categories(["watchpoint"]) + def test(self): + """Test watchpoint and a (1 second delay) breakpoint in multiple threads.""" + self.build(dictionary=self.getBuildFlags()) + self.do_thread_actions( + num_delay_breakpoint_threads=1, + num_watchpoint_threads=1) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentWatchpointDelayWatchpointOneBreakpoint.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentWatchpointDelayWatchpointOneBreakpoint.py new file mode 100644 index 00000000000..dce84fed775 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentWatchpointDelayWatchpointOneBreakpoint.py @@ -0,0 +1,23 @@ + +import unittest2 + +from lldbsuite.test.decorators import * +from lldbsuite.test.concurrent_base import ConcurrentEventsBase +from lldbsuite.test.lldbtest import TestBase + + +@skipIfWindows +class ConcurrentWatchpointDelayWatchpointOneBreakpoint(ConcurrentEventsBase): + + mydir = ConcurrentEventsBase.compute_mydir(__file__) + + @skipIfFreeBSD # timing out on buildbot + # Atomic sequences are not supported yet for MIPS in LLDB. + @skipIf(triple='^mips') + @add_test_categories(["watchpoint"]) + def test(self): + """Test two threads that trigger a watchpoint (one with a 1 second delay) and one breakpoint thread. """ + self.build(dictionary=self.getBuildFlags()) + self.do_thread_actions(num_watchpoint_threads=1, + num_delay_watchpoint_threads=1, + num_breakpoint_threads=1) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentWatchpointWithDelayWatchpointThreads.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentWatchpointWithDelayWatchpointThreads.py new file mode 100644 index 00000000000..87b8ea0d775 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentWatchpointWithDelayWatchpointThreads.py @@ -0,0 +1,22 @@ + +import unittest2 + +from lldbsuite.test.decorators import * +from lldbsuite.test.concurrent_base import ConcurrentEventsBase +from lldbsuite.test.lldbtest import TestBase + + +@skipIfWindows +class ConcurrentWatchpointWithDelayWatchpointThreads(ConcurrentEventsBase): + + mydir = ConcurrentEventsBase.compute_mydir(__file__) + + @skipIfFreeBSD # timing out on buildbot + # Atomic sequences are not supported yet for MIPS in LLDB. + @skipIf(triple='^mips') + @add_test_categories(["watchpoint"]) + def test(self): + """Test two threads that trigger a watchpoint where one thread has a 1 second delay. """ + self.build(dictionary=self.getBuildFlags()) + self.do_thread_actions(num_watchpoint_threads=1, + num_delay_watchpoint_threads=1) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/main.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/main.cpp new file mode 100644 index 00000000000..33ec8ad1f50 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/main.cpp @@ -0,0 +1,187 @@ +//===-- main.cpp ------------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// This test is intended to create a situation in which multiple events +// (breakpoints, watchpoints, crashes, and signal generation/delivery) happen +// from multiple threads. The test expects the debugger to set a breakpoint on +// the main thread (before any worker threads are spawned) and modify variables +// which control the number of threads that are spawned for each action. + +#include "pseudo_barrier.h" +#include <vector> +using namespace std; + +#include <pthread.h> + +#include <signal.h> +#include <sys/types.h> +#include <unistd.h> + +typedef std::vector<std::pair<unsigned, void*(*)(void*)> > action_counts; +typedef std::vector<pthread_t> thread_vector; + +pseudo_barrier_t g_barrier; +int g_breakpoint = 0; +int g_sigusr1_count = 0; +uint32_t g_watchme; + +struct action_args { + int delay; +}; + +// Perform any extra actions required by thread 'input' arg +void do_action_args(void *input) { + if (input) { + action_args *args = static_cast<action_args*>(input); + sleep(args->delay); + } +} + +void * +breakpoint_func (void *input) +{ + // Wait until all threads are running + pseudo_barrier_wait(g_barrier); + do_action_args(input); + + // Do something + g_breakpoint++; // Set breakpoint here + return 0; +} + +void * +signal_func (void *input) { + // Wait until all threads are running + pseudo_barrier_wait(g_barrier); + do_action_args(input); + + // Send a user-defined signal to the current process + //kill(getpid(), SIGUSR1); + // Send a user-defined signal to the current thread + pthread_kill(pthread_self(), SIGUSR1); + + return 0; +} + +void * +watchpoint_func (void *input) { + pseudo_barrier_wait(g_barrier); + do_action_args(input); + + g_watchme = 1; // watchpoint triggers here + return 0; +} + +void * +crash_func (void *input) { + pseudo_barrier_wait(g_barrier); + do_action_args(input); + + int *a = 0; + *a = 5; // crash happens here + return 0; +} + +void sigusr1_handler(int sig) { + if (sig == SIGUSR1) + g_sigusr1_count += 1; // Break here in signal handler +} + +/// Register a simple function for to handle signal +void register_signal_handler(int signal, void (*handler)(int)) +{ + sigset_t empty_sigset; + sigemptyset(&empty_sigset); + + struct sigaction action; + action.sa_sigaction = 0; + action.sa_mask = empty_sigset; + action.sa_flags = 0; + action.sa_handler = handler; + sigaction(SIGUSR1, &action, 0); +} + +void start_threads(thread_vector& threads, + action_counts& actions, + void* args = 0) { + action_counts::iterator b = actions.begin(), e = actions.end(); + for(action_counts::iterator i = b; i != e; ++i) { + for(unsigned count = 0; count < i->first; ++count) { + pthread_t t; + pthread_create(&t, 0, i->second, args); + threads.push_back(t); + } + } +} + +int dotest() +{ + g_watchme = 0; + + // Actions are triggered immediately after the thread is spawned + unsigned num_breakpoint_threads = 1; + unsigned num_watchpoint_threads = 0; + unsigned num_signal_threads = 1; + unsigned num_crash_threads = 0; + + // Actions below are triggered after a 1-second delay + unsigned num_delay_breakpoint_threads = 0; + unsigned num_delay_watchpoint_threads = 0; + unsigned num_delay_signal_threads = 0; + unsigned num_delay_crash_threads = 0; + + register_signal_handler(SIGUSR1, sigusr1_handler); // Break here and adjust num_[breakpoint|watchpoint|signal|crash]_threads + + unsigned total_threads = num_breakpoint_threads \ + + num_watchpoint_threads \ + + num_signal_threads \ + + num_crash_threads \ + + num_delay_breakpoint_threads \ + + num_delay_watchpoint_threads \ + + num_delay_signal_threads \ + + num_delay_crash_threads; + + // Don't let either thread do anything until they're both ready. + pseudo_barrier_init(g_barrier, total_threads); + + action_counts actions; + actions.push_back(std::make_pair(num_breakpoint_threads, breakpoint_func)); + actions.push_back(std::make_pair(num_watchpoint_threads, watchpoint_func)); + actions.push_back(std::make_pair(num_signal_threads, signal_func)); + actions.push_back(std::make_pair(num_crash_threads, crash_func)); + + action_counts delay_actions; + delay_actions.push_back(std::make_pair(num_delay_breakpoint_threads, breakpoint_func)); + delay_actions.push_back(std::make_pair(num_delay_watchpoint_threads, watchpoint_func)); + delay_actions.push_back(std::make_pair(num_delay_signal_threads, signal_func)); + delay_actions.push_back(std::make_pair(num_delay_crash_threads, crash_func)); + + // Create threads that handle instant actions + thread_vector threads; + start_threads(threads, actions); + + // Create threads that handle delayed actions + action_args delay_arg; + delay_arg.delay = 1; + start_threads(threads, delay_actions, &delay_arg); + + // Join all threads + typedef std::vector<pthread_t>::iterator thread_iterator; + for(thread_iterator t = threads.begin(); t != threads.end(); ++t) + pthread_join(*t, 0); + + return 0; +} + +int main () +{ + dotest(); + return 0; // Break here and verify one thread is active. +} + + diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/crash_during_step/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/crash_during_step/Makefile new file mode 100644 index 00000000000..3d0b98f13f3 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/crash_during_step/Makefile @@ -0,0 +1,2 @@ +CXX_SOURCES := main.cpp +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/crash_during_step/TestCrashDuringStep.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/crash_during_step/TestCrashDuringStep.py new file mode 100644 index 00000000000..3394bb2d6aa --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/crash_during_step/TestCrashDuringStep.py @@ -0,0 +1,61 @@ +""" +Test that step-inst over a crash behaves correctly. +""" + + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class CrashDuringStepTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + TestBase.setUp(self) + self.breakpoint = line_number('main.cpp', '// Set breakpoint here') + + # IO error due to breakpoint at invalid address + @expectedFailureAll(triple=re.compile('^mips')) + def test_step_inst_with(self): + """Test thread creation during step-inst handling.""" + self.build(dictionary=self.getBuildFlags()) + exe = self.getBuildArtifact("a.out") + + target = self.dbg.CreateTarget(exe) + self.assertTrue(target and target.IsValid(), "Target is valid") + + self.bp_num = lldbutil.run_break_set_by_file_and_line( + self, "main.cpp", self.breakpoint, num_expected_locations=1) + + # Run the program. + process = target.LaunchSimple( + None, None, self.get_process_working_directory()) + self.assertTrue(process and process.IsValid(), PROCESS_IS_VALID) + + # The stop reason should be breakpoint. + self.assertEqual( + process.GetState(), + lldb.eStateStopped, + PROCESS_STOPPED) + thread = lldbutil.get_stopped_thread( + process, lldb.eStopReasonBreakpoint) + self.assertTrue(thread.IsValid(), STOPPED_DUE_TO_BREAKPOINT) + + # Keep stepping until the inferior crashes + while process.GetState() == lldb.eStateStopped and not lldbutil.is_thread_crashed(self, thread): + thread.StepInstruction(False) + + self.assertEqual( + process.GetState(), + lldb.eStateStopped, + PROCESS_STOPPED) + self.assertTrue( + lldbutil.is_thread_crashed( + self, + thread), + "Thread has crashed") + process.Kill() diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/crash_during_step/main.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/crash_during_step/main.cpp new file mode 100644 index 00000000000..34cccf4dc2a --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/crash_during_step/main.cpp @@ -0,0 +1,15 @@ +//===-- main.cpp ------------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +void (*crash)() = nullptr; + +int main() +{ + crash(); // Set breakpoint here + return 0; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/create_after_attach/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/create_after_attach/Makefile new file mode 100644 index 00000000000..566938ca0cc --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/create_after_attach/Makefile @@ -0,0 +1,3 @@ +CXX_SOURCES := main.cpp +ENABLE_THREADS := YES +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/create_after_attach/TestCreateAfterAttach.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/create_after_attach/TestCreateAfterAttach.py new file mode 100644 index 00000000000..59fb3b6fd39 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/create_after_attach/TestCreateAfterAttach.py @@ -0,0 +1,128 @@ +""" +Test thread creation after process attach. +""" + + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class CreateAfterAttachTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + @skipIfFreeBSD # Hangs. May be the same as Linux issue llvm.org/pr16229 but + # not yet investigated. Revisit once required functionality + # is implemented for FreeBSD. + # Occasionally hangs on Windows, may be same as other issues. + @skipIfWindows + @skipIfiOSSimulator + @expectedFailureNetBSD + def test_create_after_attach_with_popen(self): + """Test thread creation after process attach.""" + self.build(dictionary=self.getBuildFlags(use_cpp11=False)) + self.create_after_attach(use_fork=False) + + @skipIfFreeBSD # Hangs. Revisit once required functionality is implemented + # for FreeBSD. + @skipIfRemote + @skipIfWindows # Windows doesn't have fork. + @skipIfiOSSimulator + @expectedFailureNetBSD + def test_create_after_attach_with_fork(self): + """Test thread creation after process attach.""" + self.build(dictionary=self.getBuildFlags(use_cpp11=False)) + self.create_after_attach(use_fork=True) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line numbers for our breakpoints. + 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.""" + + exe = self.getBuildArtifact("a.out") + + # Spawn a new process + if use_fork: + pid = self.forkSubprocess(exe) + else: + popen = self.spawnSubprocess(exe) + pid = popen.pid + self.addTearDownHook(self.cleanupSubprocesses) + + # Attach to the spawned process + self.runCmd("process attach -p " + str(pid)) + + target = self.dbg.GetSelectedTarget() + + process = target.GetProcess() + 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.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.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.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") + + # The stop reason of the thread should be breakpoint. + self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, + substrs=['stopped', + '* 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") + + # The stop reason of the thread should be breakpoint. + self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, + substrs=['stopped', + '* thread #', + 'thread_2_func', + 'stop reason = breakpoint']) + + # Change a variable to escape the loop + self.runCmd("expression child_thread_continue = 1") + + # Run to the third breakpoint + self.runCmd("continue") + + # 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 #', + 'thread_1_func', + 'stop reason = breakpoint']) + + # Run to completion + self.runCmd("continue") + + # At this point, the inferior process should have exited. + self.assertTrue( + process.GetState() == lldb.eStateExited, + PROCESS_EXITED) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/create_after_attach/main.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/create_after_attach/main.cpp new file mode 100644 index 00000000000..d8f06e55a2d --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/create_after_attach/main.cpp @@ -0,0 +1,61 @@ +#include <stdio.h> +#include <chrono> +#include <thread> + +using std::chrono::microseconds; + +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[]) +{ + lldb_enable_attach(); + + // 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"); +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/create_during_step/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/create_during_step/Makefile new file mode 100644 index 00000000000..566938ca0cc --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/create_during_step/Makefile @@ -0,0 +1,3 @@ +CXX_SOURCES := main.cpp +ENABLE_THREADS := YES +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/create_during_step/TestCreateDuringStep.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/create_during_step/TestCreateDuringStep.py new file mode 100644 index 00000000000..fa8c943836f --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/create_during_step/TestCreateDuringStep.py @@ -0,0 +1,154 @@ +""" +Test number of threads. +""" + + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class CreateDuringStepTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + @expectedFailureAll( + oslist=["linux"], + bugnumber="llvm.org/pr15824 thread states not properly maintained") + @expectedFailureAll( + oslist=lldbplatformutil.getDarwinOSTriples(), + bugnumber="llvm.org/pr15824 thread states not properly maintained, <rdar://problem/28557237>") + @expectedFailureAll( + oslist=["freebsd"], + bugnumber="llvm.org/pr18190 thread states not properly maintained") + @expectedFailureAll( + oslist=["windows"], + bugnumber="llvm.org/pr24668: Breakpoints not resolved correctly") + @expectedFailureNetBSD + def test_step_inst(self): + """Test thread creation during step-inst handling.""" + self.build(dictionary=self.getBuildFlags()) + self.create_during_step_base( + "thread step-inst -m all-threads", + 'stop reason = instruction step') + + @expectedFailureAll( + oslist=["linux"], + bugnumber="llvm.org/pr15824 thread states not properly maintained") + @expectedFailureAll( + oslist=lldbplatformutil.getDarwinOSTriples(), + bugnumber="llvm.org/pr15824 thread states not properly maintained, <rdar://problem/28557237>") + @expectedFailureAll( + oslist=["freebsd"], + bugnumber="llvm.org/pr18190 thread states not properly maintained") + @expectedFailureAll( + oslist=["windows"], + bugnumber="llvm.org/pr24668: Breakpoints not resolved correctly") + @expectedFailureNetBSD + def test_step_over(self): + """Test thread creation during step-over handling.""" + self.build(dictionary=self.getBuildFlags()) + self.create_during_step_base( + "thread step-over -m all-threads", + 'stop reason = step over') + + @expectedFailureAll( + oslist=["linux"], + bugnumber="llvm.org/pr15824 thread states not properly maintained") + @expectedFailureAll( + oslist=lldbplatformutil.getDarwinOSTriples(), + bugnumber="<rdar://problem/28574077>") + @expectedFailureAll( + oslist=["freebsd"], + bugnumber="llvm.org/pr18190 thread states not properly maintained") + @expectedFailureAll( + oslist=["windows"], + bugnumber="llvm.org/pr24668: Breakpoints not resolved correctly") + @expectedFailureNetBSD + def test_step_in(self): + """Test thread creation during step-in handling.""" + self.build(dictionary=self.getBuildFlags()) + self.create_during_step_base( + "thread step-in -m all-threads", + 'stop reason = step in') + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line numbers to break and continue. + self.breakpoint = line_number('main.cpp', '// Set breakpoint here') + self.continuepoint = line_number('main.cpp', '// Continue from here') + + def create_during_step_base(self, step_cmd, step_stop_reason): + """Test thread creation while using step-in.""" + exe = self.getBuildArtifact("a.out") + self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) + + # Get the target process + target = self.dbg.GetSelectedTarget() + + # This should create a breakpoint in the stepping thread. + self.bkpt = target.BreakpointCreateByLocation("main.cpp", self.breakpoint) + + # Run the program. + self.runCmd("run", RUN_SUCCEEDED) + + process = target.GetProcess() + + # The stop reason of the thread should be breakpoint. + stepping_thread = lldbutil.get_one_thread_stopped_at_breakpoint(process, self.bkpt) + self.assertTrue(stepping_thread.IsValid(), "We stopped at the right breakpoint") + + # Get the number of threads + num_threads = process.GetNumThreads() + + # Make sure we see only two threads + self.assertTrue( + num_threads == 2, + 'Number of expected threads and actual threads do not match.') + + # Get the thread objects + thread1 = process.GetThreadAtIndex(0) + thread2 = process.GetThreadAtIndex(1) + + current_line = self.breakpoint + # Keep stepping until we've reached our designated continue point + while current_line != self.continuepoint: + if stepping_thread != process.GetSelectedThread(): + process.SetSelectedThread(stepping_thread) + + self.runCmd(step_cmd) + + frame = stepping_thread.GetFrameAtIndex(0) + current_line = frame.GetLineEntry().GetLine() + + # Make sure we're still where we thought we were + self.assertTrue( + current_line >= self.breakpoint, + "Stepped to unexpected line, " + + str(current_line)) + self.assertTrue( + current_line <= self.continuepoint, + "Stepped to unexpected line, " + + str(current_line)) + + # Update the number of threads + num_threads = process.GetNumThreads() + + # Check to see that we increased the number of threads as expected + self.assertTrue( + num_threads == 3, + 'Number of expected threads and actual threads do not match after thread exit.') + + stop_reason = stepping_thread.GetStopReason() + self.assertEqual(stop_reason, lldb.eStopReasonPlanComplete, "Stopped for plan completion") + + # Run to completion + self.runCmd("process continue") + + # At this point, the inferior process should have exited. + self.assertTrue( + process.GetState() == lldb.eStateExited, + PROCESS_EXITED) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/create_during_step/main.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/create_during_step/main.cpp new file mode 100644 index 00000000000..d09bdb0ddfc --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/create_during_step/main.cpp @@ -0,0 +1,78 @@ +//===-- main.cpp ------------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// This test is intended to create a situation in which one thread will be +// created while the debugger is stepping in another thread. + +#include "pseudo_barrier.h" +#include <thread> + +#define do_nothing() + +pseudo_barrier_t g_barrier; + +volatile int g_thread_created = 0; +volatile int g_test = 0; + +void * +step_thread_func () +{ + g_test = 0; // Set breakpoint here + + while (!g_thread_created) + g_test++; + + // One more time to provide a continue point + g_test++; // Continue from here + + // Return + return NULL; +} + +void * +create_thread_func (void *input) +{ + std::thread *step_thread = (std::thread*)input; + + // Wait until the main thread knows this thread is started. + pseudo_barrier_wait(g_barrier); + + // Wait until the other thread is done. + step_thread->join(); + + // Return + return NULL; +} + +int main () +{ + // Use a simple count to simulate a barrier. + pseudo_barrier_init(g_barrier, 2); + + // Create a thread to hit the breakpoint. + std::thread thread_1(step_thread_func); + + // Wait until the step thread is stepping + while (g_test < 1) + do_nothing(); + + // Create a thread to exit while we're stepping. + std::thread thread_2(create_thread_func, &thread_1); + + // Wait until that thread is started + pseudo_barrier_wait(g_barrier); + + // Let the stepping thread know the other thread is there + g_thread_created = 1; + + // Wait for the threads to finish. + thread_2.join(); + thread_1.join(); + + return 0; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/exit_during_break/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/exit_during_break/Makefile new file mode 100644 index 00000000000..566938ca0cc --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/exit_during_break/Makefile @@ -0,0 +1,3 @@ +CXX_SOURCES := main.cpp +ENABLE_THREADS := YES +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/exit_during_break/TestExitDuringBreak.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/exit_during_break/TestExitDuringBreak.py new file mode 100644 index 00000000000..130abfe8652 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/exit_during_break/TestExitDuringBreak.py @@ -0,0 +1,63 @@ +""" +Test number of threads. +""" + + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class ExitDuringBreakpointTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line number for our breakpoint. + self.breakpoint = line_number('main.cpp', '// Set breakpoint here') + + def test(self): + """Test thread exit during breakpoint handling.""" + self.build(dictionary=self.getBuildFlags()) + exe = self.getBuildArtifact("a.out") + self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) + + # This should create a breakpoint in the main thread. + lldbutil.run_break_set_by_file_and_line( + self, "main.cpp", self.breakpoint, num_expected_locations=1) + + # Run the program. + self.runCmd("run", RUN_SUCCEEDED) + + # The stop reason of the thread should be breakpoint. + self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, + substrs=['stopped', + 'stop reason = breakpoint']) + + # Get the target process + target = self.dbg.GetSelectedTarget() + process = target.GetProcess() + + # The exit probably occurred during breakpoint handling, but it isn't + # guaranteed. The main thing we're testing here is that the debugger + # handles this cleanly is some way. + + # Get the number of threads + num_threads = process.GetNumThreads() + + # Make sure we see at least five threads + self.assertTrue( + num_threads >= 5, + 'Number of expected threads and actual threads do not match.') + + # Run to completion + self.runCmd("continue") + + # At this point, the inferior process should have exited. + self.assertTrue( + process.GetState() == lldb.eStateExited, + PROCESS_EXITED) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/exit_during_break/main.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/exit_during_break/main.cpp new file mode 100644 index 00000000000..ec28678c5d6 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/exit_during_break/main.cpp @@ -0,0 +1,117 @@ +//===-- main.cpp ------------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// 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 except the one that will exit. +pseudo_barrier_t g_barrier1; + +// A barrier to synchronize all the threads including the one that will exit. +pseudo_barrier_t g_barrier2; + +// A barrier to keep the first group of threads from exiting until after the +// breakpoint has been passed. +pseudo_barrier_t g_barrier3; + +void * +break_thread_func () +{ + // Wait until the entire first group of threads is running + pseudo_barrier_wait(g_barrier1); + + // Wait for the exiting thread to start + pseudo_barrier_wait(g_barrier2); + + // Do something + g_test++; // Set breakpoint here + + // Synchronize after the breakpoint + pseudo_barrier_wait(g_barrier3); + + // Return + return NULL; +} + +void * +wait_thread_func () +{ + // Wait until the entire first group of threads is running + pseudo_barrier_wait(g_barrier1); + + // Wait for the exiting thread to start + pseudo_barrier_wait(g_barrier2); + + // Wait until the breakpoint has been passed + pseudo_barrier_wait(g_barrier3); + + // Return + return NULL; +} + +void * +exit_thread_func () +{ + // Sync up with the rest of the threads. + pseudo_barrier_wait(g_barrier2); + + // Try to make sure this thread doesn't exit until the breakpoint is hit. + std::this_thread::sleep_for(std::chrono::microseconds(1)); + + // Return + return NULL; +} + +int main () +{ + + // The first barrier waits for the non-exiting threads to start. + // This thread will also participate in that barrier. + // The idea here is to guarantee that the exiting thread will be + // last in the internal list maintained by the debugger. + pseudo_barrier_init(g_barrier1, 5); + + // The second break synchronizes thread execution with the breakpoint. + pseudo_barrier_init(g_barrier2, 5); + + // The third barrier keeps the waiting threads around until the breakpoint + // has been passed. + pseudo_barrier_init(g_barrier3, 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); + + // Wait for all these threads to get started. + pseudo_barrier_wait(g_barrier1); + + // Create a thread to exit during the breakpoint + std::thread thread_5(exit_thread_func); + + // Wait for the threads to finish + thread_5.join(); + thread_4.join(); + thread_3.join(); + thread_2.join(); + thread_1.join(); + + return 0; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/exit_during_step/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/exit_during_step/Makefile new file mode 100644 index 00000000000..ebecfbf9241 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/exit_during_step/Makefile @@ -0,0 +1,3 @@ +ENABLE_THREADS := YES +CXX_SOURCES := main.cpp +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/exit_during_step/TestExitDuringStep.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/exit_during_step/TestExitDuringStep.py new file mode 100644 index 00000000000..d35bd45fe80 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/exit_during_step/TestExitDuringStep.py @@ -0,0 +1,150 @@ +""" +Test number of threads. +""" + + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class ExitDuringStepTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + @skipIfFreeBSD # llvm.org/pr21411: test is hanging + @skipIfWindows # This is flakey on Windows: llvm.org/pr38373 + def test(self): + """Test thread exit during step handling.""" + self.build(dictionary=self.getBuildFlags()) + self.exit_during_step_base( + "thread step-inst -m all-threads", + 'stop reason = instruction step', + True) + + @skipIfFreeBSD # llvm.org/pr21411: test is hanging + @skipIfWindows # This is flakey on Windows: llvm.org/pr38373 + def test_step_over(self): + """Test thread exit during step-over handling.""" + self.build(dictionary=self.getBuildFlags()) + self.exit_during_step_base( + "thread step-over -m all-threads", + 'stop reason = step over', + False) + + @skipIfFreeBSD # llvm.org/pr21411: test is hanging + @skipIfWindows # This is flakey on Windows: llvm.org/pr38373 + def test_step_in(self): + """Test thread exit during step-in handling.""" + self.build(dictionary=self.getBuildFlags()) + self.exit_during_step_base( + "thread step-in -m all-threads", + 'stop reason = step in', + False) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line numbers to break and continue. + self.breakpoint = line_number('main.cpp', '// Set breakpoint here') + self.continuepoint = line_number('main.cpp', '// Continue from here') + + def exit_during_step_base(self, step_cmd, step_stop_reason, by_instruction): + """Test thread exit during step handling.""" + exe = self.getBuildArtifact("a.out") + self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) + + # This should create a breakpoint in the main thread. + self.bp_num = lldbutil.run_break_set_by_file_and_line( + self, "main.cpp", self.breakpoint, num_expected_locations=1) + + # The breakpoint list should show 1 location. + self.expect( + "breakpoint list -f", + "Breakpoint location shown correctly", + substrs=[ + "1: file = 'main.cpp', line = %d, exact_match = 0, locations = 1" % + self.breakpoint]) + + # Run the program. + self.runCmd("run", RUN_SUCCEEDED) + + # The stop reason of the thread should be breakpoint. + self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, + substrs=['stopped', + 'stop reason = breakpoint']) + + # Get the target process + target = self.dbg.GetSelectedTarget() + process = target.GetProcess() + + num_threads = process.GetNumThreads() + # Make sure we see all three threads + self.assertGreaterEqual( + num_threads, + 3, + 'Number of expected threads and actual threads do not match.') + + stepping_thread = lldbutil.get_one_thread_stopped_at_breakpoint_id( + process, self.bp_num) + self.assertIsNotNone( + stepping_thread, + "Could not find a thread stopped at the breakpoint") + + current_line = self.breakpoint + stepping_frame = stepping_thread.GetFrameAtIndex(0) + self.assertEqual( + current_line, + stepping_frame.GetLineEntry().GetLine(), + "Starting line for stepping doesn't match breakpoint line.") + + # Keep stepping until we've reached our designated continue point + while current_line != self.continuepoint: + # Since we're using the command interpreter to issue the thread command + # (on the selected thread) we need to ensure the selected thread is the + # stepping thread. + if stepping_thread != process.GetSelectedThread(): + process.SetSelectedThread(stepping_thread) + + self.runCmd(step_cmd) + + frame = stepping_thread.GetFrameAtIndex(0) + + current_line = frame.GetLineEntry().GetLine() + + if by_instruction and current_line == 0: + continue + + self.assertGreaterEqual( + current_line, + self.breakpoint, + "Stepped to unexpected line, " + + str(current_line)) + self.assertLessEqual( + current_line, + self.continuepoint, + "Stepped to unexpected line, " + + str(current_line)) + + self.runCmd("thread list") + + # Update the number of threads + new_num_threads = process.GetNumThreads() + + # Check to see that we reduced the number of threads as expected + self.assertEqual( + new_num_threads, + num_threads - 1, + 'Number of threads did not reduce by 1 after thread exit.') + + self.expect("thread list", 'Process state is stopped due to step', + substrs=['stopped', + step_stop_reason]) + + # Run to completion + self.runCmd("continue") + + # At this point, the inferior process should have exited. + self.assertEqual(process.GetState(), lldb.eStateExited, PROCESS_EXITED) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/exit_during_step/main.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/exit_during_step/main.cpp new file mode 100644 index 00000000000..0e2ae00576c --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/exit_during_step/main.cpp @@ -0,0 +1,77 @@ +//===-- main.cpp ------------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// This test is intended to create a situation in which one thread will exit +// while the debugger is stepping in another thread. + +#include "pseudo_barrier.h" +#include <thread> + +#define do_nothing() + +// A barrier to synchronize thread start. +pseudo_barrier_t g_barrier; + +volatile int g_thread_exited = 0; + +volatile int g_test = 0; + +void * +step_thread_func () +{ + // Wait until both threads are started. + pseudo_barrier_wait(g_barrier); + + g_test = 0; // Set breakpoint here + + while (!g_thread_exited) + g_test++; + + // One more time to provide a continue point + g_test++; // Continue from here + + // Return + return NULL; +} + +void * +exit_thread_func () +{ + // Wait until both threads are started. + pseudo_barrier_wait(g_barrier); + + // Wait until the other thread is stepping. + while (g_test == 0) + do_nothing(); + + // Return + return NULL; +} + +int main () +{ + // Synchronize thread start so that doesn't happen during stepping. + pseudo_barrier_init(g_barrier, 2); + + // Create a thread to hit the breakpoint. + std::thread thread_1(step_thread_func); + + // Create a thread to exit while we're stepping. + std::thread thread_2(exit_thread_func); + + // Wait for the exit thread to finish. + thread_2.join(); + + // Let the stepping thread know the other thread is gone. + g_thread_exited = 1; + + // Wait for the stepping thread to finish. + thread_1.join(); + + return 0; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/jump/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/jump/Makefile new file mode 100644 index 00000000000..6e962b97209 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/jump/Makefile @@ -0,0 +1,3 @@ +ENABLE_THREADS := YES +CXX_SOURCES := main.cpp other.cpp +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/jump/TestThreadJump.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/jump/TestThreadJump.py new file mode 100644 index 00000000000..2035435442f --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/jump/TestThreadJump.py @@ -0,0 +1,78 @@ +""" +Test jumping to different places. +""" + + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class ThreadJumpTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def test(self): + """Test thread jump handling.""" + self.build(dictionary=self.getBuildFlags()) + exe = self.getBuildArtifact("a.out") + self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) + + # Find the line numbers for our breakpoints. + self.mark1 = line_number('main.cpp', '// 1st marker') + self.mark2 = line_number('main.cpp', '// 2nd marker') + self.mark3 = line_number('main.cpp', '// 3rd marker') + self.mark4 = line_number('main.cpp', '// 4th marker') + self.mark5 = line_number('other.cpp', '// other marker') + + lldbutil.run_break_set_by_file_and_line( + self, "main.cpp", self.mark3, num_expected_locations=1) + self.runCmd("run", RUN_SUCCEEDED) + + # The stop reason of the thread should be breakpoint 1. + self.expect( + "thread list", + STOPPED_DUE_TO_BREAKPOINT + " 1", + substrs=[ + 'stopped', + 'main.cpp:{}'.format( + self.mark3), + 'stop reason = breakpoint 1']) + + # Try the int path, force it to return 'a' + self.do_min_test(self.mark3, self.mark1, "i", "4") + # Try the int path, force it to return 'b' + self.do_min_test(self.mark3, self.mark2, "i", "5") + # Try the double path, force it to return 'a' + self.do_min_test(self.mark4, self.mark1, "j", "7") + # Expected to fail on powerpc64le architecture + if not self.isPPC64le(): + # Try the double path, force it to return 'b' + self.do_min_test(self.mark4, self.mark2, "j", "8") + + # Try jumping to another function in a different file. + self.runCmd( + "thread jump --file other.cpp --line %i --force" % + self.mark5) + self.expect("process status", + substrs=["at other.cpp:%i" % self.mark5]) + + # Try jumping to another function (without forcing) + self.expect( + "j main.cpp:%i" % + self.mark1, + COMMAND_FAILED_AS_EXPECTED, + error=True, + substrs=["error"]) + + def do_min_test(self, start, jump, var, value): + # jump to the start marker + self.runCmd("j %i" % start) + self.runCmd("thread step-in") # step into the min fn + # jump to the branch we're interested in + self.runCmd("j %i" % jump) + self.runCmd("thread step-out") # return out + self.runCmd("thread step-over") # assign to the global + self.expect("expr %s" % var, substrs=[value]) # check it diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/jump/main.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/jump/main.cpp new file mode 100644 index 00000000000..e0580bd2542 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/jump/main.cpp @@ -0,0 +1,34 @@ +//===-- main.cpp ------------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// This test verifies the correct handling of program counter jumps. + +int otherfn(); + +template<typename T> +T min(T a, T b) +{ + if (a < b) + { + return a; // 1st marker + } else { + return b; // 2nd marker + } +} + +int main () +{ + int i; + double j; + int min_i_a = 4, min_i_b = 5; + double min_j_a = 7.0, min_j_b = 8.0; + i = min(min_i_a, min_i_b); // 3rd marker + j = min(min_j_a, min_j_b); // 4th marker + + return 0; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/jump/other.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/jump/other.cpp new file mode 100644 index 00000000000..3ce9ad6548b --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/jump/other.cpp @@ -0,0 +1,12 @@ +//===-- other.cpp -----------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +int otherfn() +{ + return 4; // other marker +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/multi_break/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/multi_break/Makefile new file mode 100644 index 00000000000..566938ca0cc --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/multi_break/Makefile @@ -0,0 +1,3 @@ +CXX_SOURCES := main.cpp +ENABLE_THREADS := YES +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/multi_break/TestMultipleBreakpoints.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/multi_break/TestMultipleBreakpoints.py new file mode 100644 index 00000000000..20645fbc63e --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/multi_break/TestMultipleBreakpoints.py @@ -0,0 +1,90 @@ +""" +Test number of threads. +""" + + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class MultipleBreakpointTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line number for our breakpoint. + self.breakpoint = line_number('main.cpp', '// Set breakpoint here') + + @expectedFailureAll( + oslist=["linux"], + bugnumber="llvm.org/pr15824 thread states not properly maintained") + @expectedFailureAll( + oslist=lldbplatformutil.getDarwinOSTriples(), + bugnumber="llvm.org/pr15824 thread states not properly maintained and <rdar://problem/28557237>") + @expectedFailureAll( + oslist=["freebsd"], + bugnumber="llvm.org/pr18190 thread states not properly maintained") + @skipIfWindows # This is flakey on Windows: llvm.org/pr24668, llvm.org/pr38373 + @expectedFailureNetBSD + def test(self): + """Test simultaneous breakpoints in multiple threads.""" + self.build(dictionary=self.getBuildFlags()) + exe = self.getBuildArtifact("a.out") + self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) + + # This should create a breakpoint in the main thread. + lldbutil.run_break_set_by_file_and_line( + self, "main.cpp", self.breakpoint, num_expected_locations=1) + + # Run the program. + self.runCmd("run", RUN_SUCCEEDED) + + # The stop reason of the thread should be breakpoint. + # The breakpoint may be hit in either thread 2 or thread 3. + self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, + substrs=['stopped', + 'stop reason = breakpoint']) + + # Get the target process + target = self.dbg.GetSelectedTarget() + process = target.GetProcess() + + # Get the number of threads + num_threads = process.GetNumThreads() + + # Make sure we see all three threads + self.assertTrue( + num_threads >= 3, + '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) + + # Make sure both threads are stopped + self.assertTrue( + thread1.IsStopped(), + "Primary thread didn't stop during breakpoint") + self.assertTrue( + thread2.IsStopped(), + "Secondary thread didn't stop during breakpoint") + self.assertTrue( + thread3.IsStopped(), + "Tertiary thread didn't stop during breakpoint") + + # Delete the first breakpoint then continue + self.runCmd("breakpoint delete 1") + + # Run to completion + self.runCmd("continue") + + # At this point, the inferior process should have exited. + self.assertTrue( + process.GetState() == lldb.eStateExited, + PROCESS_EXITED) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/multi_break/main.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/multi_break/main.cpp new file mode 100644 index 00000000000..5f884d75866 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/multi_break/main.cpp @@ -0,0 +1,48 @@ +//===-- main.cpp ------------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// This test is intended to create a situation in which a breakpoint will be +// hit in two threads at nearly the same moment. The expected result is that +// the breakpoint in the second thread will be hit while the breakpoint handler +// in the first thread is trying to stop all threads. + +#include "pseudo_barrier.h" +#include <thread> + +pseudo_barrier_t g_barrier; + +volatile int g_test = 0; + +void * +thread_func () +{ + // Wait until both threads are running + pseudo_barrier_wait(g_barrier); + + // Do something + g_test++; // Set breakpoint here + + // Return + return NULL; +} + +int main () +{ + // Don't let either thread do anything until they're both ready. + pseudo_barrier_init(g_barrier, 2); + + // Create two threads + std::thread thread_1(thread_func); + std::thread thread_2(thread_func); + + // Wait for the threads to finish + thread_1.join(); + thread_2.join(); + + return 0; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/num_threads/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/num_threads/Makefile new file mode 100644 index 00000000000..566938ca0cc --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/num_threads/Makefile @@ -0,0 +1,3 @@ +CXX_SOURCES := main.cpp +ENABLE_THREADS := YES +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/num_threads/TestNumThreads.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/num_threads/TestNumThreads.py new file mode 100644 index 00000000000..cfd2941ad19 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/num_threads/TestNumThreads.py @@ -0,0 +1,123 @@ +""" +Test number of threads. +""" + + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +import lldbsuite.test.lldbutil as lldbutil + + +class NumberOfThreadsTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + NO_DEBUG_INFO_TESTCASE = True + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line numbers for our break points. + self.thread3_notify_all_line = line_number('main.cpp', '// Set thread3 break point on notify_all at this line.') + self.thread3_before_lock_line = line_number('main.cpp', '// thread3-before-lock') + + def test_number_of_threads(self): + """Test number of threads.""" + self.build() + exe = self.getBuildArtifact("a.out") + 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.cpp", self.thread3_notify_all_line, num_expected_locations=1) + + # The breakpoint list should show 1 location. + self.expect( + "breakpoint list -f", + "Breakpoint location shown correctly", + substrs=[ + "1: file = 'main.cpp', line = %d, exact_match = 0, locations = 1" % + self.thread3_notify_all_line]) + + # Run the program. + self.runCmd("run", RUN_SUCCEEDED) + + # Stopped once. + self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, + substrs=["stop reason = breakpoint 1."]) + + # Get the target process + target = self.dbg.GetSelectedTarget() + process = target.GetProcess() + + # Get the number of threads + num_threads = process.GetNumThreads() + + # Using std::thread may involve extra threads, so we assert that there are + # at least 4 rather than exactly 4. + self.assertTrue( + num_threads >= 13, + 'Number of expected threads and actual threads do not match.') + + @skipIfDarwin # rdar://33462362 + @skipIfWindows # This is flakey on Windows: llvm.org/pr37658, llvm.org/pr38373 + @expectedFailureNetBSD + def test_unique_stacks(self): + """Test backtrace unique with multiple threads executing the same stack.""" + self.build() + exe = self.getBuildArtifact("a.out") + self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) + + # Set a break point on the thread3 notify all (should get hit on threads 4-13). + lldbutil.run_break_set_by_file_and_line( + self, "main.cpp", self.thread3_before_lock_line, num_expected_locations=1) + + # Run the program. + self.runCmd("run", RUN_SUCCEEDED) + + # Stopped once. + self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, + substrs=["stop reason = breakpoint 1."]) + + process = self.process() + + # Get the number of threads + num_threads = process.GetNumThreads() + + # Using std::thread may involve extra threads, so we assert that there are + # at least 10 thread3's rather than exactly 10. + self.assertTrue( + num_threads >= 10, + 'Number of expected threads and actual threads do not match.') + + # Attempt to walk each of the thread's executing the thread3 function to + # the same breakpoint. + def is_thread3(thread): + for frame in thread: + if "thread3" in frame.GetFunctionName(): return True + return False + + expect_threads = "" + for i in range(num_threads): + thread = process.GetThreadAtIndex(i) + self.assertTrue(thread.IsValid()) + if not is_thread3(thread): + continue + + # If we aren't stopped out the thread breakpoint try to resume. + if thread.GetStopReason() != lldb.eStopReasonBreakpoint: + self.runCmd("thread continue %d"%(i+1)) + self.assertEqual(thread.GetStopReason(), lldb.eStopReasonBreakpoint) + + expect_threads += " #%d"%(i+1) + + # Construct our expected back trace string + expect_string = "10 thread(s)%s" % (expect_threads) + + # Now that we are stopped, we should have 10 threads waiting in the + # thread3 function. All of these threads should show as one stack. + self.expect("thread backtrace unique", + "Backtrace with unique stack shown correctly", + substrs=[expect_string, + "main.cpp:%d"%self.thread3_before_lock_line]) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/num_threads/main.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/num_threads/main.cpp new file mode 100644 index 00000000000..fdc060d135d --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/num_threads/main.cpp @@ -0,0 +1,65 @@ +#include "pseudo_barrier.h" +#include <condition_variable> +#include <mutex> +#include <thread> +#include <vector> + +std::mutex mutex; +std::condition_variable cond; +pseudo_barrier_t thread3_barrier; + +void * +thread3(void *input) +{ + pseudo_barrier_wait(thread3_barrier); + + int dummy = 47; // thread3-before-lock + + std::unique_lock<std::mutex> lock(mutex); + cond.notify_all(); // Set thread3 break point on notify_all at this line. + return NULL; +} + +void * +thread2(void *input) +{ + std::unique_lock<std::mutex> lock(mutex); + cond.notify_all(); // release main thread + 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); // wait for thread2 + + pseudo_barrier_init(thread3_barrier, 10); + + std::vector<std::thread> thread_3s; + for (int i = 0; i < 10; i++) { + thread_3s.push_back(std::thread(thread3, nullptr)); + } + + cond.wait(lock); // wait for thread_3s + + lock.unlock(); + + thread_1.join(); + for (auto &t : thread_3s){ + t.join(); + } + + return 0; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/state/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/state/Makefile new file mode 100644 index 00000000000..3d0b98f13f3 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/state/Makefile @@ -0,0 +1,2 @@ +CXX_SOURCES := main.cpp +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/state/TestThreadStates.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/state/TestThreadStates.py new file mode 100644 index 00000000000..60938088c9a --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/state/TestThreadStates.py @@ -0,0 +1,326 @@ +""" +Test thread states. +""" + + + +import unittest2 +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class ThreadStateTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + @expectedFailureAll( + oslist=["linux"], + bugnumber="llvm.org/pr15824 thread states not properly maintained") + @skipIfDarwin # llvm.org/pr15824 thread states not properly maintained and <rdar://problem/28557237> + @expectedFailureAll( + oslist=["freebsd"], + bugnumber="llvm.org/pr18190 thread states not properly maintained") + @expectedFailureNetBSD + def test_state_after_breakpoint(self): + """Test thread state after breakpoint.""" + self.build(dictionary=self.getBuildFlags(use_cpp11=False)) + self.thread_state_after_breakpoint_test() + + @skipIfDarwin # 'llvm.org/pr23669', cause Python crash randomly + @expectedFailureAll( + oslist=lldbplatformutil.getDarwinOSTriples(), + bugnumber="llvm.org/pr23669") + @expectedFailureAll(oslist=["freebsd"], bugnumber="llvm.org/pr15824") + @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24660") + def test_state_after_continue(self): + """Test thread state after continue.""" + self.build(dictionary=self.getBuildFlags(use_cpp11=False)) + self.thread_state_after_continue_test() + + @skipIfDarwin # 'llvm.org/pr23669', cause Python crash randomly + @expectedFailureDarwin('llvm.org/pr23669') + @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24660") + @expectedFailureNetBSD + # thread states not properly maintained + @unittest2.expectedFailure("llvm.org/pr16712") + def test_state_after_expression(self): + """Test thread state after expression.""" + self.build(dictionary=self.getBuildFlags(use_cpp11=False)) + self.thread_state_after_expression_test() + + # thread states not properly maintained + @unittest2.expectedFailure("llvm.org/pr15824 and <rdar://problem/28557237>") + @expectedFailureAll( + oslist=["windows"], + bugnumber="llvm.org/pr24668: Breakpoints not resolved correctly") + @skipIfDarwin # llvm.org/pr15824 thread states not properly maintained and <rdar://problem/28557237> + @expectedFailureNetBSD + def test_process_state(self): + """Test thread states (comprehensive).""" + self.build(dictionary=self.getBuildFlags(use_cpp11=False)) + self.thread_states_test() + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line numbers for our breakpoints. + self.break_1 = line_number('main.cpp', '// Set first breakpoint here') + self.break_2 = line_number('main.cpp', '// Set second breakpoint here') + + def thread_state_after_breakpoint_test(self): + """Test thread state after breakpoint.""" + exe = self.getBuildArtifact("a.out") + self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) + + # This should create a breakpoint in the main thread. + bp = lldbutil.run_break_set_by_file_and_line( + self, "main.cpp", self.break_1, num_expected_locations=1) + + # Run the program. + self.runCmd("run", RUN_SUCCEEDED) + + # Get the target process + target = self.dbg.GetSelectedTarget() + process = target.GetProcess() + + thread = lldbutil.get_stopped_thread( + process, lldb.eStopReasonBreakpoint) + self.assertIsNotNone(thread) + + # Make sure the thread is in the stopped state. + self.assertTrue( + thread.IsStopped(), + "Thread state isn't \'stopped\' during breakpoint 1.") + self.assertFalse(thread.IsSuspended(), + "Thread state is \'suspended\' during breakpoint 1.") + + # Kill the process + self.runCmd("process kill") + + def wait_for_running_event(self, process): + listener = self.dbg.GetListener() + if lldb.remote_platform: + lldbutil.expect_state_changes( + self, listener, process, [ + lldb.eStateConnected]) + lldbutil.expect_state_changes( + self, listener, process, [ + lldb.eStateRunning]) + + def thread_state_after_continue_test(self): + """Test thread state after continue.""" + exe = self.getBuildArtifact("a.out") + self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) + + # This should create a breakpoint in the main thread. + lldbutil.run_break_set_by_file_and_line( + self, "main.cpp", self.break_1, num_expected_locations=1) + lldbutil.run_break_set_by_file_and_line( + self, "main.cpp", self.break_2, num_expected_locations=1) + + # Run the program. + self.runCmd("run", RUN_SUCCEEDED) + + # Get the target process + target = self.dbg.GetSelectedTarget() + process = target.GetProcess() + + thread = lldbutil.get_stopped_thread( + process, lldb.eStopReasonBreakpoint) + self.assertIsNotNone(thread) + + # Continue, the inferior will go into an infinite loop waiting for + # 'g_test' to change. + self.dbg.SetAsync(True) + self.runCmd("continue") + self.wait_for_running_event(process) + + # Check the thread state. It should be running. + self.assertFalse( + thread.IsStopped(), + "Thread state is \'stopped\' when it should be running.") + self.assertFalse( + thread.IsSuspended(), + "Thread state is \'suspended\' when it should be running.") + + # Go back to synchronous interactions + self.dbg.SetAsync(False) + + # Kill the process + self.runCmd("process kill") + + def thread_state_after_expression_test(self): + """Test thread state after expression.""" + exe = self.getBuildArtifact("a.out") + self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) + + # This should create a breakpoint in the main thread. + lldbutil.run_break_set_by_file_and_line( + self, "main.cpp", self.break_1, num_expected_locations=1) + lldbutil.run_break_set_by_file_and_line( + self, "main.cpp", self.break_2, num_expected_locations=1) + + # Run the program. + self.runCmd("run", RUN_SUCCEEDED) + + # Get the target process + target = self.dbg.GetSelectedTarget() + process = target.GetProcess() + + thread = lldbutil.get_stopped_thread( + process, lldb.eStopReasonBreakpoint) + self.assertIsNotNone(thread) + + # Get the inferior out of its loop + self.runCmd("expression g_test = 1") + + # Check the thread state + self.assertTrue( + thread.IsStopped(), + "Thread state isn't \'stopped\' after expression evaluation.") + self.assertFalse( + thread.IsSuspended(), + "Thread state is \'suspended\' after expression evaluation.") + + # Let the process run to completion + self.runCmd("process continue") + + @expectedFailureAll( + oslist=["windows"], + bugnumber="llvm.org/pr24668: Breakpoints not resolved correctly") + @skipIfDarwin # llvm.org/pr15824 thread states not properly maintained and <rdar://problem/28557237> + @no_debug_info_test + def test_process_interrupt(self): + """Test process interrupt and continue.""" + self.build(dictionary=self.getBuildFlags(use_cpp11=False)) + exe = self.getBuildArtifact("a.out") + self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) + + # This should create a breakpoint in the main thread. + bpno = lldbutil.run_break_set_by_file_and_line( + self, "main.cpp", self.break_1, num_expected_locations=1) + + # Run the program. + self.runCmd("run", RUN_SUCCEEDED) + + # Get the target process + target = self.dbg.GetSelectedTarget() + process = target.GetProcess() + + thread = lldbutil.get_stopped_thread( + process, lldb.eStopReasonBreakpoint) + self.assertIsNotNone(thread) + + # Remove the breakpoint to avoid the single-step-over-bkpt dance in the + # "continue" below + self.assertTrue(target.BreakpointDelete(bpno)) + + # Continue, the inferior will go into an infinite loop waiting for + # 'g_test' to change. + self.dbg.SetAsync(True) + self.runCmd("continue") + self.wait_for_running_event(process) + + # Go back to synchronous interactions + self.dbg.SetAsync(False) + + # Stop the process + self.runCmd("process interrupt") + + self.assertEqual(thread.GetStopReason(), lldb.eStopReasonSignal) + + # Get the inferior out of its loop + self.runCmd("expression g_test = 1") + + # Run to completion + self.runCmd("continue") + + def thread_states_test(self): + """Test thread states (comprehensive).""" + exe = self.getBuildArtifact("a.out") + self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) + + # This should create a breakpoint in the main thread. + lldbutil.run_break_set_by_file_and_line( + self, "main.cpp", self.break_1, num_expected_locations=1) + lldbutil.run_break_set_by_file_and_line( + self, "main.cpp", self.break_2, num_expected_locations=1) + + # Run the program. + self.runCmd("run", RUN_SUCCEEDED) + + # Get the target process + target = self.dbg.GetSelectedTarget() + process = target.GetProcess() + thread = lldbutil.get_stopped_thread( + process, lldb.eStopReasonBreakpoint) + self.assertIsNotNone(thread) + + # Make sure the thread is in the stopped state. + self.assertTrue( + thread.IsStopped(), + "Thread state isn't \'stopped\' during breakpoint 1.") + self.assertFalse(thread.IsSuspended(), + "Thread state is \'suspended\' during breakpoint 1.") + + # Continue, the inferior will go into an infinite loop waiting for + # 'g_test' to change. + self.dbg.SetAsync(True) + self.runCmd("continue") + self.wait_for_running_event(process) + + # Check the thread state. It should be running. + self.assertFalse( + thread.IsStopped(), + "Thread state is \'stopped\' when it should be running.") + self.assertFalse( + thread.IsSuspended(), + "Thread state is \'suspended\' when it should be running.") + + # Go back to synchronous interactions + self.dbg.SetAsync(False) + + # Stop the process + self.runCmd("process interrupt") + + self.assertEqual(thread.GetState(), lldb.eStopReasonSignal) + + # Check the thread state + self.assertTrue( + thread.IsStopped(), + "Thread state isn't \'stopped\' after process stop.") + self.assertFalse(thread.IsSuspended(), + "Thread state is \'suspended\' after process stop.") + + # Get the inferior out of its loop + self.runCmd("expression g_test = 1") + + # Check the thread state + self.assertTrue( + thread.IsStopped(), + "Thread state isn't \'stopped\' after expression evaluation.") + self.assertFalse( + thread.IsSuspended(), + "Thread state is \'suspended\' after expression evaluation.") + + self.assertEqual(thread.GetState(), lldb.eStopReasonSignal) + + # Run to breakpoint 2 + self.runCmd("continue") + + self.assertEqual(thread.GetState(), lldb.eStopReasonBreakpoint) + + # Make sure both threads are stopped + self.assertTrue( + thread.IsStopped(), + "Thread state isn't \'stopped\' during breakpoint 2.") + self.assertFalse(thread.IsSuspended(), + "Thread state is \'suspended\' during breakpoint 2.") + + # Run to completion + self.runCmd("continue") + + # At this point, the inferior process should have exited. + self.assertEqual(process.GetState(), lldb.eStateExited, PROCESS_EXITED) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/state/main.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/state/main.cpp new file mode 100644 index 00000000000..63b50494bd0 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/state/main.cpp @@ -0,0 +1,44 @@ +//===-- main.cpp ------------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// This test is intended to verify that thread states are properly maintained +// when transitional actions are performed in the debugger. Most of the logic +// is in the test script. This program merely provides places where the test +// can create the intended states. + +#include <chrono> +#include <thread> + +volatile int g_test = 0; + +int addSomething(int a) +{ + return a + g_test; +} + +int doNothing() +{ + int temp = 0; // Set first breakpoint here + + while (!g_test && temp < 5) + { + ++temp; + std::this_thread::sleep_for(std::chrono::seconds(2)); + } + + return temp; // Set second breakpoint here +} + +int main () +{ + int result = doNothing(); + + int i = addSomething(result); + + return 0; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/step_out/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/step_out/Makefile new file mode 100644 index 00000000000..c46619c6623 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/step_out/Makefile @@ -0,0 +1,4 @@ +CXX_SOURCES := main.cpp +ENABLE_THREADS := YES + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/step_out/TestThreadStepOut.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/step_out/TestThreadStepOut.py new file mode 100644 index 00000000000..2d9632eb2dd --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/step_out/TestThreadStepOut.py @@ -0,0 +1,156 @@ +""" +Test stepping out from a function in a multi-threaded program. +""" + + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class ThreadStepOutTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + # Test occasionally times out on the Linux build bot + @skipIfLinux + @expectedFailureAll( + oslist=["linux"], + bugnumber="llvm.org/pr23477 Test occasionally times out on the Linux build bot") + @expectedFailureAll( + oslist=["freebsd"], + bugnumber="llvm.org/pr18066 inferior does not exit") + @skipIfWindows # This test will hang on windows llvm.org/pr21753 + @expectedFailureAll(oslist=["windows"]) + @expectedFailureNetBSD + def test_step_single_thread(self): + """Test thread step out on one thread via command interpreter. """ + self.build(dictionary=self.getBuildFlags()) + self.step_out_test(self.step_out_single_thread_with_cmd) + + # Test occasionally times out on the Linux build bot + @skipIfLinux + @expectedFailureAll( + oslist=["linux"], + bugnumber="llvm.org/pr23477 Test occasionally times out on the Linux build bot") + @expectedFailureAll( + oslist=["freebsd"], + bugnumber="llvm.org/pr19347 2nd thread stops at breakpoint") + @skipIfWindows # This test will hang on windows llvm.org/pr21753 + @expectedFailureAll(oslist=["windows"]) + @expectedFailureAll(oslist=["watchos"], archs=['armv7k'], bugnumber="rdar://problem/34674488") # stop reason is trace when it should be step-out + @expectedFailureNetBSD + def test_step_all_threads(self): + """Test thread step out on all threads via command interpreter. """ + self.build(dictionary=self.getBuildFlags()) + self.step_out_test(self.step_out_all_threads_with_cmd) + + # Test occasionally times out on the Linux build bot + @skipIfLinux + @expectedFailureAll( + oslist=["linux"], + bugnumber="llvm.org/pr23477 Test occasionally times out on the Linux build bot") + @expectedFailureAll( + oslist=["freebsd"], + bugnumber="llvm.org/pr19347 2nd thread stops at breakpoint") + @skipIfWindows # This test will hang on windows llvm.org/pr21753 + @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24681") + @expectedFailureNetBSD + def test_python(self): + """Test thread step out on one thread via Python API (dwarf).""" + self.build(dictionary=self.getBuildFlags()) + self.step_out_test(self.step_out_with_python) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line number for our breakpoint. + self.bkpt_string = '// Set breakpoint here' + self.breakpoint = line_number('main.cpp', self.bkpt_string) + + if "gcc" in self.getCompiler() or self.isIntelCompiler() or self.getArchitecture() in ['arm64', 'arm64e']: + self.step_out_destination = line_number( + 'main.cpp', '// Expect to stop here after step-out (icc and gcc; arm64)') + else: + self.step_out_destination = line_number( + 'main.cpp', '// Expect to stop here after step-out (clang)') + + def step_out_single_thread_with_cmd(self): + self.step_out_with_cmd("this-thread") + self.expect( + "thread backtrace all", + "Thread location after step out is correct", + substrs=[ + "main.cpp:%d" % + self.step_out_destination, + "main.cpp:%d" % + self.breakpoint]) + + def step_out_all_threads_with_cmd(self): + self.step_out_with_cmd("all-threads") + self.expect( + "thread backtrace all", + "Thread location after step out is correct", + substrs=[ + "main.cpp:%d" % + self.step_out_destination]) + + def step_out_with_cmd(self, run_mode): + self.runCmd("thread select %d" % self.step_out_thread.GetIndexID()) + self.runCmd("thread step-out -m %s" % run_mode) + self.expect("process status", "Expected stop reason to be step-out", + substrs=["stop reason = step out"]) + + self.expect( + "thread list", + "Selected thread did not change during step-out", + substrs=[ + "* thread #%d" % + self.step_out_thread.GetIndexID()]) + + def step_out_with_python(self): + self.step_out_thread.StepOut() + + reason = self.step_out_thread.GetStopReason() + self.assertEqual( + lldb.eStopReasonPlanComplete, + reason, + "Expected thread stop reason 'plancomplete', but got '%s'" % + lldbutil.stop_reason_to_str(reason)) + + # Verify location after stepping out + frame = self.step_out_thread.GetFrameAtIndex(0) + desc = lldbutil.get_description(frame.GetLineEntry()) + expect = "main.cpp:%d" % self.step_out_destination + self.assertTrue( + expect in desc, "Expected %s but thread stopped at %s" % + (expect, desc)) + + def step_out_test(self, step_out_func): + """Test single thread step out of a function.""" + (self.inferior_target, self.inferior_process, thread, bkpt) = lldbutil.run_to_source_breakpoint( + self, self.bkpt_string, lldb.SBFileSpec('main.cpp'), only_one_thread = False) + + # We hit the breakpoint on at least one thread. If we hit it on both threads + # simultaneously, we can try the step out. Otherwise, suspend the thread + # that hit the breakpoint, and continue till the second thread hits + # the breakpoint: + + (breakpoint_threads, other_threads) = ([], []) + lldbutil.sort_stopped_threads(self.inferior_process, + breakpoint_threads=breakpoint_threads, + other_threads=other_threads) + if len(breakpoint_threads) == 1: + success = thread.Suspend() + self.assertTrue(success, "Couldn't suspend a thread") + bkpt_threads = lldbutil.continue_to_breakpoint(bkpt) + self.assertEqual(len(bkpt_threads), 1, "Second thread stopped") + success = thread.Resume() + self.assertTrue(success, "Couldn't resume a thread") + + self.step_out_thread = breakpoint_threads[0] + + # Step out of thread stopped at breakpoint + step_out_func() diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/step_out/main.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/step_out/main.cpp new file mode 100644 index 00000000000..e7754d0ac74 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/step_out/main.cpp @@ -0,0 +1,50 @@ +//===-- main.cpp ------------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// This test is intended to create a situation in which two threads are stopped +// at a breakpoint and the debugger issues a step-out command. + +#include "pseudo_barrier.h" +#include <thread> + +pseudo_barrier_t g_barrier; + +volatile int g_test = 0; + +void step_out_of_here() { + g_test += 5; // Set breakpoint here +} + +void * +thread_func () +{ + // Wait until both threads are running + pseudo_barrier_wait(g_barrier); + + // Do something + step_out_of_here(); // Expect to stop here after step-out (clang) + + // Return + return NULL; // Expect to stop here after step-out (icc and gcc; arm64) +} + +int main () +{ + // Don't let either thread do anything until they're both ready. + pseudo_barrier_init(g_barrier, 2); + + // Create two threads + std::thread thread_1(thread_func); + std::thread thread_2(thread_func); + + // Wait for the threads to finish + thread_1.join(); + thread_2.join(); + + return 0; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/step_until/.categories b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/step_until/.categories new file mode 100644 index 00000000000..c00c25822e4 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/step_until/.categories @@ -0,0 +1 @@ +basic_process diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/step_until/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/step_until/Makefile new file mode 100644 index 00000000000..10495940055 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/step_until/Makefile @@ -0,0 +1,3 @@ +C_SOURCES := main.c + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/step_until/TestStepUntil.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/step_until/TestStepUntil.py new file mode 100644 index 00000000000..dd48ebaf8e1 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/step_until/TestStepUntil.py @@ -0,0 +1,86 @@ +"""Test stepping over vrs. hitting breakpoints & subsequent stepping in various forms.""" + + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class StepUntilTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line numbers that we will step to in main: + self.main_source = "main.c" + self.less_than_two = line_number('main.c', 'Less than 2') + self.greater_than_two = line_number('main.c', 'Greater than or equal to 2.') + self.back_out_in_main = line_number('main.c', 'Back out in main') + + def do_until (self, args, until_lines, expected_linenum): + self.build() + exe = self.getBuildArtifact("a.out") + + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + main_source_spec = lldb.SBFileSpec(self.main_source) + break_before = target.BreakpointCreateBySourceRegex( + 'At the start', + main_source_spec) + self.assertTrue(break_before, VALID_BREAKPOINT) + + # Now launch the process, and do not stop at entry point. + process = target.LaunchSimple( + args, None, self.get_process_working_directory()) + + self.assertTrue(process, PROCESS_IS_VALID) + + # The stop reason of the thread should be breakpoint. + threads = lldbutil.get_threads_stopped_at_breakpoint( + process, break_before) + + if len(threads) != 1: + self.fail("Failed to stop at first breakpoint in main.") + + thread = threads[0] + return thread + + thread = self.common_setup(None) + + cmd_interp = self.dbg.GetCommandInterpreter() + ret_obj = lldb.SBCommandReturnObject() + + cmd_line = "thread until" + for line_num in until_lines: + cmd_line += " %d"%(line_num) + + cmd_interp.HandleCommand(cmd_line, ret_obj) + self.assertTrue(ret_obj.Succeeded(), "'%s' failed: %s."%(cmd_line, ret_obj.GetError())) + + frame = thread.frames[0] + line = frame.GetLineEntry().GetLine() + self.assertEqual(line, expected_linenum, 'Did not get the expected stop line number') + + def test_hitting_one (self): + """Test thread step until - targeting one line and hitting it.""" + self.do_until(None, [self.less_than_two], self.less_than_two) + + def test_targetting_two_hitting_first (self): + """Test thread step until - targeting two lines and hitting one.""" + self.do_until(["foo", "bar", "baz"], [self.less_than_two, self.greater_than_two], self.greater_than_two) + + def test_targetting_two_hitting_second (self): + """Test thread step until - targeting two lines and hitting the other one.""" + self.do_until(None, [self.less_than_two, self.greater_than_two], self.less_than_two) + + def test_missing_one (self): + """Test thread step until - targeting one line and missing it.""" + self.do_until(["foo", "bar", "baz"], [self.less_than_two], self.back_out_in_main) + + + diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/step_until/main.c b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/step_until/main.c new file mode 100644 index 00000000000..e0b4d8ab951 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/step_until/main.c @@ -0,0 +1,20 @@ +#include <stdio.h> + +void call_me(int argc) +{ + printf ("At the start, argc: %d.\n", argc); + + if (argc < 2) + printf("Less than 2.\n"); + else + printf("Greater than or equal to 2.\n"); +} + +int +main(int argc, char **argv) +{ + call_me(argc); + printf("Back out in main.\n"); + + return 0; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/thread_exit/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/thread_exit/Makefile new file mode 100644 index 00000000000..ebecfbf9241 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/thread_exit/Makefile @@ -0,0 +1,3 @@ +ENABLE_THREADS := YES +CXX_SOURCES := main.cpp +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/thread_exit/TestThreadExit.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/thread_exit/TestThreadExit.py new file mode 100644 index 00000000000..6bd55e1753f --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/thread_exit/TestThreadExit.py @@ -0,0 +1,121 @@ +""" +Test number of threads. +""" + + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +import lldbsuite.test.lldbutil as lldbutil + + +class ThreadExitTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line numbers for our breakpoints. + 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') + self.break_4 = line_number('main.cpp', '// Set fourth breakpoint here') + + @skipIfWindows # This is flakey on Windows: llvm.org/pr38373 + def test(self): + """Test thread exit handling.""" + self.build(dictionary=self.getBuildFlags()) + exe = self.getBuildArtifact("a.out") + self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) + + # This should create a breakpoint with 1 location. + bp1_id = lldbutil.run_break_set_by_file_and_line( + self, "main.cpp", self.break_1, num_expected_locations=1) + bp2_id = lldbutil.run_break_set_by_file_and_line( + self, "main.cpp", self.break_2, num_expected_locations=1) + bp3_id = lldbutil.run_break_set_by_file_and_line( + self, "main.cpp", self.break_3, num_expected_locations=1) + bp4_id = lldbutil.run_break_set_by_file_and_line( + self, "main.cpp", self.break_4, num_expected_locations=1) + + # The breakpoint list should show 1 locations. + self.expect( + "breakpoint list -f", + "Breakpoint location shown correctly", + substrs=[ + "1: file = 'main.cpp', line = %d, exact_match = 0, locations = 1" % + self.break_1, + "2: file = 'main.cpp', line = %d, exact_match = 0, locations = 1" % + self.break_2, + "3: file = 'main.cpp', line = %d, exact_match = 0, locations = 1" % + self.break_3, + "4: file = 'main.cpp', line = %d, exact_match = 0, locations = 1" % + self.break_4]) + + # Run the program. + self.runCmd("run", RUN_SUCCEEDED) + # Get the target process + target = self.dbg.GetSelectedTarget() + process = target.GetProcess() + + stopped_thread = lldbutil.get_one_thread_stopped_at_breakpoint_id( + process, bp1_id) + self.assertIsNotNone(stopped_thread, + "Process is not stopped at breakpoint 1") + + # Get the number of threads + num_threads = process.GetNumThreads() + self.assertGreaterEqual( + num_threads, + 2, + 'Number of expected threads and actual threads do not match at breakpoint 1.') + + # Run to the second breakpoint + self.runCmd("continue") + stopped_thread = lldbutil.get_one_thread_stopped_at_breakpoint_id( + process, bp2_id) + self.assertIsNotNone(stopped_thread, + "Process is not stopped at breakpoint 2") + + # Update the number of threads + new_num_threads = process.GetNumThreads() + self.assertEqual( + new_num_threads, + num_threads + 1, + 'Number of expected threads did not increase by 1 at bp 2.') + + # Run to the third breakpoint + self.runCmd("continue") + stopped_thread = lldbutil.get_one_thread_stopped_at_breakpoint_id( + process, bp3_id) + self.assertIsNotNone(stopped_thread, + "Process is not stopped at breakpoint 3") + + # Update the number of threads + new_num_threads = process.GetNumThreads() + self.assertEqual( + new_num_threads, + num_threads, + 'Number of expected threads is not equal to original number of threads at bp 3.') + + # Run to the fourth breakpoint + self.runCmd("continue") + stopped_thread = lldbutil.get_one_thread_stopped_at_breakpoint_id( + process, bp4_id) + self.assertIsNotNone(stopped_thread, + "Process is not stopped at breakpoint 4") + + # Update the number of threads + new_num_threads = process.GetNumThreads() + self.assertEqual( + new_num_threads, + num_threads - 1, + 'Number of expected threads did not decrease by 1 at bp 4.') + + # Run to completion + self.runCmd("continue") + + # At this point, the inferior process should have exited. + self.assertEqual(process.GetState(), lldb.eStateExited, PROCESS_EXITED) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/thread_exit/main.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/thread_exit/main.cpp new file mode 100644 index 00000000000..7510dd3a7ff --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/thread_exit/main.cpp @@ -0,0 +1,73 @@ +//===-- main.cpp ------------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// This test verifies the correct handling of child thread exits. + +#include "pseudo_barrier.h" +#include <thread> + +pseudo_barrier_t g_barrier1; +pseudo_barrier_t g_barrier2; +pseudo_barrier_t g_barrier3; + +void * +thread1 () +{ + // Synchronize with the main thread. + pseudo_barrier_wait(g_barrier1); + + // Synchronize with the main thread and thread2. + pseudo_barrier_wait(g_barrier2); + + // Return + return NULL; // Set second breakpoint here +} + +void * +thread2 () +{ + // Synchronize with thread1 and the main thread. + pseudo_barrier_wait(g_barrier2); + + // Synchronize with the main thread. + pseudo_barrier_wait(g_barrier3); + + // Return + return NULL; +} + +int main () +{ + pseudo_barrier_init(g_barrier1, 2); + pseudo_barrier_init(g_barrier2, 3); + pseudo_barrier_init(g_barrier3, 2); + + // Create a thread. + std::thread thread_1(thread1); + + // Wait for thread1 to start. + pseudo_barrier_wait(g_barrier1); + + // Create another thread. + std::thread thread_2(thread2); // Set first breakpoint here + + // Wait for thread2 to start. + pseudo_barrier_wait(g_barrier2); + + // Wait for the first thread to finish + thread_1.join(); + + // Synchronize with the remaining thread + int dummy = 47; // Set third breakpoint here + pseudo_barrier_wait(g_barrier3); + + // Wait for the second thread to finish + thread_2.join(); + + return 0; // Set fourth breakpoint here +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/thread_specific_break/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/thread_specific_break/Makefile new file mode 100644 index 00000000000..c46619c6623 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/thread_specific_break/Makefile @@ -0,0 +1,4 @@ +CXX_SOURCES := main.cpp +ENABLE_THREADS := YES + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/thread_specific_break/TestThreadSpecificBreakpoint.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/thread_specific_break/TestThreadSpecificBreakpoint.py new file mode 100644 index 00000000000..e5505e1943c --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/thread_specific_break/TestThreadSpecificBreakpoint.py @@ -0,0 +1,71 @@ +""" +Test that we obey thread conditioned breakpoints. +""" + + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + +def set_thread_id(thread, breakpoint): + id = thread.id + breakpoint.SetThreadID(id) + +def set_thread_name(thread, breakpoint): + breakpoint.SetThreadName("main-thread") + +class ThreadSpecificBreakTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + NO_DEBUG_INFO_TESTCASE = True + + @add_test_categories(['pyapi']) + + @expectedFailureAll(oslist=['ios', 'watchos', 'tvos', 'bridgeos'], archs=['armv7', 'armv7k'], bugnumber='rdar://problem/34563920') # armv7 ios problem - breakpoint with tid qualifier isn't working + def test_thread_id(self): + self.do_test(set_thread_id) + + @skipUnlessDarwin + @expectedFailureAll(oslist=['ios', 'watchos', 'tvos', 'bridgeos'], archs=['armv7', 'armv7k'], bugnumber='rdar://problem/34563920') # armv7 ios problem - breakpoint with tid qualifier isn't working + def test_thread_name(self): + self.do_test(set_thread_name) + + def do_test(self, setter_method): + """Test that we obey thread conditioned breakpoints.""" + self.build() + main_source_spec = lldb.SBFileSpec("main.cpp") + (target, process, main_thread, main_breakpoint) = lldbutil.run_to_source_breakpoint(self, + "Set main breakpoint here", main_source_spec) + + thread_breakpoint = target.BreakpointCreateBySourceRegex( + "Set thread-specific breakpoint here", main_source_spec) + self.assertGreater( + thread_breakpoint.GetNumLocations(), + 0, + "thread breakpoint has no locations associated with it.") + + # Set the thread-specific breakpoint to stop only on the main thread + # before the secondary thread has a chance to execute it. The main + # thread joins the secondary thread, and then the main thread will + # execute the code at the breakpoint. If the thread-specific + # breakpoint works, the next stop will be on the main thread. + setter_method(main_thread, thread_breakpoint) + + process.Continue() + next_stop_state = process.GetState() + self.assertEqual( + next_stop_state, + lldb.eStateStopped, + "We should have stopped at the thread breakpoint.") + stopped_threads = lldbutil.get_threads_stopped_at_breakpoint( + process, thread_breakpoint) + self.assertEqual( + len(stopped_threads), + 1, + "thread breakpoint stopped at unexpected number of threads") + self.assertEqual( + stopped_threads[0].GetThreadID(), + main_thread.GetThreadID(), + "thread breakpoint stopped at the wrong thread") diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/thread_specific_break/main.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/thread_specific_break/main.cpp new file mode 100644 index 00000000000..03e93bd4125 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/thread_specific_break/main.cpp @@ -0,0 +1,32 @@ +#include <chrono> +#include <thread> + +void +thread_function () +{ + // Set thread-specific breakpoint here. + std::this_thread::sleep_for(std::chrono::milliseconds(20)); + // On Windows, a sleep_for of less than about 16 ms effectively calls + // Sleep(0). The MS standard thread implementation uses a system thread + // pool, which can deadlock on a Sleep(0), hanging not only the secondary + // thread but the entire test. I increased the delay to 20 ms to ensure + // Sleep is called with a delay greater than 0. The deadlock potential + // is described here: + // https://docs.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-sleep#remarks +} + +int +main () +{ + // Set main breakpoint here. + + #ifdef __APPLE__ + pthread_setname_np("main-thread"); + #endif + + std::thread t(thread_function); + t.join(); + + thread_function(); + return 0; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/thread_specific_break_plus_condition/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/thread_specific_break_plus_condition/Makefile new file mode 100644 index 00000000000..c46619c6623 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/thread_specific_break_plus_condition/Makefile @@ -0,0 +1,4 @@ +CXX_SOURCES := main.cpp +ENABLE_THREADS := YES + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/thread_specific_break_plus_condition/TestThreadSpecificBpPlusCondition.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/thread_specific_break_plus_condition/TestThreadSpecificBpPlusCondition.py new file mode 100644 index 00000000000..126ad9e97ee --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/thread_specific_break_plus_condition/TestThreadSpecificBpPlusCondition.py @@ -0,0 +1,76 @@ +""" +Test that we obey thread conditioned breakpoints and expression +conditioned breakpoints simultaneously +""" + + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class ThreadSpecificBreakPlusConditionTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + # test frequently times out or hangs + @skipIf(oslist=['windows', 'freebsd']) + @skipIfDarwin + # hits break in another thread in testrun + @expectedFailureAll(oslist=['freebsd'], bugnumber='llvm.org/pr18522') + @add_test_categories(['pyapi']) + @expectedFailureAll(oslist=['ios', 'watchos', 'tvos', 'bridgeos'], archs=['armv7', 'armv7k'], bugnumber='rdar://problem/34563348') # Two threads seem to end up with the same my_value when built for armv7. + @expectedFailureNetBSD + def test_python(self): + """Test that we obey thread conditioned breakpoints.""" + self.build() + exe = self.getBuildArtifact("a.out") + + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + main_source_spec = lldb.SBFileSpec("main.cpp") + + # Set a breakpoint in the thread body, and make it active for only the + # first thread. + break_thread_body = target.BreakpointCreateBySourceRegex( + "Break here in thread body.", main_source_spec) + self.assertTrue( + break_thread_body.IsValid() and break_thread_body.GetNumLocations() > 0, + "Failed to set thread body breakpoint.") + + process = target.LaunchSimple( + None, None, self.get_process_working_directory()) + + self.assertTrue(process, PROCESS_IS_VALID) + + threads = lldbutil.get_threads_stopped_at_breakpoint( + process, break_thread_body) + + victim_thread = threads[0] + + # Pick one of the threads, and change the breakpoint so it ONLY stops for this thread, + # but add a condition that it won't stop for this thread's my_value. The other threads + # pass the condition, so they should stop, but if the thread-specification is working + # they should not stop. So nobody should hit the breakpoint anymore, and we should + # just exit cleanly. + + frame = victim_thread.GetFrameAtIndex(0) + value = frame.FindVariable("my_value").GetValueAsSigned(0) + self.assertTrue( + value > 0 and value < 11, + "Got a reasonable value for my_value.") + + cond_string = "my_value != %d" % (value) + + break_thread_body.SetThreadID(victim_thread.GetThreadID()) + break_thread_body.SetCondition(cond_string) + + process.Continue() + + next_stop_state = process.GetState() + self.assertTrue( + next_stop_state == lldb.eStateExited, + "We should have not hit the breakpoint again.") diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/thread_specific_break_plus_condition/main.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/thread_specific_break_plus_condition/main.cpp new file mode 100644 index 00000000000..af8ab84157f --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/functionalities/thread/thread_specific_break_plus_condition/main.cpp @@ -0,0 +1,39 @@ +#include <chrono> +#include <thread> +#include <vector> + +void * +thread_function (void *thread_marker) +{ + int keep_going = 1; + int my_value = *((int *)thread_marker); + int counter = 0; + + while (counter < 20) + { + counter++; // Break here in thread body. + std::this_thread::sleep_for(std::chrono::microseconds(10)); + } + return NULL; +} + + +int +main () +{ + std::vector<std::thread> threads; + + int thread_value = 0; + int i; + + for (i = 0; i < 10; i++) + { + thread_value += 1; + threads.push_back(std::thread(thread_function, &thread_value)); + } + + for (i = 0; i < 10; i++) + threads[i].join(); + + return 0; +} |