Differential D115204 Diff 395276 compiler-rt/lib/sanitizer_common/tests/sanitizer_stoptheworld_test.cpp
Changeset View
Changeset View
Standalone View
Standalone View
compiler-rt/lib/sanitizer_common/tests/sanitizer_stoptheworld_test.cpp
//===-- sanitizer_stoptheworld_test.cpp -----------------------------------===// | //===-- sanitizer_stoptheworld_test.cpp -----------------------------------===// | ||||
// | // | ||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||||
// See https://llvm.org/LICENSE.txt for license information. | // See https://llvm.org/LICENSE.txt for license information. | ||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||||
// | // | ||||
//===----------------------------------------------------------------------===// | //===----------------------------------------------------------------------===// | ||||
// | // | ||||
// Tests for sanitizer_stoptheworld.h | // Tests for sanitizer_stoptheworld.h | ||||
// | // | ||||
//===----------------------------------------------------------------------===// | //===----------------------------------------------------------------------===// | ||||
#include "sanitizer_common/sanitizer_stoptheworld.h" | #include "sanitizer_common/sanitizer_stoptheworld.h" | ||||
#include "sanitizer_common/sanitizer_platform.h" | #include "sanitizer_common/sanitizer_platform.h" | ||||
#if SANITIZER_LINUX && defined(__x86_64__) | #if (SANITIZER_LINUX || SANITIZER_WINDOWS) && defined(__x86_64__) | ||||
# include <atomic> | # include <atomic> | ||||
# include <mutex> | # include <mutex> | ||||
# include <thread> | # include <thread> | ||||
# include "gtest/gtest.h" | # include "gtest/gtest.h" | ||||
# include "sanitizer_common/sanitizer_common.h" | # include "sanitizer_common/sanitizer_common.h" | ||||
# include "sanitizer_common/sanitizer_libc.h" | # include "sanitizer_common/sanitizer_libc.h" | ||||
▲ Show 20 Lines • Show All 104 Lines • ▼ Show 20 Lines | void AdvancedCallback(const SuspendedThreadsList &suspended_threads_list, | ||||
} | } | ||||
callback_argument->threads_stopped = true; | callback_argument->threads_stopped = true; | ||||
} | } | ||||
TEST(StopTheWorld, SuspendThreadsAdvanced) { | TEST(StopTheWorld, SuspendThreadsAdvanced) { | ||||
AdvancedCallbackArgument argument; | AdvancedCallbackArgument argument; | ||||
{ | { | ||||
std::lock_guard<std::mutex> lock(mutex); | std::lock_guard<std::mutex> lock(mutex); | ||||
vitalybuka: why do we need NO_THROW? Isn't the test fails if it throws anyway?
And I see the following on… | |||||
argument.threads[0] = | argument.threads[0] = | ||||
std::thread(AdvancedIncrementerThread, std::ref(argument)); | std::thread(AdvancedIncrementerThread, std::ref(argument)); | ||||
// Wait for several threads to spawn before proceeding. | // Wait for several threads to spawn before proceeding. | ||||
while (argument.thread_index < kStopWorldAfter) std::this_thread::yield(); | while (argument.thread_index < kStopWorldAfter) std::this_thread::yield(); | ||||
StopTheWorld(&AdvancedCallback, &argument); | StopTheWorld(&AdvancedCallback, &argument); | ||||
EXPECT_TRUE(argument.callback_executed); | EXPECT_TRUE(argument.callback_executed); | ||||
EXPECT_TRUE(argument.threads_stopped); | EXPECT_TRUE(argument.threads_stopped); | ||||
// Wait for all threads to spawn before we start terminating them. | // Wait for all threads to spawn before we start terminating them. | ||||
while (argument.thread_index < kThreadCount) std::this_thread::yield(); | while (argument.thread_index < kThreadCount) std::this_thread::yield(); | ||||
} | } | ||||
// Signal the threads to terminate. | // Signal the threads to terminate. | ||||
for (auto &t : argument.threads) t.join(); | for (auto &t : argument.threads) t.join(); | ||||
} | } | ||||
static void SegvCallback(const SuspendedThreadsList &suspended_threads_list, | static void SegvCallback(const SuspendedThreadsList &suspended_threads_list, | ||||
void *argument) { | void *argument) { | ||||
*(volatile int *)0x1234 = 0; | *(volatile int *)0x1234 = 0; | ||||
} | } | ||||
TEST(StopTheWorld, SegvInCallback) { | # if SANITIZER_WINDOWS | ||||
# define MAYBE_SegvInCallback DISABLED_SegvInCallback | |||||
# else | |||||
# define MAYBE_SegvInCallback SegvInCallback | |||||
# endif | |||||
TEST(StopTheWorld, MAYBE_SegvInCallback) { | |||||
// Test that tracer thread catches SIGSEGV. | // Test that tracer thread catches SIGSEGV. | ||||
StopTheWorld(&SegvCallback, NULL); | StopTheWorld(&SegvCallback, NULL); | ||||
} | } | ||||
} // namespace __sanitizer | } // namespace __sanitizer | ||||
#endif // SANITIZER_LINUX && defined(__x86_64__) | #endif // SANITIZER_LINUX && defined(__x86_64__) |
why do we need NO_THROW? Isn't the test fails if it throws anyway?
And I see the following on linux: