diff options
Diffstat (limited to 'lldb/test')
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") |