Skip to content

Commit 11b9ec5

Browse files
committed
[sanitizer] Add more internal symbolizer tests
And merge them with demangle_internal.cpp.
1 parent 71f9e76 commit 11b9ec5

File tree

2 files changed

+142
-22
lines changed

2 files changed

+142
-22
lines changed
Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
// RUN: %clangxx %s -o %t && %run %t
2+
3+
// REQUIRES: internal_symbolizer
4+
5+
#include <assert.h>
6+
#include <dlfcn.h>
7+
#include <link.h>
8+
#include <sanitizer/msan_interface.h>
9+
#include <string.h>
10+
11+
#include <string>
12+
#include <vector>
13+
14+
extern "C" {
15+
bool __sanitizer_symbolize_code(const char *ModuleName, uint64_t ModuleOffset,
16+
char *Buffer, int MaxLength,
17+
bool SymbolizeInlineFrames);
18+
bool __sanitizer_symbolize_data(const char *ModuleName, uint64_t ModuleOffset,
19+
char *Buffer, int MaxLength);
20+
void __sanitizer_print_stack_trace();
21+
bool __sanitizer_symbolize_demangle(const char *Name, char *Buffer,
22+
int MaxLength);
23+
}
24+
25+
struct ScopedInSymbolizer {
26+
#if defined(__has_feature)
27+
# if __has_feature(memory_sanitizer)
28+
ScopedInSymbolizer() { __msan_scoped_disable_interceptor_checks(); }
29+
~ScopedInSymbolizer() { __msan_scoped_enable_interceptor_checks(); }
30+
# endif
31+
#endif
32+
};
33+
34+
struct FrameInfo {
35+
int line;
36+
std::string file;
37+
std::string function;
38+
void *address;
39+
};
40+
41+
__attribute__((noinline)) void *GetPC() { return __builtin_return_address(0); }
42+
43+
__attribute__((always_inline)) FrameInfo InlineFunction() {
44+
void *address = GetPC();
45+
return {__LINE__ - 1, __FILE__, __FUNCTION__,
46+
reinterpret_cast<void *>(reinterpret_cast<uintptr_t>(address) - 1)};
47+
}
48+
49+
__attribute__((noinline)) FrameInfo NoInlineFunction() {
50+
void *address = GetPC();
51+
return {__LINE__ - 1, __FILE__, __FUNCTION__,
52+
reinterpret_cast<void *>(reinterpret_cast<uintptr_t>(address) - 1)};
53+
}
54+
55+
template <int N> struct A {
56+
template <class T> FrameInfo RecursiveTemplateFunction(const T &t);
57+
};
58+
59+
template <int N>
60+
template <class T>
61+
__attribute__((noinline)) FrameInfo A<N>::RecursiveTemplateFunction(const T &) {
62+
std::vector<T> t;
63+
return A<N - 1>().RecursiveTemplateFunction(t);
64+
}
65+
66+
template <>
67+
template <class T>
68+
__attribute__((noinline)) FrameInfo A<0>::RecursiveTemplateFunction(const T &) {
69+
return NoInlineFunction();
70+
}
71+
72+
__attribute__((no_sanitize_memory)) std::pair<const char *, uint64_t>
73+
GetModuleAndOffset(void *address) {
74+
Dl_info di;
75+
link_map *lm = nullptr;
76+
assert(
77+
dladdr1(address, &di, reinterpret_cast<void **>(&lm), RTLD_DL_LINKMAP));
78+
return {di.dli_fname, reinterpret_cast<uint64_t>(address) - lm->l_addr};
79+
}
80+
81+
std::string Symbolize(FrameInfo frame) {
82+
auto modul_offset = GetModuleAndOffset(frame.address);
83+
char buffer[1024] = {};
84+
ScopedInSymbolizer in_symbolizer;
85+
__sanitizer_symbolize_code(modul_offset.first, modul_offset.second, buffer,
86+
std::size(buffer), true);
87+
return buffer;
88+
}
89+
90+
std::string GetRegex(const FrameInfo &frame) {
91+
return frame.function + "[^\\n]*\\n[^\\n]*" + frame.file + ":" +
92+
std::to_string(frame.line);
93+
}
94+
95+
void TestInline() {
96+
auto frame = InlineFunction();
97+
fprintf(stderr, "%s: %s\n", __FUNCTION__, Symbolize(frame).c_str());
98+
}
99+
100+
void TestNoInline() {
101+
auto frame = NoInlineFunction();
102+
fprintf(stderr, "%s: %s\n", __FUNCTION__, Symbolize(frame).c_str());
103+
}
104+
105+
void TestLongFunctionNames() {
106+
auto frame = A<10>().RecursiveTemplateFunction(0);
107+
fprintf(stderr, "%s: %s\n", __FUNCTION__, Symbolize(frame).c_str());
108+
}
109+
110+
std::string SymbolizeStaticVar() {
111+
static int var = 1;
112+
auto modul_offset = GetModuleAndOffset(&var);
113+
char buffer[1024] = {};
114+
ScopedInSymbolizer in_symbolizer;
115+
__sanitizer_symbolize_data(modul_offset.first, modul_offset.second, buffer,
116+
std::size(buffer));
117+
return buffer;
118+
}
119+
120+
void TestData() {
121+
fprintf(stderr, "%s: %s\n", __FUNCTION__, SymbolizeStaticVar().c_str());
122+
}
123+
124+
void TestDemangle() {
125+
char out[128];
126+
assert(!__sanitizer_symbolize_demangle("1A", out, sizeof(out)));
127+
128+
const char name[] = "_Z3fooi";
129+
for (int i = 1; i < sizeof(out); ++i) {
130+
memset(out, 1, sizeof(out));
131+
assert(__sanitizer_symbolize_demangle(name, out, i) == (i > 8));
132+
assert(i < 9 || 0 == strncmp(out, "foo(int)", i - 1));
133+
}
134+
}
135+
136+
int main() {
137+
TestInline();
138+
TestNoInline();
139+
TestLongFunctionNames();
140+
TestData();
141+
TestDemangle();
142+
}

compiler-rt/test/sanitizer_common/TestCases/demangle_internal.cpp

Lines changed: 0 additions & 22 deletions
This file was deleted.

0 commit comments

Comments
 (0)