xref: /aosp_15_r20/external/cronet/base/debug/asan_service_unittest.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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