diff options
Diffstat (limited to 'lib/sanitizer_common/tests')
8 files changed, 152 insertions, 47 deletions
diff --git a/lib/sanitizer_common/tests/CMakeLists.txt b/lib/sanitizer_common/tests/CMakeLists.txt index 75008db3b6c9..b0165eac25f0 100644 --- a/lib/sanitizer_common/tests/CMakeLists.txt +++ b/lib/sanitizer_common/tests/CMakeLists.txt @@ -28,6 +28,7 @@ set(SANITIZER_UNITTESTS sanitizer_stacktrace_test.cc sanitizer_stoptheworld_test.cc sanitizer_suppressions_test.cc + sanitizer_symbolizer_test.cc sanitizer_test_main.cc sanitizer_thread_registry_test.cc) @@ -50,23 +51,33 @@ set(SANITIZER_TEST_CFLAGS_COMMON -Werror=sign-compare -Wno-non-virtual-dtor) +if(MSVC) + # Disable exceptions on Windows until they work reliably. + list(APPEND SANITIZER_TEST_CFLAGS_COMMON -fno-exceptions -DGTEST_HAS_SEH=0) +endif() + # -gline-tables-only must be enough for these tests, so use it if possible. if(COMPILER_RT_TEST_COMPILER_ID MATCHES "Clang") - list(APPEND ASAN_UNITTEST_COMMON_CFLAGS -gline-tables-only) + list(APPEND SANITIZER_TEST_CFLAGS_COMMON -gline-tables-only) else() - list(APPEND ASAN_UNITTEST_COMMON_CFLAGS -g) + list(APPEND SANITIZER_TEST_CFLAGS_COMMON -g) endif() if(NOT MSVC) list(APPEND SANITIZER_TEST_LINK_FLAGS_COMMON --driver-mode=g++) endif() +if(ANDROID) + list(APPEND SANITIZER_TEST_LINK_FLAGS_COMMON -pie) +endif() + set(SANITIZER_TEST_LINK_LIBS) append_list_if(ANDROID log SANITIZER_TEST_LINK_LIBS) # NDK r10 requires -latomic almost always. append_list_if(ANDROID atomic SANITIZER_TEST_LINK_LIBS) append_list_if(COMPILER_RT_HAS_LIBDL -ldl SANITIZER_TEST_LINK_FLAGS_COMMON) +append_list_if(COMPILER_RT_HAS_LIBRT -lrt SANITIZER_TEST_LINK_FLAGS_COMMON) append_list_if(COMPILER_RT_HAS_LIBPTHREAD -pthread SANITIZER_TEST_LINK_FLAGS_COMMON) # x86_64 FreeBSD 9.2 additionally requires libc++ to build the tests. Also, # 'libm' shall be specified explicitly to build i386 tests. diff --git a/lib/sanitizer_common/tests/sanitizer_libc_test.cc b/lib/sanitizer_common/tests/sanitizer_libc_test.cc index 8712d2c1b2a5..3252db77653d 100644 --- a/lib/sanitizer_common/tests/sanitizer_libc_test.cc +++ b/lib/sanitizer_common/tests/sanitizer_libc_test.cc @@ -17,6 +17,7 @@ #if SANITIZER_LINUX || SANITIZER_MAC # define SANITIZER_TEST_HAS_STAT_H 1 # include <sys/stat.h> +# include "sanitizer_common/sanitizer_posix.h" #else # define SANITIZER_TEST_HAS_STAT_H 0 #endif @@ -78,16 +79,14 @@ TEST(SanitizerCommon, FileOps) { char tmpfile[128]; temp_file_name(tmpfile, sizeof(tmpfile), "sanitizer_common.fileops.tmp."); - uptr openrv = OpenFile(tmpfile, true); - EXPECT_FALSE(internal_iserror(openrv)); - fd_t fd = openrv; + fd_t fd = OpenFile(tmpfile, WrOnly); + ASSERT_NE(fd, kInvalidFd); EXPECT_EQ(len1, internal_write(fd, str1, len1)); EXPECT_EQ(len2, internal_write(fd, str2, len2)); - internal_close(fd); + CloseFile(fd); - openrv = OpenFile(tmpfile, false); - EXPECT_FALSE(internal_iserror(openrv)); - fd = openrv; + fd = OpenFile(tmpfile, RdOnly); + ASSERT_NE(fd, kInvalidFd); uptr fsize = internal_filesize(fd); EXPECT_EQ(len1 + len2, fsize); @@ -115,7 +114,7 @@ TEST(SanitizerCommon, FileOps) { internal_memset(buf, 0, len1); EXPECT_EQ(len2, internal_read(fd, buf, len2)); EXPECT_EQ(0, internal_memcmp(buf, str2, len2)); - internal_close(fd); + CloseFile(fd); internal_unlink(tmpfile); } #endif @@ -134,12 +133,11 @@ TEST(SanitizerCommon, InternalMmapWithOffset) { char tmpfile[128]; temp_file_name(tmpfile, sizeof(tmpfile), "sanitizer_common.internalmmapwithoffset.tmp."); - uptr res = OpenFile(tmpfile, true); - ASSERT_FALSE(internal_iserror(res)); - fd_t fd = res; + fd_t fd = OpenFile(tmpfile, RdWr); + ASSERT_NE(fd, kInvalidFd); uptr page_size = GetPageSizeCached(); - res = internal_ftruncate(fd, page_size * 2); + uptr res = internal_ftruncate(fd, page_size * 2); ASSERT_FALSE(internal_iserror(res)); res = internal_lseek(fd, page_size, SEEK_SET); @@ -154,8 +152,8 @@ TEST(SanitizerCommon, InternalMmapWithOffset) { ASSERT_EQ('A', p[0]); ASSERT_EQ('B', p[1]); - internal_close(fd); - internal_munmap(p, page_size); + CloseFile(fd); + UnmapOrDie(p, page_size); internal_unlink(tmpfile); } #endif diff --git a/lib/sanitizer_common/tests/sanitizer_posix_test.cc b/lib/sanitizer_common/tests/sanitizer_posix_test.cc index 56ce416141fa..03ca449d3622 100644 --- a/lib/sanitizer_common/tests/sanitizer_posix_test.cc +++ b/lib/sanitizer_common/tests/sanitizer_posix_test.cc @@ -52,9 +52,9 @@ static void SpawnThread(uptr iteration) { TEST(SanitizerCommon, PthreadDestructorIterations) { ASSERT_EQ(0, pthread_key_create(&key, &destructor)); - SpawnThread(kPthreadDestructorIterations); + SpawnThread(GetPthreadDestructorIterations()); EXPECT_TRUE(destructor_executed); - SpawnThread(kPthreadDestructorIterations + 1); + SpawnThread(GetPthreadDestructorIterations() + 1); EXPECT_FALSE(destructor_executed); } diff --git a/lib/sanitizer_common/tests/sanitizer_procmaps_test.cc b/lib/sanitizer_common/tests/sanitizer_procmaps_test.cc index abe4ef43093f..12bc9e18193a 100644 --- a/lib/sanitizer_common/tests/sanitizer_procmaps_test.cc +++ b/lib/sanitizer_common/tests/sanitizer_procmaps_test.cc @@ -37,8 +37,7 @@ TEST(MemoryMappingLayout, DumpListOfModules) { const char *binary_name = last_slash ? last_slash + 1 : argv0; MemoryMappingLayout memory_mapping(false); const uptr kMaxModules = 100; - LoadedModule *modules = - (LoadedModule *)malloc(kMaxModules * sizeof(LoadedModule)); + LoadedModule modules[kMaxModules]; uptr n_modules = memory_mapping.DumpListOfModules(modules, kMaxModules, 0); EXPECT_GT(n_modules, 0U); bool found = false; @@ -51,7 +50,6 @@ TEST(MemoryMappingLayout, DumpListOfModules) { modules[i].clear(); } EXPECT_TRUE(found); - free(modules); } } // namespace __sanitizer diff --git a/lib/sanitizer_common/tests/sanitizer_stacktrace_printer_test.cc b/lib/sanitizer_common/tests/sanitizer_stacktrace_printer_test.cc index cc9a9edbbb46..05796fcbff77 100644 --- a/lib/sanitizer_common/tests/sanitizer_stacktrace_printer_test.cc +++ b/lib/sanitizer_common/tests/sanitizer_stacktrace_printer_test.cc @@ -18,20 +18,36 @@ namespace __sanitizer { TEST(SanitizerStacktracePrinter, RenderSourceLocation) { InternalScopedString str(128); - RenderSourceLocation(&str, "/dir/file.cc", 10, 5, ""); + RenderSourceLocation(&str, "/dir/file.cc", 10, 5, false, ""); EXPECT_STREQ("/dir/file.cc:10:5", str.data()); str.clear(); - RenderSourceLocation(&str, "/dir/file.cc", 11, 0, ""); + RenderSourceLocation(&str, "/dir/file.cc", 11, 0, false, ""); EXPECT_STREQ("/dir/file.cc:11", str.data()); str.clear(); - RenderSourceLocation(&str, "/dir/file.cc", 0, 0, ""); + RenderSourceLocation(&str, "/dir/file.cc", 0, 0, false, ""); EXPECT_STREQ("/dir/file.cc", str.data()); str.clear(); - RenderSourceLocation(&str, "/dir/file.cc", 10, 5, "/dir/"); + RenderSourceLocation(&str, "/dir/file.cc", 10, 5, false, "/dir/"); EXPECT_STREQ("file.cc:10:5", str.data()); + + str.clear(); + RenderSourceLocation(&str, "/dir/file.cc", 10, 5, true, ""); + EXPECT_STREQ("/dir/file.cc(10,5)", str.data()); + + str.clear(); + RenderSourceLocation(&str, "/dir/file.cc", 11, 0, true, ""); + EXPECT_STREQ("/dir/file.cc(11)", str.data()); + + str.clear(); + RenderSourceLocation(&str, "/dir/file.cc", 0, 0, true, ""); + EXPECT_STREQ("/dir/file.cc", str.data()); + + str.clear(); + RenderSourceLocation(&str, "/dir/file.cc", 10, 5, true, "/dir/"); + EXPECT_STREQ("file.cc(10,5)", str.data()); } TEST(SanitizerStacktracePrinter, RenderModuleLocation) { @@ -62,7 +78,7 @@ TEST(SanitizerStacktracePrinter, RenderFrame) { RenderFrame(&str, "%% Frame:%n PC:%p Module:%m ModuleOffset:%o " "Function:%f FunctionOffset:%q Source:%s Line:%l " "Column:%c", - frame_no, info, "/path/to/", "function_"); + frame_no, info, false, "/path/to/", "function_"); EXPECT_STREQ("% Frame:42 PC:0x400000 Module:my/module ModuleOffset:0x200 " "Function:foo FunctionOffset:0x100 Source:my/source Line:10 " "Column:5", @@ -72,50 +88,64 @@ TEST(SanitizerStacktracePrinter, RenderFrame) { // Test special format specifiers. info.address = 0x400000; - RenderFrame(&str, "%M", frame_no, info); + RenderFrame(&str, "%M", frame_no, info, false); EXPECT_NE(nullptr, internal_strstr(str.data(), "400000")); str.clear(); - RenderFrame(&str, "%L", frame_no, info); + RenderFrame(&str, "%L", frame_no, info, false); EXPECT_STREQ("(<unknown module>)", str.data()); str.clear(); info.module = internal_strdup("/path/to/module"); info.module_offset = 0x200; - RenderFrame(&str, "%M", frame_no, info); + RenderFrame(&str, "%M", frame_no, info, false); EXPECT_NE(nullptr, internal_strstr(str.data(), "(module+0x")); EXPECT_NE(nullptr, internal_strstr(str.data(), "200")); str.clear(); - RenderFrame(&str, "%L", frame_no, info); + RenderFrame(&str, "%L", frame_no, info, false); EXPECT_STREQ("(/path/to/module+0x200)", str.data()); str.clear(); info.function = internal_strdup("my_function"); - RenderFrame(&str, "%F", frame_no, info); + RenderFrame(&str, "%F", frame_no, info, false); EXPECT_STREQ("in my_function", str.data()); str.clear(); info.function_offset = 0x100; - RenderFrame(&str, "%F %S", frame_no, info); + RenderFrame(&str, "%F %S", frame_no, info, false); EXPECT_STREQ("in my_function+0x100 <null>", str.data()); str.clear(); info.file = internal_strdup("my_file"); - RenderFrame(&str, "%F %S", frame_no, info); + RenderFrame(&str, "%F %S", frame_no, info, false); EXPECT_STREQ("in my_function my_file", str.data()); str.clear(); info.line = 10; - RenderFrame(&str, "%F %S", frame_no, info); + RenderFrame(&str, "%F %S", frame_no, info, false); EXPECT_STREQ("in my_function my_file:10", str.data()); str.clear(); info.column = 5; - RenderFrame(&str, "%S %L", frame_no, info); + RenderFrame(&str, "%S %L", frame_no, info, false); EXPECT_STREQ("my_file:10:5 my_file:10:5", str.data()); str.clear(); + RenderFrame(&str, "%S %L", frame_no, info, true); + EXPECT_STREQ("my_file(10,5) my_file(10,5)", str.data()); + str.clear(); + + info.column = 0; + RenderFrame(&str, "%F %S", frame_no, info, true); + EXPECT_STREQ("in my_function my_file(10)", str.data()); + str.clear(); + + info.line = 0; + RenderFrame(&str, "%F %S", frame_no, info, true); + EXPECT_STREQ("in my_function my_file", str.data()); + str.clear(); + info.Clear(); } diff --git a/lib/sanitizer_common/tests/sanitizer_stacktrace_test.cc b/lib/sanitizer_common/tests/sanitizer_stacktrace_test.cc index ac820c25a0f8..654ea1db82fb 100644 --- a/lib/sanitizer_common/tests/sanitizer_stacktrace_test.cc +++ b/lib/sanitizer_common/tests/sanitizer_stacktrace_test.cc @@ -30,11 +30,11 @@ class FastUnwindTest : public ::testing::Test { } void *mapping; - uptr *fake_stack; + uhwptr *fake_stack; const uptr fake_stack_size = 10; - uptr start_pc; - uptr fake_top; - uptr fake_bottom; + uhwptr start_pc; + uhwptr fake_top; + uhwptr fake_bottom; BufferedStackTrace trace; }; @@ -45,10 +45,10 @@ static uptr PC(uptr idx) { void FastUnwindTest::SetUp() { size_t ps = GetPageSize(); mapping = MmapOrDie(2 * ps, "FastUnwindTest"); - Mprotect((uptr)mapping, ps); + MprotectNoAccess((uptr)mapping, ps); // Unwinder may peek 1 word down from the starting FP. - fake_stack = (uptr *)((uptr)mapping + ps + sizeof(uptr)); + fake_stack = (uhwptr *)((uptr)mapping + ps + sizeof(uhwptr)); // Fill an array of pointers with fake fp+retaddr pairs. Frame pointers have // even indices. @@ -57,12 +57,12 @@ void FastUnwindTest::SetUp() { fake_stack[i+1] = PC(i + 1); // retaddr } // Mark the last fp point back up to terminate the stack trace. - fake_stack[RoundDownTo(fake_stack_size - 1, 2)] = (uptr)&fake_stack[0]; + fake_stack[RoundDownTo(fake_stack_size - 1, 2)] = (uhwptr)&fake_stack[0]; // Top is two slots past the end because FastUnwindStack subtracts two. - fake_top = (uptr)&fake_stack[fake_stack_size + 2]; + fake_top = (uhwptr)&fake_stack[fake_stack_size + 2]; // Bottom is one slot before the start because FastUnwindStack uses >. - fake_bottom = (uptr)mapping; + fake_bottom = (uhwptr)mapping; start_pc = PC(0); } @@ -85,7 +85,7 @@ TEST_F(FastUnwindTest, Basic) { // From: http://code.google.com/p/address-sanitizer/issues/detail?id=162 TEST_F(FastUnwindTest, FramePointerLoop) { // Make one fp point to itself. - fake_stack[4] = (uptr)&fake_stack[4]; + fake_stack[4] = (uhwptr)&fake_stack[4]; if (!TryFastUnwind(kStackTraceMax)) return; // Should get all on-stack retaddrs up to the 4th slot and start_pc. @@ -114,7 +114,7 @@ TEST_F(FastUnwindTest, OneFrameStackTrace) { return; EXPECT_EQ(1U, trace.size); EXPECT_EQ(start_pc, trace.trace[0]); - EXPECT_EQ((uptr)&fake_stack[0], trace.top_frame_bp); + EXPECT_EQ((uhwptr)&fake_stack[0], trace.top_frame_bp); } TEST_F(FastUnwindTest, ZeroFramesStackTrace) { @@ -127,7 +127,7 @@ TEST_F(FastUnwindTest, ZeroFramesStackTrace) { TEST_F(FastUnwindTest, FPBelowPrevFP) { // The next FP points to unreadable memory inside the stack limits, but below // current FP. - fake_stack[0] = (uptr)&fake_stack[-50]; + fake_stack[0] = (uhwptr)&fake_stack[-50]; fake_stack[1] = PC(1); if (!TryFastUnwind(3)) return; diff --git a/lib/sanitizer_common/tests/sanitizer_stoptheworld_test.cc b/lib/sanitizer_common/tests/sanitizer_stoptheworld_test.cc index b6786ba8b013..802af392c609 100644 --- a/lib/sanitizer_common/tests/sanitizer_stoptheworld_test.cc +++ b/lib/sanitizer_common/tests/sanitizer_stoptheworld_test.cc @@ -189,6 +189,16 @@ TEST(StopTheWorld, SuspendThreadsAdvanced) { pthread_mutex_destroy(&advanced_incrementer_thread_exit_mutex); } +static void SegvCallback(const SuspendedThreadsList &suspended_threads_list, + void *argument) { + *(volatile int*)0x1234 = 0; +} + +TEST(StopTheWorld, SegvInCallback) { + // Test that tracer thread catches SIGSEGV. + StopTheWorld(&SegvCallback, NULL); +} + } // namespace __sanitizer #endif // SANITIZER_LINUX && defined(__x86_64__) diff --git a/lib/sanitizer_common/tests/sanitizer_symbolizer_test.cc b/lib/sanitizer_common/tests/sanitizer_symbolizer_test.cc new file mode 100644 index 000000000000..429ac591e502 --- /dev/null +++ b/lib/sanitizer_common/tests/sanitizer_symbolizer_test.cc @@ -0,0 +1,58 @@ +//===-- sanitizer_symbolizer_test.cc --------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Tests for sanitizer_symbolizer.h and sanitizer_symbolizer_internal.h +// +//===----------------------------------------------------------------------===// + +#include "sanitizer_common/sanitizer_allocator_internal.h" +#include "sanitizer_common/sanitizer_symbolizer_internal.h" +#include "gtest/gtest.h" + +namespace __sanitizer { + +TEST(Symbolizer, ExtractToken) { + char *token; + const char *rest; + + rest = ExtractToken("a;b;c", ";", &token); + EXPECT_STREQ("a", token); + EXPECT_STREQ("b;c", rest); + InternalFree(token); + + rest = ExtractToken("aaa-bbb.ccc", ";.-*", &token); + EXPECT_STREQ("aaa", token); + EXPECT_STREQ("bbb.ccc", rest); + InternalFree(token); +} + +TEST(Symbolizer, ExtractInt) { + int token; + const char *rest = ExtractInt("123,456;789", ";,", &token); + EXPECT_EQ(123, token); + EXPECT_STREQ("456;789", rest); +} + +TEST(Symbolizer, ExtractUptr) { + uptr token; + const char *rest = ExtractUptr("123,456;789", ";,", &token); + EXPECT_EQ(123U, token); + EXPECT_STREQ("456;789", rest); +} + +TEST(Symbolizer, ExtractTokenUpToDelimiter) { + char *token; + const char *rest = + ExtractTokenUpToDelimiter("aaa-+-bbb-+-ccc", "-+-", &token); + EXPECT_STREQ("aaa", token); + EXPECT_STREQ("bbb-+-ccc", rest); + InternalFree(token); +} + +} // namespace __sanitizer |