summaryrefslogtreecommitdiffstats
path: root/lldb/packages/Python/lldbsuite
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/packages/Python/lldbsuite')
-rw-r--r--lldb/packages/Python/lldbsuite/test/functionalities/thread/backtrace_all/Makefile6
-rwxr-xr-xlldb/packages/Python/lldbsuite/test/functionalities/thread/backtrace_all/ParallelTask.cpp151
-rw-r--r--lldb/packages/Python/lldbsuite/test/functionalities/thread/backtrace_all/TestBacktraceAll.py54
-rw-r--r--lldb/packages/Python/lldbsuite/test/lang/c/typedef/Testtypedef.py2
-rw-r--r--lldb/packages/Python/lldbsuite/test/lang/c/typedef/main.c16
5 files changed, 223 insertions, 6 deletions
diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/thread/backtrace_all/Makefile b/lldb/packages/Python/lldbsuite/test/functionalities/thread/backtrace_all/Makefile
new file mode 100644
index 00000000000..90ec8b9d913
--- /dev/null
+++ b/lldb/packages/Python/lldbsuite/test/functionalities/thread/backtrace_all/Makefile
@@ -0,0 +1,6 @@
+LEVEL = ../../../make
+
+CXXFLAGS += -std=c++11
+CXX_SOURCES := ParallelTask.cpp
+ENABLE_STD_THREADS := YES
+include $(LEVEL)/Makefile.rules
diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/thread/backtrace_all/ParallelTask.cpp b/lldb/packages/Python/lldbsuite/test/functionalities/thread/backtrace_all/ParallelTask.cpp
new file mode 100755
index 00000000000..71fb8e3bb56
--- /dev/null
+++ b/lldb/packages/Python/lldbsuite/test/functionalities/thread/backtrace_all/ParallelTask.cpp
@@ -0,0 +1,151 @@
+#include <cstdint>
+#include <thread>
+#include <vector>
+#include <queue>
+#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/lldb/packages/Python/lldbsuite/test/functionalities/thread/backtrace_all/TestBacktraceAll.py b/lldb/packages/Python/lldbsuite/test/functionalities/thread/backtrace_all/TestBacktraceAll.py
new file mode 100644
index 00000000000..d4000548b2c
--- /dev/null
+++ b/lldb/packages/Python/lldbsuite/test/functionalities/thread/backtrace_all/TestBacktraceAll.py
@@ -0,0 +1,54 @@
+"""
+Test regression for Bug 25251.
+"""
+
+import os, time
+import unittest2
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as 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('ParallelTask.cpp', '// Set breakpoint here')
+
+ def test(self):
+ """Test breakpoint handling after a thread join."""
+ self.build(dictionary=self.getBuildFlags())
+
+ exe = os.path.join(os.getcwd(), "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/lldb/packages/Python/lldbsuite/test/lang/c/typedef/Testtypedef.py b/lldb/packages/Python/lldbsuite/test/lang/c/typedef/Testtypedef.py
index 9a73f851759..594c0528963 100644
--- a/lldb/packages/Python/lldbsuite/test/lang/c/typedef/Testtypedef.py
+++ b/lldb/packages/Python/lldbsuite/test/lang/c/typedef/Testtypedef.py
@@ -32,7 +32,7 @@ class TypedefTestCase(TestBase):
"""Test 'image lookup -t a' at different scopes and check for correct display."""
exe = os.path.join(os.getcwd(), "a.out")
self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
- typearray = ("float", "float", "char", "float", "int", "double", "float", "float")
+ typearray = ("float", "float", "char", "double *", "float", "int", "double", "float", "float")
arraylen = len(typearray)+1
for i in range(1,arraylen):
loc_line = line_number('main.c', '// Set break point ' + str(i) + '.')
diff --git a/lldb/packages/Python/lldbsuite/test/lang/c/typedef/main.c b/lldb/packages/Python/lldbsuite/test/lang/c/typedef/main.c
index 6c13affbbc1..62f8a00e664 100644
--- a/lldb/packages/Python/lldbsuite/test/lang/c/typedef/main.c
+++ b/lldb/packages/Python/lldbsuite/test/lang/c/typedef/main.c
@@ -6,6 +6,11 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
+void test()
+{
+ typedef double * a;
+ a b = 0; // Set break point 4.
+}
int main (int argc, char const *argv[])
{
typedef float a;
@@ -16,25 +21,26 @@ int main (int argc, char const *argv[])
typedef char a;
i++;
a charvariable = 'a'; // Set break point 3.
+ test();
}
{
int c = 0;
- c++; // Set break point 4.
+ c++; // Set break point 5.
for(i = 0 ; i < 1 ; i++)
{
typedef int a;
a b;
- b = 7; // Set break point 5.
+ b = 7; // Set break point 6.
}
for(i = 0 ; i < 1 ; i++)
{
typedef double a;
a b;
- b = 3.14; // Set break point 6.
+ b = 3.14; // Set break point 7.
}
- c = 1; // Set break point 7.
+ c = 1; // Set break point 8.
}
floatvariable = 2.5;
- floatvariable = 2.8; // Set break point 8.
+ floatvariable = 2.8; // Set break point 9.
return 0;
}
OpenPOWER on IntegriCloud