1 //===-- sanitizer_procmaps_test.cpp ---------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // This file is a part of ThreadSanitizer/AddressSanitizer runtime.
11 //===----------------------------------------------------------------------===//
12 #if !defined(_WIN32) // There are no /proc/maps on Windows.
14 # include "sanitizer_common/sanitizer_procmaps.h"
21 # include "gtest/gtest.h"
24 extern const char *argv0
;
26 namespace __sanitizer
{
28 # if SANITIZER_LINUX && !SANITIZER_ANDROID
29 TEST(MemoryMappingLayout
, CodeRange
) {
31 bool res
= GetCodeRangeForFile("[vdso]", &start
, &end
);
34 EXPECT_LT(start
, end
);
38 TEST(MemoryMappingLayout
, DumpListOfModules
) {
39 const char *last_slash
= strrchr(argv0
, '/');
40 const char *binary_name
= last_slash
? last_slash
+ 1 : argv0
;
41 MemoryMappingLayout
memory_mapping(false);
42 const uptr kMaxModules
= 100;
43 InternalMmapVector
<LoadedModule
> modules
;
44 modules
.reserve(kMaxModules
);
45 memory_mapping
.DumpListOfModules(&modules
);
46 EXPECT_GT(modules
.size(), 0U);
48 for (uptr i
= 0; i
< modules
.size(); ++i
) {
49 if (modules
[i
].containsAddress((uptr
)&noop
)) {
50 // Verify that the module name is sane.
51 if (strstr(modules
[i
].full_name(), binary_name
) != 0)
59 TEST(MemoryMapping
, LoadedModuleArchAndUUID
) {
60 if (SANITIZER_APPLE
) {
61 MemoryMappingLayout
memory_mapping(false);
62 const uptr kMaxModules
= 100;
63 InternalMmapVector
<LoadedModule
> modules
;
64 modules
.reserve(kMaxModules
);
65 memory_mapping
.DumpListOfModules(&modules
);
66 for (uptr i
= 0; i
< modules
.size(); ++i
) {
67 ModuleArch arch
= modules
[i
].arch();
68 // Darwin unit tests are only run on i386/x86_64/x86_64h/arm64.
69 if (SANITIZER_WORDSIZE
== 32) {
70 EXPECT_EQ(arch
, kModuleArchI386
);
71 } else if (SANITIZER_WORDSIZE
== 64) {
72 EXPECT_TRUE(arch
== kModuleArchX86_64
|| arch
== kModuleArchX86_64H
||
73 arch
== kModuleArchARM64
);
75 const u8
*uuid
= modules
[i
].uuid();
76 u8 null_uuid
[kModuleUUIDSize
] = {0};
77 EXPECT_NE(memcmp(null_uuid
, uuid
, kModuleUUIDSize
), 0);
82 # if (SANITIZER_LINUX || SANITIZER_NETBSD || SANITIZER_SOLARIS) && \
84 const char *const parse_unix_input
= R
"(
85 7fb9862f1000-7fb9862f3000 rw-p 00000000 00:00 0
88 7fb9864ae000-7fb9864b1000 r--p 001ba000 fd:01 22413919 /lib/x86_64-linux-gnu/libc-2.32.so
93 TEST(MemoryMapping
, ParseUnixMemoryProfile
) {
99 typedef std::vector
<entry
> entries_t
;
101 std::vector
<char> input(parse_unix_input
,
102 parse_unix_input
+ strlen(parse_unix_input
));
103 ParseUnixMemoryProfile(
104 [](uptr p
, uptr rss
, bool file
, uptr
*mem
) {
105 reinterpret_cast<entries_t
*>(mem
)->push_back({p
, rss
, file
});
107 reinterpret_cast<uptr
*>(&entries
), &input
[0], input
.size());
108 EXPECT_EQ(entries
.size(), 2ul);
109 EXPECT_EQ(entries
[0].p
, 0x7fb9862f1000ul
);
110 EXPECT_EQ(entries
[0].rss
, 4ul << 10);
111 EXPECT_EQ(entries
[0].file
, false);
112 EXPECT_EQ(entries
[1].p
, 0x7fb9864ae000ul
);
113 EXPECT_EQ(entries
[1].rss
, 12ul << 10);
114 EXPECT_EQ(entries
[1].file
, true);
117 TEST(MemoryMapping
, ParseUnixMemoryProfileTruncated
) {
118 // ParseUnixMemoryProfile used to crash on truncated inputs.
119 // This test allocates 2 pages, protects the second one
120 // and places the input at the very end of the first page
121 // to test for over-reads.
122 uptr page
= GetPageSizeCached();
123 char *mem
= static_cast<char *>(
124 MmapOrDie(2 * page
, "ParseUnixMemoryProfileTruncated"));
125 EXPECT_TRUE(MprotectNoAccess(reinterpret_cast<uptr
>(mem
+ page
), page
));
126 const uptr len
= strlen(parse_unix_input
);
127 for (uptr i
= 0; i
< len
; i
++) {
128 char *smaps
= mem
+ page
- len
+ i
;
129 memcpy(smaps
, parse_unix_input
, len
- i
);
130 ParseUnixMemoryProfile([](uptr p
, uptr rss
, bool file
, uptr
*mem
) {},
131 nullptr, smaps
, len
- i
);
133 UnmapOrDie(mem
, 2 * page
);
137 } // namespace __sanitizer
138 #endif // !defined(_WIN32)