1*6777b538SAndroid Build Coastguard Worker // Copyright 2022 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker
5*6777b538SAndroid Build Coastguard Worker #include "base/debug/asan_service.h"
6*6777b538SAndroid Build Coastguard Worker
7*6777b538SAndroid Build Coastguard Worker #if defined(ADDRESS_SANITIZER)
8*6777b538SAndroid Build Coastguard Worker
9*6777b538SAndroid Build Coastguard Worker #include <map>
10*6777b538SAndroid Build Coastguard Worker #include <memory>
11*6777b538SAndroid Build Coastguard Worker #include <sstream>
12*6777b538SAndroid Build Coastguard Worker
13*6777b538SAndroid Build Coastguard Worker #include "base/debug/asan_invalid_access.h"
14*6777b538SAndroid Build Coastguard Worker #include "base/memory/raw_ref.h"
15*6777b538SAndroid Build Coastguard Worker #include "base/run_loop.h"
16*6777b538SAndroid Build Coastguard Worker #include "base/strings/string_piece.h"
17*6777b538SAndroid Build Coastguard Worker #include "base/test/bind.h"
18*6777b538SAndroid Build Coastguard Worker #include "base/test/task_environment.h"
19*6777b538SAndroid Build Coastguard Worker #include "testing/gmock/include/gmock/gmock.h"
20*6777b538SAndroid Build Coastguard Worker #include "testing/gtest/include/gtest/gtest.h"
21*6777b538SAndroid Build Coastguard Worker
22*6777b538SAndroid Build Coastguard Worker // All of the tests require death tests, so there's nothing to build if we're
23*6777b538SAndroid Build Coastguard Worker // building for a platform that doesn't support them.
24*6777b538SAndroid Build Coastguard Worker #if defined(GTEST_HAS_DEATH_TEST)
25*6777b538SAndroid Build Coastguard Worker
26*6777b538SAndroid Build Coastguard Worker namespace base {
27*6777b538SAndroid Build Coastguard Worker namespace debug {
28*6777b538SAndroid Build Coastguard Worker
29*6777b538SAndroid Build Coastguard Worker class AsanServiceTest : public ::testing::Test {
30*6777b538SAndroid Build Coastguard Worker protected:
SetUp()31*6777b538SAndroid Build Coastguard Worker void SetUp() override { AsanService::GetInstance()->Initialize(); }
32*6777b538SAndroid Build Coastguard Worker };
33*6777b538SAndroid Build Coastguard Worker
ExitedCleanly(int exit_status)34*6777b538SAndroid Build Coastguard Worker bool ExitedCleanly(int exit_status) {
35*6777b538SAndroid Build Coastguard Worker return exit_status == 0;
36*6777b538SAndroid Build Coastguard Worker }
37*6777b538SAndroid Build Coastguard Worker
38*6777b538SAndroid Build Coastguard Worker // TODO(crbug.com/1402267): ASAN death test is not picking up the failure
39*6777b538SAndroid Build Coastguard Worker // in the emulator logs. Disabling to keep ASAN queue clear.
40*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_FUCHSIA)
41*6777b538SAndroid Build Coastguard Worker #define MAYBE_ErrorCallback DISABLED_ErrorCallback
42*6777b538SAndroid Build Coastguard Worker #define MAYBE_CrashInErrorCallback DISABLED_CrashInErrorCallback
43*6777b538SAndroid Build Coastguard Worker #define MAYBE_ShouldExitCleanly DISABLED_ShouldExitCleanly
44*6777b538SAndroid Build Coastguard Worker #define MAYBE_TaskTraceCallback DISABLED_TaskTraceCallback
45*6777b538SAndroid Build Coastguard Worker #else
46*6777b538SAndroid Build Coastguard Worker #define MAYBE_ErrorCallback ErrorCallback
47*6777b538SAndroid Build Coastguard Worker #define MAYBE_CrashInErrorCallback CrashInErrorCallback
48*6777b538SAndroid Build Coastguard Worker #define MAYBE_ShouldExitCleanly ShouldExitCleanly
49*6777b538SAndroid Build Coastguard Worker #define MAYBE_TaskTraceCallback TaskTraceCallback
50*6777b538SAndroid Build Coastguard Worker #endif
51*6777b538SAndroid Build Coastguard Worker
TEST_F(AsanServiceTest,MAYBE_ErrorCallback)52*6777b538SAndroid Build Coastguard Worker TEST_F(AsanServiceTest, MAYBE_ErrorCallback) {
53*6777b538SAndroid Build Coastguard Worker // Register an error callback, and check that the output is added.
54*6777b538SAndroid Build Coastguard Worker AsanService::GetInstance()->AddErrorCallback([](const char*, bool*) {
55*6777b538SAndroid Build Coastguard Worker AsanService::GetInstance()->Log("\nErrorCallback1");
56*6777b538SAndroid Build Coastguard Worker });
57*6777b538SAndroid Build Coastguard Worker EXPECT_DEATH(AsanHeapUseAfterFree(), "ErrorCallback1");
58*6777b538SAndroid Build Coastguard Worker
59*6777b538SAndroid Build Coastguard Worker // Register a second error callback, and check that the output from both
60*6777b538SAndroid Build Coastguard Worker // callbacks is added.
61*6777b538SAndroid Build Coastguard Worker AsanService::GetInstance()->AddErrorCallback([](const char*, bool*) {
62*6777b538SAndroid Build Coastguard Worker AsanService::GetInstance()->Log("\nErrorCallback2");
63*6777b538SAndroid Build Coastguard Worker });
64*6777b538SAndroid Build Coastguard Worker EXPECT_DEATH(AsanHeapUseAfterFree(), "ErrorCallback1");
65*6777b538SAndroid Build Coastguard Worker EXPECT_DEATH(AsanHeapUseAfterFree(), "ErrorCallback2");
66*6777b538SAndroid Build Coastguard Worker }
67*6777b538SAndroid Build Coastguard Worker
TEST_F(AsanServiceTest,MAYBE_CrashInErrorCallback)68*6777b538SAndroid Build Coastguard Worker TEST_F(AsanServiceTest, MAYBE_CrashInErrorCallback) {
69*6777b538SAndroid Build Coastguard Worker // If a nested fault happens, we don't expect to get our custom log messages
70*6777b538SAndroid Build Coastguard Worker // displayed, but we should still get some part of the ASan report. This
71*6777b538SAndroid Build Coastguard Worker // matches current ASan recursive fault handling - make sure we don't end up
72*6777b538SAndroid Build Coastguard Worker // deadlocking.
73*6777b538SAndroid Build Coastguard Worker AsanService::GetInstance()->AddErrorCallback([](const char*, bool*) {
74*6777b538SAndroid Build Coastguard Worker AsanService::GetInstance()->Log("\nErrorCallback1");
75*6777b538SAndroid Build Coastguard Worker AsanHeapUseAfterFree();
76*6777b538SAndroid Build Coastguard Worker });
77*6777b538SAndroid Build Coastguard Worker EXPECT_DEATH(AsanHeapUseAfterFree(),
78*6777b538SAndroid Build Coastguard Worker "AddressSanitizer: nested bug in the same thread");
79*6777b538SAndroid Build Coastguard Worker }
80*6777b538SAndroid Build Coastguard Worker
TEST_F(AsanServiceTest,MAYBE_ShouldExitCleanly)81*6777b538SAndroid Build Coastguard Worker TEST_F(AsanServiceTest, MAYBE_ShouldExitCleanly) {
82*6777b538SAndroid Build Coastguard Worker // Register an error callback, and check that the output is added.
83*6777b538SAndroid Build Coastguard Worker AsanService::GetInstance()->AddErrorCallback([](const char*, bool*) {
84*6777b538SAndroid Build Coastguard Worker AsanService::GetInstance()->Log("\nErrorCallback1");
85*6777b538SAndroid Build Coastguard Worker });
86*6777b538SAndroid Build Coastguard Worker EXPECT_DEATH(AsanHeapUseAfterFree(), "ErrorCallback1");
87*6777b538SAndroid Build Coastguard Worker EXPECT_DEATH(AsanHeapUseAfterFree(), "ABORTING");
88*6777b538SAndroid Build Coastguard Worker
89*6777b538SAndroid Build Coastguard Worker // Register a second error callback which will set should_exit_cleanly.
90*6777b538SAndroid Build Coastguard Worker AsanService::GetInstance()->AddErrorCallback(
91*6777b538SAndroid Build Coastguard Worker [](const char* reason, bool* should_exit_cleanly) {
92*6777b538SAndroid Build Coastguard Worker AsanService::GetInstance()->Log("\nShouldExitCleanly");
93*6777b538SAndroid Build Coastguard Worker *should_exit_cleanly = true;
94*6777b538SAndroid Build Coastguard Worker });
95*6777b538SAndroid Build Coastguard Worker
96*6777b538SAndroid Build Coastguard Worker // Check that we now exit instead of crashing.
97*6777b538SAndroid Build Coastguard Worker EXPECT_EXIT(AsanHeapUseAfterFree(), ExitedCleanly, "ErrorCallback1");
98*6777b538SAndroid Build Coastguard Worker EXPECT_EXIT(AsanHeapUseAfterFree(), ExitedCleanly, "ShouldExitCleanly");
99*6777b538SAndroid Build Coastguard Worker EXPECT_EXIT(AsanHeapUseAfterFree(), ExitedCleanly, "EXITING");
100*6777b538SAndroid Build Coastguard Worker }
101*6777b538SAndroid Build Coastguard Worker
102*6777b538SAndroid Build Coastguard Worker class AsanTaskTraceTest {
103*6777b538SAndroid Build Coastguard Worker public:
AsanTaskTraceTest()104*6777b538SAndroid Build Coastguard Worker AsanTaskTraceTest() {}
105*6777b538SAndroid Build Coastguard Worker
Run()106*6777b538SAndroid Build Coastguard Worker void Run() {
107*6777b538SAndroid Build Coastguard Worker task_runner_->PostTask(
108*6777b538SAndroid Build Coastguard Worker FROM_HERE, BindOnce(&AsanTaskTraceTest::PostingTask, Unretained(this)));
109*6777b538SAndroid Build Coastguard Worker task_environment_.RunUntilIdle();
110*6777b538SAndroid Build Coastguard Worker }
111*6777b538SAndroid Build Coastguard Worker
112*6777b538SAndroid Build Coastguard Worker private:
PostingTask()113*6777b538SAndroid Build Coastguard Worker void PostingTask() {
114*6777b538SAndroid Build Coastguard Worker task_runner_->PostTask(FROM_HERE, BindOnce(&AsanHeapUseAfterFree));
115*6777b538SAndroid Build Coastguard Worker }
116*6777b538SAndroid Build Coastguard Worker
117*6777b538SAndroid Build Coastguard Worker test::TaskEnvironment task_environment_;
118*6777b538SAndroid Build Coastguard Worker const raw_ref<SingleThreadTaskRunner> task_runner_{
119*6777b538SAndroid Build Coastguard Worker *task_environment_.GetMainThreadTaskRunner()};
120*6777b538SAndroid Build Coastguard Worker };
121*6777b538SAndroid Build Coastguard Worker
TEST_F(AsanServiceTest,MAYBE_TaskTraceCallback)122*6777b538SAndroid Build Coastguard Worker TEST_F(AsanServiceTest, MAYBE_TaskTraceCallback) {
123*6777b538SAndroid Build Coastguard Worker AsanTaskTraceTest test;
124*6777b538SAndroid Build Coastguard Worker // We can't check the symbolization of the task trace, as this will fail on
125*6777b538SAndroid Build Coastguard Worker // build configurations that don't include symbols. We instead just check
126*6777b538SAndroid Build Coastguard Worker // that the task trace has the correct number of entries.
127*6777b538SAndroid Build Coastguard Worker EXPECT_DEATH(test.Run(), "#0 0x.* .*\\n\\s+#1 0x.*");
128*6777b538SAndroid Build Coastguard Worker }
129*6777b538SAndroid Build Coastguard Worker
130*6777b538SAndroid Build Coastguard Worker } // namespace debug
131*6777b538SAndroid Build Coastguard Worker } // namespace base
132*6777b538SAndroid Build Coastguard Worker
133*6777b538SAndroid Build Coastguard Worker #endif // defined(GTEST_HAS_DEATH_TEST)
134*6777b538SAndroid Build Coastguard Worker #endif // ADDRESS_SANITIZER
135