aboutsummaryrefslogtreecommitdiff
path: root/lldb/test
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/test')
-rw-r--r--lldb/test/API/commands/frame/diagnose/dereference-function-return/TestDiagnoseDereferenceFunctionReturn.py3
-rw-r--r--lldb/test/API/commands/process/detach-resumes/Makefile4
-rw-r--r--lldb/test/API/commands/process/detach-resumes/TestDetachResumes.py59
-rw-r--r--lldb/test/API/commands/process/detach-resumes/main.cpp48
-rw-r--r--lldb/test/API/functionalities/asan/Makefile6
-rw-r--r--lldb/test/API/functionalities/asan/TestMemoryHistory.py74
-rw-r--r--lldb/test/API/functionalities/asan/TestReportData.py21
-rw-r--r--lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/valarray/TestDataFormatterLibcxxValarray.py88
-rw-r--r--lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/valarray/main.cpp6
-rw-r--r--lldb/test/API/functionalities/fork/concurrent_vfork/TestConcurrentVFork.py16
-rw-r--r--lldb/test/Shell/lit.cfg.py12
-rw-r--r--lldb/test/Shell/lit.site.cfg.py.in1
12 files changed, 302 insertions, 36 deletions
diff --git a/lldb/test/API/commands/frame/diagnose/dereference-function-return/TestDiagnoseDereferenceFunctionReturn.py b/lldb/test/API/commands/frame/diagnose/dereference-function-return/TestDiagnoseDereferenceFunctionReturn.py
index d8f4516..4d9b036 100644
--- a/lldb/test/API/commands/frame/diagnose/dereference-function-return/TestDiagnoseDereferenceFunctionReturn.py
+++ b/lldb/test/API/commands/frame/diagnose/dereference-function-return/TestDiagnoseDereferenceFunctionReturn.py
@@ -19,6 +19,9 @@ class TestDiagnoseDereferenceFunctionReturn(TestBase):
TestBase.setUp(self)
self.build()
exe = self.getBuildArtifact("a.out")
+ # FIXME: This default changed in lldbtest.py and this test
+ # seems to rely on having it turned off.
+ self.runCmd("settings set target.disable-aslr true")
self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
self.runCmd("run", RUN_SUCCEEDED)
self.expect("thread list", "Thread should be stopped", substrs=["stopped"])
diff --git a/lldb/test/API/commands/process/detach-resumes/Makefile b/lldb/test/API/commands/process/detach-resumes/Makefile
new file mode 100644
index 0000000..c46619c
--- /dev/null
+++ b/lldb/test/API/commands/process/detach-resumes/Makefile
@@ -0,0 +1,4 @@
+CXX_SOURCES := main.cpp
+ENABLE_THREADS := YES
+
+include Makefile.rules
diff --git a/lldb/test/API/commands/process/detach-resumes/TestDetachResumes.py b/lldb/test/API/commands/process/detach-resumes/TestDetachResumes.py
new file mode 100644
index 0000000..5772729
--- /dev/null
+++ b/lldb/test/API/commands/process/detach-resumes/TestDetachResumes.py
@@ -0,0 +1,59 @@
+"""
+Test that the process continues running after we detach from it.
+"""
+
+import lldb
+import time
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+
+class DetachResumesTestCase(TestBase):
+ NO_DEBUG_INFO_TESTCASE = True
+
+ def test_detach_resumes(self):
+ self.build()
+ exe = self.getBuildArtifact()
+
+ # The inferior will use this file to let us know it is ready to be
+ # attached.
+ sync_file_path = lldbutil.append_to_process_working_directory(
+ self, "sync_file_%d" % (int(time.time()))
+ )
+
+ # And this one to let us know it is running after we've detached from
+ # it.
+ exit_file_path = lldbutil.append_to_process_working_directory(
+ self, "exit_file_%d" % (int(time.time()))
+ )
+
+ popen = self.spawnSubprocess(
+ self.getBuildArtifact(exe), [sync_file_path, exit_file_path]
+ )
+ lldbutil.wait_for_file_on_target(self, sync_file_path)
+
+ self.runCmd("process attach -p " + str(popen.pid))
+
+ # Set a breakpoint at a place that will be called by multiple threads
+ # simultaneously. On systems (e.g. linux) where the debugger needs to
+ # send signals to suspend threads, these signals will race with threads
+ # hitting the breakpoint (and stopping on their own).
+ bpno = lldbutil.run_break_set_by_symbol(self, "break_here")
+
+ # And let the inferior know it can call the function.
+ self.runCmd("expr -- wait_for_debugger_flag = false")
+
+ self.runCmd("continue")
+
+ self.expect(
+ "thread list",
+ STOPPED_DUE_TO_BREAKPOINT,
+ substrs=["stopped", "stop reason = breakpoint"],
+ )
+
+ # Detach, the process should keep running after this, and not be stopped
+ # by the signals that the debugger may have used to suspend the threads.
+ self.runCmd("detach")
+
+ lldbutil.wait_for_file_on_target(self, exit_file_path)
diff --git a/lldb/test/API/commands/process/detach-resumes/main.cpp b/lldb/test/API/commands/process/detach-resumes/main.cpp
new file mode 100644
index 0000000..e8050fe
--- /dev/null
+++ b/lldb/test/API/commands/process/detach-resumes/main.cpp
@@ -0,0 +1,48 @@
+#include "pseudo_barrier.h"
+#include <chrono>
+#include <fcntl.h>
+#include <fstream>
+#include <stdio.h>
+#include <thread>
+#include <vector>
+
+pseudo_barrier_t barrier;
+
+constexpr size_t nthreads = 5;
+volatile bool wait_for_debugger_flag = true;
+
+void break_here() {}
+
+void tfunc() {
+ pseudo_barrier_wait(barrier);
+
+ break_here();
+}
+
+int main(int argc, char const *argv[]) {
+ lldb_enable_attach();
+
+ if (argc < 3)
+ return 1;
+
+ // Create a file to signal that this process has started up.
+ std::ofstream(argv[1]).close();
+
+ // And wait for it to attach.
+ for (int i = 0; i < 100 && wait_for_debugger_flag; ++i)
+ std::this_thread::sleep_for(std::chrono::seconds(1));
+
+ // Fire up the threads and have them call break_here() simultaneously.
+ pseudo_barrier_init(barrier, nthreads);
+ std::vector<std::thread> threads;
+ for (size_t i = 0; i < nthreads; ++i)
+ threads.emplace_back(tfunc);
+
+ for (std::thread &t : threads)
+ t.join();
+
+ // Create the file to let the debugger know we're running.
+ std::ofstream(argv[2]).close();
+
+ return 0;
+}
diff --git a/lldb/test/API/functionalities/asan/Makefile b/lldb/test/API/functionalities/asan/Makefile
index 4913a18..d66696f 100644
--- a/lldb/test/API/functionalities/asan/Makefile
+++ b/lldb/test/API/functionalities/asan/Makefile
@@ -1,4 +1,8 @@
C_SOURCES := main.c
-CFLAGS_EXTRAS := -fsanitize=address -g -gcolumn-info
+asan: CFLAGS_EXTRAS := -fsanitize=address -g -gcolumn-info
+asan: all
+
+libsanitizers: CFLAGS_EXTRAS := -fsanitize=address -fsanitize-stable-abi -g -gcolumn-info
+libsanitizers: all
include Makefile.rules
diff --git a/lldb/test/API/functionalities/asan/TestMemoryHistory.py b/lldb/test/API/functionalities/asan/TestMemoryHistory.py
index 00162ae..41ab258 100644
--- a/lldb/test/API/functionalities/asan/TestMemoryHistory.py
+++ b/lldb/test/API/functionalities/asan/TestMemoryHistory.py
@@ -8,16 +8,24 @@ from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbplatform
from lldbsuite.test import lldbutil
-
+from lldbsuite.test_event.build_exception import BuildError
class AsanTestCase(TestBase):
@skipIfFreeBSD # llvm.org/pr21136 runtimes not yet available by default
@expectedFailureNetBSD
@skipUnlessAddressSanitizer
def test(self):
- self.build()
+ self.build(make_targets=["asan"])
self.asan_tests()
+ @skipIf(oslist=no_match(["macosx"]))
+ def test_libsanitizers_asan(self):
+ try:
+ self.build(make_targets=["libsanitizers"])
+ except BuildError as e:
+ self.skipTest("failed to build with libsanitizers")
+ self.libsanitizer_tests()
+
def setUp(self):
# Call super's setUp().
TestBase.setUp(self)
@@ -26,6 +34,68 @@ class AsanTestCase(TestBase):
self.line_free = line_number("main.c", "// free line")
self.line_breakpoint = line_number("main.c", "// break line")
+ # Test line numbers: rdar://126237493
+ def libsanitizer_tests(self):
+ target = self.createTestTarget()
+
+ self.runCmd(
+ "env SanitizersAddress=1 MallocSanitizerZone=1 MallocSecureAllocator=0"
+ )
+
+ self.runCmd("run")
+
+ # In libsanitizers, memory history is not supported until a report has been generated
+ self.expect(
+ "thread list",
+ "Process should be stopped due to ASan report",
+ substrs=["stopped", "stop reason = Use of deallocated memory"],
+ )
+
+ # test the 'memory history' command
+ self.expect(
+ "memory history 'pointer'",
+ substrs=[
+ "Memory deallocated by Thread",
+ "a.out`f2",
+ "main.c",
+ "Memory allocated by Thread",
+ "a.out`f1",
+ "main.c",
+ ],
+ )
+
+ # do the same using SB API
+ process = self.dbg.GetSelectedTarget().process
+ val = (
+ process.GetSelectedThread().GetSelectedFrame().EvaluateExpression("pointer")
+ )
+ addr = val.GetValueAsUnsigned()
+ threads = process.GetHistoryThreads(addr)
+ self.assertEqual(threads.GetSize(), 2)
+
+ history_thread = threads.GetThreadAtIndex(0)
+ self.assertTrue(history_thread.num_frames >= 2)
+ self.assertEqual(
+ history_thread.frames[1].GetLineEntry().GetFileSpec().GetFilename(),
+ "main.c",
+ )
+
+ history_thread = threads.GetThreadAtIndex(1)
+ self.assertTrue(history_thread.num_frames >= 2)
+ self.assertEqual(
+ history_thread.frames[1].GetLineEntry().GetFileSpec().GetFilename(),
+ "main.c",
+ )
+
+ # let's free the container (SBThreadCollection) and see if the
+ # SBThreads still live
+ threads = None
+ self.assertTrue(history_thread.num_frames >= 2)
+ self.assertEqual(
+ history_thread.frames[1].GetLineEntry().GetFileSpec().GetFilename(),
+ "main.c",
+ )
+
def asan_tests(self):
target = self.createTestTarget()
diff --git a/lldb/test/API/functionalities/asan/TestReportData.py b/lldb/test/API/functionalities/asan/TestReportData.py
index 543c5fe..5e4c179 100644
--- a/lldb/test/API/functionalities/asan/TestReportData.py
+++ b/lldb/test/API/functionalities/asan/TestReportData.py
@@ -8,7 +8,7 @@ import lldb
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
-
+from lldbsuite.test_event.build_exception import BuildError
class AsanTestReportDataCase(TestBase):
@skipIfFreeBSD # llvm.org/pr21136 runtimes not yet available by default
@@ -16,9 +16,17 @@ class AsanTestReportDataCase(TestBase):
@skipUnlessAddressSanitizer
@skipIf(archs=["i386"], bugnumber="llvm.org/PR36710")
def test(self):
- self.build()
+ self.build(make_targets=["asan"])
self.asan_tests()
+ @skipIf(oslist=no_match(["macosx"]))
+ def test_libsanitizers_asan(self):
+ try:
+ self.build(make_targets=["libsanitizers"])
+ except BuildError as e:
+ self.skipTest("failed to build with libsanitizers")
+ self.asan_tests(libsanitizers=True)
+
def setUp(self):
# Call super's setUp().
TestBase.setUp(self)
@@ -29,10 +37,15 @@ class AsanTestReportDataCase(TestBase):
self.line_crash = line_number("main.c", "// BOOM line")
self.col_crash = 16
- def asan_tests(self):
+ def asan_tests(self, libsanitizers=False):
target = self.createTestTarget()
- self.registerSanitizerLibrariesWithTarget(target)
+ if libsanitizers:
+ self.runCmd(
+ "env SanitizersAddress=1 MallocSanitizerZone=1 MallocSecureAllocator=0"
+ )
+ else:
+ self.registerSanitizerLibrariesWithTarget(target)
self.runCmd("run")
diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/valarray/TestDataFormatterLibcxxValarray.py b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/valarray/TestDataFormatterLibcxxValarray.py
index b59b770..613546b 100644
--- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/valarray/TestDataFormatterLibcxxValarray.py
+++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/valarray/TestDataFormatterLibcxxValarray.py
@@ -89,21 +89,93 @@ class LibcxxChronoDataFormatterTestCase(TestBase):
"frame variable sa",
substrs=[
"sa = stride=2 size=4",
- "[0] = 1",
- "[1] = 3",
- "[2] = 5",
- "[3] = 7",
+ "[0] = 11",
+ "[1] = 13",
+ "[2] = 15",
+ "[3] = 17",
"}",
],
)
# check access-by-index
- self.expect("frame variable sa[0]", substrs=["1"])
- self.expect("frame variable sa[1]", substrs=["3"])
- self.expect("frame variable sa[2]", substrs=["5"])
- self.expect("frame variable sa[3]", substrs=["7"])
+ self.expect("frame variable sa[0]", substrs=["11"])
+ self.expect("frame variable sa[1]", substrs=["13"])
+ self.expect("frame variable sa[2]", substrs=["15"])
+ self.expect("frame variable sa[3]", substrs=["17"])
self.expect(
"frame variable sa[4]",
error=True,
substrs=['array index 4 is not valid for "(slice_array<int>) sa"'],
)
+
+ #
+ # std::gslice_array
+ #
+
+ self.expect(
+ "frame variable ga",
+ substrs=[
+ "ga = size=3",
+ "[0] -> [3] = 13",
+ "[1] -> [4] = 14",
+ "[2] -> [5] = 15",
+ "}",
+ ],
+ )
+
+ # check access-by-index
+ self.expect("frame variable ga[0]", substrs=["13"])
+ self.expect("frame variable ga[1]", substrs=["14"])
+ self.expect("frame variable ga[2]", substrs=["15"])
+ self.expect(
+ "frame variable ga[3]",
+ error=True,
+ substrs=['array index 3 is not valid for "(gslice_array<int>) ga"'],
+ )
+ #
+ # std::mask_array
+ #
+
+ self.expect(
+ "frame variable ma",
+ substrs=[
+ "ma = size=2",
+ "[0] -> [1] = 11",
+ "[1] -> [2] = 12",
+ "}",
+ ],
+ )
+
+ # check access-by-index
+ self.expect("frame variable ma[0]", substrs=["11"])
+ self.expect("frame variable ma[1]", substrs=["12"])
+ self.expect(
+ "frame variable ma[2]",
+ error=True,
+ substrs=['array index 2 is not valid for "(mask_array<int>) ma"'],
+ )
+
+ #
+ # std::indirect_array
+ #
+
+ self.expect(
+ "frame variable ia",
+ substrs=[
+ "ia = size=3",
+ "[0] -> [3] = 13",
+ "[1] -> [6] = 16",
+ "[2] -> [9] = 19",
+ "}",
+ ],
+ )
+
+ # check access-by-index
+ self.expect("frame variable ia[0]", substrs=["13"])
+ self.expect("frame variable ia[1]", substrs=["16"])
+ self.expect("frame variable ia[2]", substrs=["19"])
+ self.expect(
+ "frame variable ia[3]",
+ error=True,
+ substrs=['array index 3 is not valid for "(indirect_array<int>) ia"'],
+ )
diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/valarray/main.cpp b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/valarray/main.cpp
index 1481d8b..d31951c 100644
--- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/valarray/main.cpp
+++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/valarray/main.cpp
@@ -13,8 +13,12 @@ int main() {
std::valarray<double> va_double({1.0, 0.5, 0.25, 0.125});
- std::valarray<int> va({0, 1, 2, 3, 4, 5, 6, 7, 8, 9});
+ std::valarray<int> va({10, 11, 12, 13, 14, 15, 16, 17, 18, 19});
std::slice_array<int> sa = va[std::slice(1, 4, 2)];
+ std::gslice_array<int> ga = va[std::gslice(
+ 3, std::valarray<std::size_t>(3, 1), std::valarray<std::size_t>(1, 1))];
+ std::mask_array<int> ma = va[std::valarray<bool>{false, true, true}];
+ std::indirect_array<int> ia = va[std::valarray<size_t>{3, 6, 9}];
std::cout << "break here\n";
}
diff --git a/lldb/test/API/functionalities/fork/concurrent_vfork/TestConcurrentVFork.py b/lldb/test/API/functionalities/fork/concurrent_vfork/TestConcurrentVFork.py
index 1790bd4..2dcbb72 100644
--- a/lldb/test/API/functionalities/fork/concurrent_vfork/TestConcurrentVFork.py
+++ b/lldb/test/API/functionalities/fork/concurrent_vfork/TestConcurrentVFork.py
@@ -48,8 +48,6 @@ class TestConcurrentVFork(TestBase):
self.expect("continue", patterns=[r"exited with status = 1[0-4]"])
@skipUnlessPlatform(["linux"])
- # See https://github.com/llvm/llvm-project/issues/85084.
- @skipIf(oslist=["linux"], archs=["aarch64", "arm"])
def test_follow_parent_vfork_no_exec(self):
"""
Make sure that debugging concurrent vfork() from multiple threads won't crash lldb during follow-parent.
@@ -58,8 +56,6 @@ class TestConcurrentVFork(TestBase):
self.follow_parent_helper(use_fork=False, call_exec=False)
@skipUnlessPlatform(["linux"])
- # See https://github.com/llvm/llvm-project/issues/85084.
- @skipIf(oslist=["linux"], archs=["aarch64", "arm"])
def test_follow_parent_fork_no_exec(self):
"""
Make sure that debugging concurrent fork() from multiple threads won't crash lldb during follow-parent.
@@ -68,8 +64,6 @@ class TestConcurrentVFork(TestBase):
self.follow_parent_helper(use_fork=True, call_exec=False)
@skipUnlessPlatform(["linux"])
- # See https://github.com/llvm/llvm-project/issues/85084.
- @skipIf(oslist=["linux"], archs=["aarch64", "arm"])
def test_follow_parent_vfork_call_exec(self):
"""
Make sure that debugging concurrent vfork() from multiple threads won't crash lldb during follow-parent.
@@ -78,8 +72,6 @@ class TestConcurrentVFork(TestBase):
self.follow_parent_helper(use_fork=False, call_exec=True)
@skipUnlessPlatform(["linux"])
- # See https://github.com/llvm/llvm-project/issues/85084.
- @skipIf(oslist=["linux"], archs=["aarch64", "arm"])
def test_follow_parent_fork_call_exec(self):
"""
Make sure that debugging concurrent vfork() from multiple threads won't crash lldb during follow-parent.
@@ -88,8 +80,6 @@ class TestConcurrentVFork(TestBase):
self.follow_parent_helper(use_fork=True, call_exec=True)
@skipUnlessPlatform(["linux"])
- # See https://github.com/llvm/llvm-project/issues/85084.
- @skipIf(oslist=["linux"], archs=["aarch64", "arm"])
def test_follow_child_vfork_no_exec(self):
"""
Make sure that debugging concurrent vfork() from multiple threads won't crash lldb during follow-child.
@@ -98,8 +88,6 @@ class TestConcurrentVFork(TestBase):
self.follow_child_helper(use_fork=False, call_exec=False)
@skipUnlessPlatform(["linux"])
- # See https://github.com/llvm/llvm-project/issues/85084.
- @skipIf(oslist=["linux"], archs=["aarch64", "arm"])
def test_follow_child_fork_no_exec(self):
"""
Make sure that debugging concurrent fork() from multiple threads won't crash lldb during follow-child.
@@ -108,8 +96,6 @@ class TestConcurrentVFork(TestBase):
self.follow_child_helper(use_fork=True, call_exec=False)
@skipUnlessPlatform(["linux"])
- # See https://github.com/llvm/llvm-project/issues/85084.
- @skipIf(oslist=["linux"], archs=["aarch64", "arm"])
def test_follow_child_vfork_call_exec(self):
"""
Make sure that debugging concurrent vfork() from multiple threads won't crash lldb during follow-child.
@@ -118,8 +104,6 @@ class TestConcurrentVFork(TestBase):
self.follow_child_helper(use_fork=False, call_exec=True)
@skipUnlessPlatform(["linux"])
- # See https://github.com/llvm/llvm-project/issues/85084.
- @skipIf(oslist=["linux"], archs=["aarch64", "arm"])
def test_follow_child_fork_call_exec(self):
"""
Make sure that debugging concurrent fork() from multiple threads won't crash lldb during follow-child.
diff --git a/lldb/test/Shell/lit.cfg.py b/lldb/test/Shell/lit.cfg.py
index 2905695..e24f3fb 100644
--- a/lldb/test/Shell/lit.cfg.py
+++ b/lldb/test/Shell/lit.cfg.py
@@ -50,10 +50,14 @@ llvm_config.with_system_environment(
)
# Enable sanitizer runtime flags.
-config.environment["ASAN_OPTIONS"] = "detect_stack_use_after_return=1"
-config.environment["TSAN_OPTIONS"] = "halt_on_error=1"
-if platform.system() == "Darwin":
- config.environment["MallocNanoZone"] = "0"
+if "Address" in config.llvm_use_sanitizer:
+ config.environment["ASAN_OPTIONS"] = "detect_stack_use_after_return=1"
+ if platform.system() == "Darwin":
+ config.environment["MallocNanoZone"] = "0"
+
+if "Thread" in config.llvm_use_sanitizer:
+ config.environment["TSAN_OPTIONS"] = "halt_on_error=1"
+
# Support running the test suite under the lldb-repro wrapper. This makes it
# possible to capture a test suite run and then rerun all the test from the
diff --git a/lldb/test/Shell/lit.site.cfg.py.in b/lldb/test/Shell/lit.site.cfg.py.in
index 736dfc3..b69e7bc 100644
--- a/lldb/test/Shell/lit.site.cfg.py.in
+++ b/lldb/test/Shell/lit.site.cfg.py.in
@@ -26,6 +26,7 @@ config.lldb_enable_lua = @LLDB_ENABLE_LUA@
config.lldb_build_directory = "@LLDB_TEST_BUILD_DIRECTORY@"
config.have_lldb_server = @LLDB_TOOL_LLDB_SERVER_BUILD@
config.lldb_system_debugserver = @LLDB_USE_SYSTEM_DEBUGSERVER@
+config.llvm_use_sanitizer = "@LLVM_USE_SANITIZER@"
# The shell tests use their own module caches.
config.lldb_module_cache = os.path.join("@LLDB_TEST_MODULE_CACHE_LLDB@", "lldb-shell")
config.clang_module_cache = os.path.join("@LLDB_TEST_MODULE_CACHE_CLANG@", "lldb-shell")