Movatterモバイル変換


[0]ホーム

URL:


Google Git
Sign in
chromium /chromium /src /refs/heads/main /. /base /tools_sanity_unittest.cc
blob: 75986fe21b78253f27d8d318bff9f78ee7139bf3 [file] [log] [blame]
Avi Drissmane4622aa2022-09-08 20:36:06[diff] [blame]1// Copyright 2012 The Chromium Authors
glider@chromium.org0716cba2009-12-17 12:37:58[diff] [blame]2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
danakj51d26a42024-04-25 14:23:56[diff] [blame]4
5#ifdef UNSAFE_BUFFERS_BUILD
6// TODO(crbug.com/40284755): Remove this and spanify to fix the errors.
7#pragma allow_unsafe_buffers
8#endif
9
Arthur Sonzogni0844a992024-12-12 11:36:20[diff] [blame]10#include<array>
11
glider@chromium.orgc2a18492011-10-05 13:22:50[diff] [blame]12// This file contains intentional memory errors, some of which may lead to
13// crashes if the test is ran without special memory testing tools. We use these
14// errors to verify the sanity of the tools.
glider@chromium.org0716cba2009-12-17 12:37:58[diff] [blame]15
avi9b6f42932015-12-26 22:15:14[diff] [blame]16#include<stddef.h>
17
Venkatesh Srinivas4539c2962025-05-28 23:58:57[diff] [blame]18#include<atomic>
19
Scott Violet44165792018-02-22 02:08:08[diff] [blame]20#include"base/cfi_buildflags.h"
sebmarchand@chromium.orgb4b34792014-06-14 08:29:37[diff] [blame]21#include"base/debug/asan_invalid_access.h"
22#include"base/debug/profiler.h"
Hans Wennborg9f3bb63d2020-04-21 11:12:38[diff] [blame]23#include"base/logging.h"
Keishi Hattori0e45c022021-11-27 09:25:52[diff] [blame]24#include"base/memory/raw_ptr.h"
Peter Boström54d7f8d2024-11-27 23:03:11[diff] [blame]25#include"base/notreached.h"
Peter Collingbourne5a35305d2019-02-06 02:51:43[diff] [blame]26#include"base/sanitizer_buildflags.h"
brettw@chromium.org34b99632011-01-01 01:01:06[diff] [blame]27#include"base/threading/thread.h"
avi9b6f42932015-12-26 22:15:14[diff] [blame]28#include"build/build_config.h"
glider@chromium.org0716cba2009-12-17 12:37:58[diff] [blame]29#include"testing/gtest/include/gtest/gtest.h"
Nathaniel Manistaca9287e72024-04-02 15:40:57[diff] [blame]30#include"third_party/abseil-cpp/absl/base/dynamic_annotations.h"
glider@chromium.org0716cba2009-12-17 12:37:58[diff] [blame]31
Nico Weberaa5ce8fa2022-05-03 22:56:23[diff] [blame]32#if BUILDFLAG(IS_WIN)
33#include<windows.h>
34#else
35#include<dlfcn.h>
36#endif
37
brettw@chromium.orgce072a72010-12-31 20:02:16[diff] [blame]38namespace base{
39
glider@chromium.org0716cba2009-12-17 12:37:58[diff] [blame]40namespace{
41
Venkatesh Srinivas4539c2962025-05-28 23:58:57[diff] [blame]42constuint32_t kMagicValue=42;
glider@chromium.org0716cba2009-12-17 12:37:58[diff] [blame]43
glider@chromium.orgc2a18492011-10-05 13:22:50[diff] [blame]44// Helper for memory accesses that can potentially corrupt memory or cause a
45// crash during a native run.
Sigurdur Asgeirsson69d0bcd2018-03-29 21:50:51[diff] [blame]46#if defined(ADDRESS_SANITIZER)
Rohit Rao150dc5bb2020-07-22 20:43:55[diff] [blame]47#define HARMFUL_ACCESS(action, error_regexp) \
48 EXPECT_DEATH_IF_SUPPORTED(action, error_regexp)
Peter Collingbourne5a35305d2019-02-06 02:51:43[diff] [blame]49#elif BUILDFLAG(IS_HWASAN)
50#define HARMFUL_ACCESS(action, error_regexp) \
51 EXPECT_DEATH(action,"tag-mismatch")
glider@chromium.orgc2a18492011-10-05 13:22:50[diff] [blame]52#else
Mostyn Bramley-Moored0ecd6a2017-12-06 19:13:21[diff] [blame]53#define HARMFUL_ACCESS(action, error_regexp)
54#define HARMFUL_ACCESS_IS_NOOP
glider@chromium.orgc2a18492011-10-05 13:22:50[diff] [blame]55#endif
56
Peter Kasting134ef9af2024-12-28 02:30:09[diff] [blame]57voidDoReadUninitializedValue(volatilechar* ptr){
eugenis@google.com43dea192012-05-16 08:42:08[diff] [blame]58// Comparison with 64 is to prevent clang from optimizing away the
thakis@chromium.org83a13b22011-09-18 16:39:12[diff] [blame]59// jump -- valgrind only catches jumps and conditional moves, but clang uses
Mostyn Bramley-Moored0ecd6a2017-12-06 19:13:21[diff] [blame]60// the borrow flag if the condition is just `*ptr == '\0'`. We no longer
61// support valgrind, but this constant should be fine to keep as-is.
eugenis@google.com43dea192012-05-16 08:42:08[diff] [blame]62if(*ptr==64){
earthdok@chromium.org1e51a962014-01-16 05:31:41[diff] [blame]63 VLOG(1)<<"Uninit condition is true";
timurrrr@chromium.orgadf7d802010-09-23 09:12:37[diff] [blame]64}else{
earthdok@chromium.org1e51a962014-01-16 05:31:41[diff] [blame]65 VLOG(1)<<"Uninit condition is false";
timurrrr@chromium.orgadf7d802010-09-23 09:12:37[diff] [blame]66}
67}
68
Peter Kasting134ef9af2024-12-28 02:30:09[diff] [blame]69voidReadUninitializedValue(volatilechar* ptr){
earthdok@chromium.org1e51a962014-01-16 05:31:41[diff] [blame]70#if defined(MEMORY_SANITIZER)
Peter Kasting134ef9af2024-12-28 02:30:09[diff] [blame]71 EXPECT_DEATH(DoReadUninitializedValue(ptr),"use-of-uninitialized-value");
earthdok@chromium.org1e51a962014-01-16 05:31:41[diff] [blame]72#else
73DoReadUninitializedValue(ptr);
74#endif
75}
76
Mostyn Bramley-Moored0ecd6a2017-12-06 19:13:21[diff] [blame]77#ifndef HARMFUL_ACCESS_IS_NOOP
Peter Kasting134ef9af2024-12-28 02:30:09[diff] [blame]78voidReadValueOutOfArrayBoundsLeft(char* ptr){
pkasting@chromium.org45b9eba2010-10-18 23:57:49[diff] [blame]79char c= ptr[-2];
80 VLOG(1)<<"Reading a byte out of bounds: "<< c;
timurrrr@chromium.org9ded9912010-03-26 12:54:44[diff] [blame]81}
82
Peter Kasting134ef9af2024-12-28 02:30:09[diff] [blame]83voidReadValueOutOfArrayBoundsRight(char* ptr,size_t size){
pkasting@chromium.org45b9eba2010-10-18 23:57:49[diff] [blame]84char c= ptr[size+1];
85 VLOG(1)<<"Reading a byte out of bounds: "<< c;
timurrrr@chromium.org9ded9912010-03-26 12:54:44[diff] [blame]86}
87
Peter Kasting134ef9af2024-12-28 02:30:09[diff] [blame]88voidWriteValueOutOfArrayBoundsLeft(char* ptr){
timurrrr@chromium.orgf49ecd8f2011-05-10 18:03:34[diff] [blame]89 ptr[-1]= kMagicValue;
timurrrr@chromium.org9ded9912010-03-26 12:54:44[diff] [blame]90}
91
Peter Kasting134ef9af2024-12-28 02:30:09[diff] [blame]92voidWriteValueOutOfArrayBoundsRight(char* ptr,size_t size){
timurrrr@chromium.orgf49ecd8f2011-05-10 18:03:34[diff] [blame]93 ptr[size]= kMagicValue;
timurrrr@chromium.org9ded9912010-03-26 12:54:44[diff] [blame]94}
Mostyn Bramley-Moored0ecd6a2017-12-06 19:13:21[diff] [blame]95#endif// HARMFUL_ACCESS_IS_NOOP
timurrrr@chromium.org9ded9912010-03-26 12:54:44[diff] [blame]96
Peter Kasting134ef9af2024-12-28 02:30:09[diff] [blame]97voidMakeSomeErrors(char* ptr,size_t size){
timurrrr@chromium.orgadf7d802010-09-23 09:12:37[diff] [blame]98ReadUninitializedValue(ptr);
mithro@mithis.come260ebc2013-12-18 05:31:33[diff] [blame]99
Hans Wennborg2a3b7f22022-09-10 19:35:42[diff] [blame]100 HARMFUL_ACCESS(ReadValueOutOfArrayBoundsLeft(ptr),"2 bytes before");
101 HARMFUL_ACCESS(ReadValueOutOfArrayBoundsRight(ptr, size),"1 bytes after");
102 HARMFUL_ACCESS(WriteValueOutOfArrayBoundsLeft(ptr),"1 bytes before");
103 HARMFUL_ACCESS(WriteValueOutOfArrayBoundsRight(ptr, size),"0 bytes after");
timurrrr@chromium.org9ded9912010-03-26 12:54:44[diff] [blame]104}
105
glider@chromium.org66d051bb2010-10-14 08:25:54[diff] [blame]106}// namespace
107
Nico Weberaa5ce8fa2022-05-03 22:56:23[diff] [blame]108#if defined(ADDRESS_SANITIZER) || defined(LEAK_SANITIZER) || \
109 defined(MEMORY_SANITIZER)|| defined(THREAD_SANITIZER)|| \
110 defined(UNDEFINED_SANITIZER)
111// build/sanitizers/sanitizer_options.cc defines symbols like
112// __asan_default_options which the sanitizer runtime calls if they exist
113// in the executable. If they don't, the sanitizer runtime silently uses an
114// internal default value instead. The build puts the symbol
115// _sanitizer_options_link_helper (which the sanitizer runtime doesn't know
116// about, it's a chrome thing) in that file and then tells the linker that
117// that symbol must exist. This causes sanitizer_options.cc to be part of
118// our binaries, which in turn makes sure our __asan_default_options are used.
119// We had problems with __asan_default_options not being used, so this test
120// verifies that _sanitizer_options_link_helper actually makes it into our
121// binaries.
122#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_WIN)
Alison Gale81f4f2c72024-04-22 19:33:31[diff] [blame]123// TODO(crbug.com/40224191): Sanitizer options are currently broken
Nico Weberaa5ce8fa2022-05-03 22:56:23[diff] [blame]124// on Android.
Alison Gale81f4f2c72024-04-22 19:33:31[diff] [blame]125// TODO(crbug.com/40223949): __asan_default_options should be used
Nico Weberaa5ce8fa2022-05-03 22:56:23[diff] [blame]126// on Windows too, but currently isn't.
127#define MAYBE_LinksSanitizerOptions DISABLED_LinksSanitizerOptions
128#else
129#define MAYBE_LinksSanitizerOptionsLinksSanitizerOptions
130#endif
131TEST(ToolsSanityTest, MAYBE_LinksSanitizerOptions){
132constexprchar kSym[]="_sanitizer_options_link_helper";
133#if BUILDFLAG(IS_WIN)
134auto sym=GetProcAddress(GetModuleHandle(nullptr), kSym);
135#else
136void* sym= dlsym(RTLD_DEFAULT, kSym);
137#endif
138 EXPECT_TRUE(sym!=nullptr);
139}
140#endif// sanitizers
141
glider@chromium.org66d051bb2010-10-14 08:25:54[diff] [blame]142// A memory leak detector should report an error in this test.
143TEST(ToolsSanityTest,MemoryLeak){
thakis@chromium.org6bfad0e2011-11-01 11:08:09[diff] [blame]144// Without the |volatile|, clang optimizes away the next two lines.
145int*volatile leak=newint[256];// Leak some memory intentionally.
Peter Kasting134ef9af2024-12-28 02:30:09[diff] [blame]146 leak[4]=1;// Make sure the allocated memory is used.
glider@chromium.org66d051bb2010-10-14 08:25:54[diff] [blame]147}
148
Rohit Rao150dc5bb2020-07-22 20:43:55[diff] [blame]149TEST(ToolsSanityTest,AccessesToNewMemory){
Peter Collingbourne5a35305d2019-02-06 02:51:43[diff] [blame]150char* foo=newchar[16];
151MakeSomeErrors(foo,16);
Peter Kasting134ef9af2024-12-28 02:30:09[diff] [blame]152delete[] foo;
glider@chromium.orgc2a18492011-10-05 13:22:50[diff] [blame]153// Use after delete.
154 HARMFUL_ACCESS(foo[5]=0,"heap-use-after-free");
timurrrr@chromium.org9ded9912010-03-26 12:54:44[diff] [blame]155}
156
Rohit Rao150dc5bb2020-07-22 20:43:55[diff] [blame]157TEST(ToolsSanityTest,AccessesToMallocMemory){
Peter Collingbourne5a35305d2019-02-06 02:51:43[diff] [blame]158char* foo=reinterpret_cast<char*>(malloc(16));
159MakeSomeErrors(foo,16);
timurrrr@chromium.org9ded9912010-03-26 12:54:44[diff] [blame]160 free(foo);
glider@chromium.orgc2a18492011-10-05 13:22:50[diff] [blame]161// Use after free.
162 HARMFUL_ACCESS(foo[5]=0,"heap-use-after-free");
timurrrr@chromium.org9ded9912010-03-26 12:54:44[diff] [blame]163}
164
Rohit Rao150dc5bb2020-07-22 20:43:55[diff] [blame]165TEST(ToolsSanityTest,AccessesToStack){
Peter Collingbourne5a35305d2019-02-06 02:51:43[diff] [blame]166char foo[16];
167
168ReadUninitializedValue(foo);
169 HARMFUL_ACCESS(ReadValueOutOfArrayBoundsLeft(foo),
David Benjamin533295e2024-07-01 22:01:14[diff] [blame]170"underflows this variable");
Peter Collingbourne5a35305d2019-02-06 02:51:43[diff] [blame]171 HARMFUL_ACCESS(ReadValueOutOfArrayBoundsRight(foo,16),
David Benjamin533295e2024-07-01 22:01:14[diff] [blame]172"overflows this variable");
Peter Collingbourne5a35305d2019-02-06 02:51:43[diff] [blame]173 HARMFUL_ACCESS(WriteValueOutOfArrayBoundsLeft(foo),
David Benjamin533295e2024-07-01 22:01:14[diff] [blame]174"underflows this variable");
Peter Collingbourne5a35305d2019-02-06 02:51:43[diff] [blame]175 HARMFUL_ACCESS(WriteValueOutOfArrayBoundsRight(foo,16),
David Benjamin533295e2024-07-01 22:01:14[diff] [blame]176"overflows this variable");
Peter Collingbourne5a35305d2019-02-06 02:51:43[diff] [blame]177}
178
Sigurdur Asgeirsson69d0bcd2018-03-29 21:50:51[diff] [blame]179#if defined(ADDRESS_SANITIZER)
Mostyn Bramley-Moored0ecd6a2017-12-06 19:13:21[diff] [blame]180
Nico Weberd1fc45e2022-05-03 15:45:17[diff] [blame]181// alloc_dealloc_mismatch defaults to
182// !SANITIZER_MAC && !SANITIZER_WINDOWS && !SANITIZER_ANDROID,
183// in the sanitizer runtime upstream.
Chong Gu3ab0b4692022-05-05 17:20:03[diff] [blame]184#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN) || \
185 BUILDFLAG(IS_FUCHSIA)
Nico Weberd1fc45e2022-05-03 15:45:17[diff] [blame]186#define MAYBE_SingleElementDeletedWithBraces \
Peter Kasting134ef9af2024-12-28 02:30:09[diff] [blame]187 DISABLED_SingleElementDeletedWithBraces
Nico Weberd1fc45e2022-05-03 15:45:17[diff] [blame]188#define MAYBE_ArrayDeletedWithoutBraces DISABLED_ArrayDeletedWithoutBraces
189#else
190#define MAYBE_ArrayDeletedWithoutBracesArrayDeletedWithoutBraces
191#define MAYBE_SingleElementDeletedWithBracesSingleElementDeletedWithBraces
192#endif// defined(ADDRESS_SANITIZER)
193
hanscd4cce32015-05-19 17:03:14[diff] [blame]194staticint* allocateArray(){
195// Clang warns about the mismatched new[]/delete if they occur in the same
196// function.
197returnnewint[10];
198}
199
Mostyn Bramley-Moored0ecd6a2017-12-06 19:13:21[diff] [blame]200// This test may corrupt memory if not compiled with AddressSanitizer.
glider@chromium.org9a4f6182012-10-24 14:11:02[diff] [blame]201TEST(ToolsSanityTest, MAYBE_ArrayDeletedWithoutBraces){
thakis@chromium.org014b0b062011-09-18 16:30:12[diff] [blame]202// Without the |volatile|, clang optimizes away the next two lines.
hanscd4cce32015-05-19 17:03:14[diff] [blame]203int*volatile foo= allocateArray();
Nico Weberd1fc45e2022-05-03 15:45:17[diff] [blame]204 HARMFUL_ACCESS(delete foo,"alloc-dealloc-mismatch");
205// Under ASan the crash happens in the process spawned by HARMFUL_ACCESS,
206// need to free the memory in the parent.
Peter Kasting134ef9af2024-12-28 02:30:09[diff] [blame]207delete[] foo;
timurrrr@chromium.org9ded9912010-03-26 12:54:44[diff] [blame]208}
209
hanscd4cce32015-05-19 17:03:14[diff] [blame]210staticint* allocateScalar(){
211// Clang warns about the mismatched new/delete[] if they occur in the same
212// function.
213returnnewint;
214}
215
Mostyn Bramley-Moored0ecd6a2017-12-06 19:13:21[diff] [blame]216// This test may corrupt memory if not compiled with AddressSanitizer.
glider@chromium.org9a4f6182012-10-24 14:11:02[diff] [blame]217TEST(ToolsSanityTest, MAYBE_SingleElementDeletedWithBraces){
thakis@chromium.org014b0b062011-09-18 16:30:12[diff] [blame]218// Without the |volatile|, clang optimizes away the next two lines.
hanscd4cce32015-05-19 17:03:14[diff] [blame]219int*volatile foo= allocateScalar();
Peter Kasting134ef9af2024-12-28 02:30:09[diff] [blame]220(void)foo;
221 HARMFUL_ACCESS(delete[] foo,"alloc-dealloc-mismatch");
Nico Weberd1fc45e2022-05-03 15:45:17[diff] [blame]222// Under ASan the crash happens in the process spawned by HARMFUL_ACCESS,
223// need to free the memory in the parent.
224delete foo;
timurrrr@chromium.org9ded9912010-03-26 12:54:44[diff] [blame]225}
Mostyn Bramley-Moored0ecd6a2017-12-06 19:13:21[diff] [blame]226#endif
timurrrr@chromium.org9ded9912010-03-26 12:54:44[diff] [blame]227
glider@chromium.org9b147ae2011-11-08 09:28:49[diff] [blame]228TEST(ToolsSanityTest, DISABLED_AddressSanitizerNullDerefCrashTest){
glider@chromium.org6fcbc62f2011-10-12 17:18:24[diff] [blame]229// Intentionally crash to make sure AddressSanitizer is running.
230// This test should not be ran on bots.
Peter Kasting811504a72025-01-09 03:18:50[diff] [blame]231int*volatile zero=nullptr;
glider@chromium.org6fcbc62f2011-10-12 17:18:24[diff] [blame]232*zero=0;
233}
glider@chromium.org9b147ae2011-11-08 09:28:49[diff] [blame]234
235TEST(ToolsSanityTest, DISABLED_AddressSanitizerLocalOOBCrashTest){
236// Intentionally crash to make sure AddressSanitizer is instrumenting
237// the local variables.
Peter Kasting2bc85c992025-01-13 14:19:52[diff] [blame]238// This test should not be run on bots.
239int array[5];// Must not use std::array, lest hardening catch this first.
glider@chromium.org9b147ae2011-11-08 09:28:49[diff] [blame]240// Work around the OOB warning reported by Clang.
241int*volatile access=&array[5];
242*access=43;
243}
244
245namespace{
246int g_asan_test_global_array[10];
247}// namespace
248
249TEST(ToolsSanityTest, DISABLED_AddressSanitizerGlobalOOBCrashTest){
250// Intentionally crash to make sure AddressSanitizer is instrumenting
251// the global variables.
252// This test should not be ran on bots.
253
254// Work around the OOB warning reported by Clang.
255int*volatile access= g_asan_test_global_array-1;
256*access=43;
257}
258
Mostyn Bramley-Moored0ecd6a2017-12-06 19:13:21[diff] [blame]259#ifndef HARMFUL_ACCESS_IS_NOOP
sebmarchand@chromium.orgb4b34792014-06-14 08:29:37[diff] [blame]260TEST(ToolsSanityTest,AsanHeapOverflow){
Hans Wennborg2a3b7f22022-09-10 19:35:42[diff] [blame]261 HARMFUL_ACCESS(debug::AsanHeapOverflow(),"after");
sebmarchand@chromium.orgb4b34792014-06-14 08:29:37[diff] [blame]262}
263
264TEST(ToolsSanityTest,AsanHeapUnderflow){
Hans Wennborg2a3b7f22022-09-10 19:35:42[diff] [blame]265 HARMFUL_ACCESS(debug::AsanHeapUnderflow(),"before");
sebmarchand@chromium.orgb4b34792014-06-14 08:29:37[diff] [blame]266}
267
268TEST(ToolsSanityTest,AsanHeapUseAfterFree){
269 HARMFUL_ACCESS(debug::AsanHeapUseAfterFree(),"heap-use-after-free");
270}
271
Xiaohan Wang38e4ebb2022-01-19 06:57:43[diff] [blame]272#if BUILDFLAG(IS_WIN)
Sigurdur Asgeirsson597be542018-04-04 15:44:04[diff] [blame]273// The ASAN runtime doesn't detect heap corruption, this needs fixing before
274// ASAN builds can ship to the wild. See https://crbug.com/818747.
275TEST(ToolsSanityTest, DISABLED_AsanCorruptHeapBlock){
sebmarchand@chromium.orgb4b34792014-06-14 08:29:37[diff] [blame]276 HARMFUL_ACCESS(debug::AsanCorruptHeapBlock(),"");
277}
278
Sigurdur Asgeirsson597be542018-04-04 15:44:04[diff] [blame]279TEST(ToolsSanityTest, DISABLED_AsanCorruptHeap){
sebmarchand@chromium.orgb4b34792014-06-14 08:29:37[diff] [blame]280// This test will kill the process by raising an exception, there's no
281// particular string to look for in the stack trace.
282 EXPECT_DEATH(debug::AsanCorruptHeap(),"");
283}
Xiaohan Wang38e4ebb2022-01-19 06:57:43[diff] [blame]284#endif// BUILDFLAG(IS_WIN)
Mostyn Bramley-Moored0ecd6a2017-12-06 19:13:21[diff] [blame]285#endif// !HARMFUL_ACCESS_IS_NOOP
sebmarchand@chromium.orgb4b34792014-06-14 08:29:37[diff] [blame]286
timurrrr@chromium.orgf49ecd8f2011-05-10 18:03:34[diff] [blame]287namespace{
288
289// We use caps here just to ensure that the method name doesn't interfere with
290// the wildcarded suppressions.
291class TOOLS_SANITY_TEST_CONCURRENT_THREAD:publicPlatformThread::Delegate{
292public:
Peter Kasting134ef9af2024-12-28 02:30:09[diff] [blame]293explicit TOOLS_SANITY_TEST_CONCURRENT_THREAD(bool* value): value_(value){}
Chris Watkinsbb7211c2017-11-29 07:16:38[diff] [blame]294~TOOLS_SANITY_TEST_CONCURRENT_THREAD() override=default;
dcheng56488182014-10-21 10:54:51[diff] [blame]295voidThreadMain() override{
timurrrr@chromium.orgf49ecd8f2011-05-10 18:03:34[diff] [blame]296*value_=true;
297
298// Sleep for a few milliseconds so the two threads are more likely to live
299// simultaneously. Otherwise we may miss the report due to mutex
300// lock/unlock's inside thread creation code in pure-happens-before mode...
Peter Kasting53fd6ee2021-10-05 20:40:48[diff] [blame]301PlatformThread::Sleep(Milliseconds(100));
timurrrr@chromium.orgf49ecd8f2011-05-10 18:03:34[diff] [blame]302}
Peter Kasting134ef9af2024-12-28 02:30:09[diff] [blame]303
timurrrr@chromium.orgf49ecd8f2011-05-10 18:03:34[diff] [blame]304private:
Keishi Hattori0e45c022021-11-27 09:25:52[diff] [blame]305 raw_ptr<bool> value_;
timurrrr@chromium.orgf49ecd8f2011-05-10 18:03:34[diff] [blame]306};
307
308classReleaseStoreThread:publicPlatformThread::Delegate{
309public:
Venkatesh Srinivas4539c2962025-05-28 23:58:57[diff] [blame]310explicitReleaseStoreThread(std::atomic<uint32_t>*value): value_(value){}
Chris Watkinsbb7211c2017-11-29 07:16:38[diff] [blame]311~ReleaseStoreThread() override=default;
dcheng56488182014-10-21 10:54:51[diff] [blame]312voidThreadMain() override{
Venkatesh Srinivas4539c2962025-05-28 23:58:57[diff] [blame]313 value_->store(kMagicValue, std::memory_order_release);
timurrrr@chromium.orgf49ecd8f2011-05-10 18:03:34[diff] [blame]314
315// Sleep for a few milliseconds so the two threads are more likely to live
316// simultaneously. Otherwise we may miss the report due to mutex
317// lock/unlock's inside thread creation code in pure-happens-before mode...
Peter Kasting53fd6ee2021-10-05 20:40:48[diff] [blame]318PlatformThread::Sleep(Milliseconds(100));
timurrrr@chromium.orgf49ecd8f2011-05-10 18:03:34[diff] [blame]319}
Peter Kasting134ef9af2024-12-28 02:30:09[diff] [blame]320
timurrrr@chromium.orgf49ecd8f2011-05-10 18:03:34[diff] [blame]321private:
Venkatesh Srinivas4539c2962025-05-28 23:58:57[diff] [blame]322 raw_ptr<std::atomic<uint32_t>> value_;
timurrrr@chromium.orgf49ecd8f2011-05-10 18:03:34[diff] [blame]323};
324
325classAcquireLoadThread:publicPlatformThread::Delegate{
326public:
Venkatesh Srinivas4539c2962025-05-28 23:58:57[diff] [blame]327explicitAcquireLoadThread(std::atomic<uint32_t>*value): value_(value){}
Chris Watkinsbb7211c2017-11-29 07:16:38[diff] [blame]328~AcquireLoadThread() override=default;
dcheng56488182014-10-21 10:54:51[diff] [blame]329voidThreadMain() override{
timurrrr@chromium.orgf49ecd8f2011-05-10 18:03:34[diff] [blame]330// Wait for the other thread to make Release_Store
Peter Kasting53fd6ee2021-10-05 20:40:48[diff] [blame]331PlatformThread::Sleep(Milliseconds(100));
Venkatesh Srinivas4539c2962025-05-28 23:58:57[diff] [blame]332 value_->load(std::memory_order_acquire);
timurrrr@chromium.orgf49ecd8f2011-05-10 18:03:34[diff] [blame]333}
Peter Kasting134ef9af2024-12-28 02:30:09[diff] [blame]334
timurrrr@chromium.orgf49ecd8f2011-05-10 18:03:34[diff] [blame]335private:
Venkatesh Srinivas4539c2962025-05-28 23:58:57[diff] [blame]336 raw_ptr<std::atomic<uint32_t>> value_;
timurrrr@chromium.orgf49ecd8f2011-05-10 18:03:34[diff] [blame]337};
338
Peter Kasting134ef9af2024-12-28 02:30:09[diff] [blame]339voidRunInParallel(PlatformThread::Delegate* d1,PlatformThread::Delegate* d2){
timurrrr@chromium.orgf49ecd8f2011-05-10 18:03:34[diff] [blame]340PlatformThreadHandle a;
341PlatformThreadHandle b;
342PlatformThread::Create(0, d1,&a);
343PlatformThread::Create(0, d2,&b);
344PlatformThread::Join(a);
345PlatformThread::Join(b);
346}
347
glider@chromium.orgb11d38d02014-06-26 13:10:50[diff] [blame]348#if defined(THREAD_SANITIZER)
349voidDataRace(){
Peter Kasting134ef9af2024-12-28 02:30:09[diff] [blame]350bool* shared=newbool(false);
glider@chromium.orga4057982013-03-23 11:28:17[diff] [blame]351 TOOLS_SANITY_TEST_CONCURRENT_THREAD thread1(shared), thread2(shared);
timurrrr@chromium.orgf49ecd8f2011-05-10 18:03:34[diff] [blame]352RunInParallel(&thread1,&thread2);
glider@chromium.orga4057982013-03-23 11:28:17[diff] [blame]353 EXPECT_TRUE(*shared);
354delete shared;
glider@chromium.orgb11d38d02014-06-26 13:10:50[diff] [blame]355// We're in a death test - crash.
Peter Boström54d7f8d2024-11-27 23:03:11[diff] [blame]356 NOTREACHED();
timurrrr@chromium.orgf49ecd8f2011-05-10 18:03:34[diff] [blame]357}
glider@chromium.orgb11d38d02014-06-26 13:10:50[diff] [blame]358#endif
359
360}// namespace
361
362#if defined(THREAD_SANITIZER)
363// A data race detector should report an error in this test.
Fumitoshi Ukaice2f3082025-05-26 02:30:45[diff] [blame]364TEST(ToolsSanityTest,DataRace){
glider@chromium.orgb11d38d02014-06-26 13:10:50[diff] [blame]365// The suppression regexp must match that in base/debug/tsan_suppressions.cc.
366 EXPECT_DEATH(DataRace(),"1 race:base/tools_sanity_unittest.cc");
367}
368#endif
timurrrr@chromium.orgf49ecd8f2011-05-10 18:03:34[diff] [blame]369
370TEST(ToolsSanityTest,AnnotateBenignRace){
371bool shared=false;
Peter Kasting134ef9af2024-12-28 02:30:09[diff] [blame]372 ABSL_ANNOTATE_BENIGN_RACE(&shared,
373"Intentional race - make sure doesn't show up");
timurrrr@chromium.orgf49ecd8f2011-05-10 18:03:34[diff] [blame]374 TOOLS_SANITY_TEST_CONCURRENT_THREAD thread1(&shared), thread2(&shared);
375RunInParallel(&thread1,&thread2);
376 EXPECT_TRUE(shared);
377}
378
379TEST(ToolsSanityTest,AtomicsAreIgnored){
Venkatesh Srinivas4539c2962025-05-28 23:58:57[diff] [blame]380 std::atomic<uint32_t> shared=0;
timurrrr@chromium.orgf49ecd8f2011-05-10 18:03:34[diff] [blame]381ReleaseStoreThread thread1(&shared);
382AcquireLoadThread thread2(&shared);
383RunInParallel(&thread1,&thread2);
384 EXPECT_EQ(kMagicValue, shared);
glider@chromium.org0716cba2009-12-17 12:37:58[diff] [blame]385}
brettw@chromium.orgce072a72010-12-31 20:02:16[diff] [blame]386
Vlad Tsyrkleviche0408ff2017-10-13 19:35:24[diff] [blame]387#if BUILDFLAG(CFI_ENFORCEMENT_TRAP)
Xiaohan Wang38e4ebb2022-01-19 06:57:43[diff] [blame]388#if BUILDFLAG(IS_WIN)
Peter Collingbourne355546f2017-10-12 19:51:27[diff] [blame]389#define CFI_ERROR_MSG"EXCEPTION_ILLEGAL_INSTRUCTION"
Xiaohan Wang38e4ebb2022-01-19 06:57:43[diff] [blame]390#elif BUILDFLAG(IS_ANDROID)
Peter Collingbourne355546f2017-10-12 19:51:27[diff] [blame]391// TODO(pcc): Produce proper stack dumps on Android and test for the correct
392// si_code here.
393#define CFI_ERROR_MSG"^$"
394#else
Vlad Tsyrklevich37f1e352017-08-15 23:45:10[diff] [blame]395#define CFI_ERROR_MSG"ILL_ILLOPN"
Peter Collingbourne355546f2017-10-12 19:51:27[diff] [blame]396#endif
Vlad Tsyrkleviche0408ff2017-10-13 19:35:24[diff] [blame]397#elif BUILDFLAG(CFI_ENFORCEMENT_DIAGNOSTIC)
Vlad Tsyrklevich37f1e352017-08-15 23:45:10[diff] [blame]398#define CFI_ERROR_MSG"runtime error: control flow integrity check"
Vlad Tsyrkleviche0408ff2017-10-13 19:35:24[diff] [blame]399#endif// BUILDFLAG(CFI_ENFORCEMENT_TRAP || CFI_ENFORCEMENT_DIAGNOSTIC)
pcc07364912015-07-31 00:19:06[diff] [blame]400
Vlad Tsyrklevich37f1e352017-08-15 23:45:10[diff] [blame]401#if defined(CFI_ERROR_MSG)
krasin59d37182016-07-13 03:24:34[diff] [blame]402class A{
403public:
Peter Kasting134ef9af2024-12-28 02:30:09[diff] [blame]404 A(): n_(0){}
krasin59d37182016-07-13 03:24:34[diff] [blame]405virtualvoid f(){ n_++;}
Peter Kasting134ef9af2024-12-28 02:30:09[diff] [blame]406
krasin59d37182016-07-13 03:24:34[diff] [blame]407protected:
408int n_;
409};
410
Peter Kasting134ef9af2024-12-28 02:30:09[diff] [blame]411class B:public A{
krasin59d37182016-07-13 03:24:34[diff] [blame]412public:
413void f() override{ n_--;}
414};
415
Peter Kasting134ef9af2024-12-28 02:30:09[diff] [blame]416class C:public B{
Vlad Tsyrklevich37f1e352017-08-15 23:45:10[diff] [blame]417public:
418void f() override{ n_+=2;}
419};
420
Peter Kasting134ef9af2024-12-28 02:30:09[diff] [blame]421NOINLINEvoidKillVptrAndCall(A* obj){
422*reinterpret_cast<void**>(obj)=0;
krasin59d37182016-07-13 03:24:34[diff] [blame]423 obj->f();
424}
425
Vlad Tsyrklevich37f1e352017-08-15 23:45:10[diff] [blame]426TEST(ToolsSanityTest,BadVirtualCallNull){
krasin59d37182016-07-13 03:24:34[diff] [blame]427 A a;
428 B b;
Peter Kasting134ef9af2024-12-28 02:30:09[diff] [blame]429 EXPECT_DEATH(
430{
431KillVptrAndCall(&a);
432KillVptrAndCall(&b);
433},
434 CFI_ERROR_MSG);
krasin59d37182016-07-13 03:24:34[diff] [blame]435}
436
Peter Kasting134ef9af2024-12-28 02:30:09[diff] [blame]437NOINLINEvoidOverwriteVptrAndCall(B* obj, A* vptr){
438*reinterpret_cast<void**>(obj)=*reinterpret_cast<void**>(vptr);
Vlad Tsyrklevich37f1e352017-08-15 23:45:10[diff] [blame]439 obj->f();
440}
441
442TEST(ToolsSanityTest,BadVirtualCallWrongType){
443 A a;
444 B b;
445 C c;
Peter Kasting134ef9af2024-12-28 02:30:09[diff] [blame]446 EXPECT_DEATH(
447{
448OverwriteVptrAndCall(&b,&a);
449OverwriteVptrAndCall(&b,&c);
450},
451 CFI_ERROR_MSG);
Vlad Tsyrklevich37f1e352017-08-15 23:45:10[diff] [blame]452}
453
454// TODO(pcc): remove CFI_CAST_CHECK, see https://crbug.com/626794.
Vlad Tsyrkleviche0408ff2017-10-13 19:35:24[diff] [blame]455#if BUILDFLAG(CFI_CAST_CHECK)
Vlad Tsyrklevich37f1e352017-08-15 23:45:10[diff] [blame]456TEST(ToolsSanityTest,BadDerivedCast){
457 A a;
458 EXPECT_DEATH((void)(B*)&a, CFI_ERROR_MSG);
459}
460
461TEST(ToolsSanityTest,BadUnrelatedCast){
462class A{
463virtualvoid f(){}
464};
465
466class B{
467virtualvoid f(){}
468};
469
470 A a;
471 EXPECT_DEATH((void)(B*)&a, CFI_ERROR_MSG);
472}
Vlad Tsyrkleviche0408ff2017-10-13 19:35:24[diff] [blame]473#endif// BUILDFLAG(CFI_CAST_CHECK)
Vlad Tsyrklevich37f1e352017-08-15 23:45:10[diff] [blame]474
Vlad Tsyrkleviche0408ff2017-10-13 19:35:24[diff] [blame]475#endif// CFI_ERROR_MSG
pcc07364912015-07-31 00:19:06[diff] [blame]476
Mostyn Bramley-Moored0ecd6a2017-12-06 19:13:21[diff] [blame]477#undef CFI_ERROR_MSG
Mostyn Bramley-Moored0ecd6a2017-12-06 19:13:21[diff] [blame]478#undef HARMFUL_ACCESS
479#undef HARMFUL_ACCESS_IS_NOOP
480
brettw@chromium.orgce072a72010-12-31 20:02:16[diff] [blame]481}// namespace base

[8]ページ先頭

©2009-2025 Movatter.jp