Index: lib/asan/tests/CMakeLists.txt =================================================================== --- lib/asan/tests/CMakeLists.txt +++ lib/asan/tests/CMakeLists.txt @@ -28,6 +28,7 @@ -I${COMPILER_RT_SOURCE_DIR}/lib/asan -I${COMPILER_RT_SOURCE_DIR}/lib/sanitizer_common/tests -fno-rtti + -fno-inline-functions -O2 -Wno-format -Werror=sign-compare) Index: lib/asan/tests/asan_asm_test.cc =================================================================== --- lib/asan/tests/asan_asm_test.cc +++ lib/asan/tests/asan_asm_test.cc @@ -201,6 +201,32 @@ asm_rep_movs(dp, sp, 0); } +int __attribute__((noinline)) +TestAsmStacktraceRec(int depth, int n, int *buffer) { + if (depth != 0) + return depth * TestAsmStacktraceRec(depth - 1, n, buffer); + int r; + __asm__("movl (%[buffer], %[n], 4), %[r] \n\t" + : [r] "=r"(r) + : [buffer] "r"(buffer), [n] "r"(static_cast(n)) + : "memory"); + return r; +} + +void __attribute__((noinline)) TestAsmStacktrace() { + const int size = 16; + const int depth = 4; + int *buffer = new int[size]; + EXPECT_DEATH(TestAsmStacktraceRec(depth, size, buffer), + ".*#0.*TestAsmStacktraceRec(.*).*\\n" + ".*#1.*TestAsmStacktraceRec(.*).*\\n" + ".*#2.*TestAsmStacktraceRec(.*).*\\n" + ".*#3.*TestAsmStacktraceRec(.*).*\\n" + ".*#4.*TestAsmStacktraceRec(.*).*\\n" + ".*#5.*TestAsmStacktrace().*\\n"); + delete[] buffer; +} + } // End of anonymous namespace TEST(AddressSanitizer, asm_load_store) { @@ -262,6 +288,10 @@ #endif // defined(__x86_64__) } +TEST(AddressSanitizer, asm_stacktrace) { + TestAsmStacktrace(); +} + #endif // defined(__x86_64__) || (defined(__i386__) && defined(__SSE2__)) #endif // defined(__linux__)