forked from OSchip/llvm-project
[ASan] Print global registration site in init-order-checker reports.
llvm-svn: 235540
This commit is contained in:
parent
e74ec45b88
commit
9e463ba35d
|
@ -91,9 +91,19 @@ static void ReportGlobal(const Global &g, const char *prefix) {
|
|||
}
|
||||
}
|
||||
|
||||
// Returns the number of globals close to the provided address and copies
|
||||
// them to "globals" array.
|
||||
int GetGlobalsForAddress(uptr addr, Global *globals, int max_globals) {
|
||||
static u32 FindRegistrationSite(const Global *g) {
|
||||
mu_for_globals.CheckLocked();
|
||||
CHECK(global_registration_site_vector);
|
||||
for (uptr i = 0, n = global_registration_site_vector->size(); i < n; i++) {
|
||||
GlobalRegistrationSite &grs = (*global_registration_site_vector)[i];
|
||||
if (g >= grs.g_first && g <= grs.g_last)
|
||||
return grs.stack_id;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int GetGlobalsForAddress(uptr addr, Global *globals, u32 *reg_sites,
|
||||
int max_globals) {
|
||||
if (!flags()->report_globals) return 0;
|
||||
BlockingMutexLock lock(&mu_for_globals);
|
||||
int res = 0;
|
||||
|
@ -102,7 +112,10 @@ int GetGlobalsForAddress(uptr addr, Global *globals, int max_globals) {
|
|||
if (flags()->report_globals >= 2)
|
||||
ReportGlobal(g, "Search");
|
||||
if (IsAddressNearGlobal(addr, g)) {
|
||||
globals[res++] = g;
|
||||
globals[res] = g;
|
||||
if (reg_sites)
|
||||
reg_sites[res] = FindRegistrationSite(&g);
|
||||
res++;
|
||||
if (res == max_globals) break;
|
||||
}
|
||||
}
|
||||
|
@ -111,7 +124,7 @@ int GetGlobalsForAddress(uptr addr, Global *globals, int max_globals) {
|
|||
|
||||
bool GetInfoForAddressIfGlobal(uptr addr, AddressDescription *descr) {
|
||||
Global g = {};
|
||||
if (GetGlobalsForAddress(addr, &g, 1)) {
|
||||
if (GetGlobalsForAddress(addr, &g, nullptr, 1)) {
|
||||
internal_strncpy(descr->name, g.name, descr->name_size);
|
||||
descr->region_address = g.beg;
|
||||
descr->region_size = g.size;
|
||||
|
@ -121,16 +134,6 @@ bool GetInfoForAddressIfGlobal(uptr addr, AddressDescription *descr) {
|
|||
return false;
|
||||
}
|
||||
|
||||
u32 FindRegistrationSite(const Global *g) {
|
||||
CHECK(global_registration_site_vector);
|
||||
for (uptr i = 0, n = global_registration_site_vector->size(); i < n; i++) {
|
||||
GlobalRegistrationSite &grs = (*global_registration_site_vector)[i];
|
||||
if (g >= grs.g_first && g <= grs.g_last)
|
||||
return grs.stack_id;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Register a global variable.
|
||||
// This function may be called more than once for every global
|
||||
// so we store the globals in a map.
|
||||
|
|
|
@ -307,15 +307,24 @@ static void DescribeAddressRelativeToGlobal(uptr addr, uptr size,
|
|||
Printf("%s", str.data());
|
||||
}
|
||||
|
||||
static bool DescribeAddressIfGlobal(uptr addr, uptr size) {
|
||||
static bool DescribeAddressIfGlobal(uptr addr, uptr size,
|
||||
const char *bug_type) {
|
||||
// Assume address is close to at most four globals.
|
||||
const int kMaxGlobalsInReport = 4;
|
||||
__asan_global globals[kMaxGlobalsInReport];
|
||||
int globals_num = GetGlobalsForAddress(addr, globals, ARRAY_SIZE(globals));
|
||||
u32 reg_sites[kMaxGlobalsInReport];
|
||||
int globals_num =
|
||||
GetGlobalsForAddress(addr, globals, reg_sites, ARRAY_SIZE(globals));
|
||||
if (globals_num == 0)
|
||||
return false;
|
||||
for (int i = 0; i < globals_num; i++)
|
||||
for (int i = 0; i < globals_num; i++) {
|
||||
DescribeAddressRelativeToGlobal(addr, size, globals[i]);
|
||||
if (0 == internal_strcmp(bug_type, "initialization-order-fiasco") &&
|
||||
reg_sites[i]) {
|
||||
Printf(" registered at:\n");
|
||||
StackDepotGet(reg_sites[i]).Print();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -561,12 +570,12 @@ void DescribeHeapAddress(uptr addr, uptr access_size) {
|
|||
DescribeThread(alloc_thread);
|
||||
}
|
||||
|
||||
void DescribeAddress(uptr addr, uptr access_size) {
|
||||
static void DescribeAddress(uptr addr, uptr access_size, const char *bug_type) {
|
||||
// Check if this is shadow or shadow gap.
|
||||
if (DescribeAddressIfShadow(addr))
|
||||
return;
|
||||
CHECK(AddrIsInMem(addr));
|
||||
if (DescribeAddressIfGlobal(addr, access_size))
|
||||
if (DescribeAddressIfGlobal(addr, access_size, bug_type))
|
||||
return;
|
||||
if (DescribeAddressIfStack(addr, access_size))
|
||||
return;
|
||||
|
@ -820,8 +829,8 @@ void ReportStringFunctionMemoryRangesOverlap(const char *function,
|
|||
bug_type, offset1, offset1 + length1, offset2, offset2 + length2);
|
||||
Printf("%s", d.EndWarning());
|
||||
stack->Print();
|
||||
DescribeAddress((uptr)offset1, length1);
|
||||
DescribeAddress((uptr)offset2, length2);
|
||||
DescribeAddress((uptr)offset1, length1, bug_type);
|
||||
DescribeAddress((uptr)offset2, length2, bug_type);
|
||||
ReportErrorSummary(bug_type, stack);
|
||||
}
|
||||
|
||||
|
@ -834,7 +843,7 @@ void ReportStringFunctionSizeOverflow(uptr offset, uptr size,
|
|||
Report("ERROR: AddressSanitizer: %s: (size=%zd)\n", bug_type, size);
|
||||
Printf("%s", d.EndWarning());
|
||||
stack->Print();
|
||||
DescribeAddress(offset, size);
|
||||
DescribeAddress(offset, size, bug_type);
|
||||
ReportErrorSummary(bug_type, stack);
|
||||
}
|
||||
|
||||
|
@ -889,15 +898,16 @@ void ReportODRViolation(const __asan_global *g1, u32 stack_id1,
|
|||
static NOINLINE void
|
||||
ReportInvalidPointerPair(uptr pc, uptr bp, uptr sp, uptr a1, uptr a2) {
|
||||
ScopedInErrorReport in_report;
|
||||
const char *bug_type = "invalid-pointer-pair";
|
||||
Decorator d;
|
||||
Printf("%s", d.Warning());
|
||||
Report("ERROR: AddressSanitizer: invalid-pointer-pair: %p %p\n", a1, a2);
|
||||
Printf("%s", d.EndWarning());
|
||||
GET_STACK_TRACE_FATAL(pc, bp);
|
||||
stack.Print();
|
||||
DescribeAddress(a1, 1);
|
||||
DescribeAddress(a2, 1);
|
||||
ReportErrorSummary("invalid-pointer-pair", &stack);
|
||||
DescribeAddress(a1, 1, bug_type);
|
||||
DescribeAddress(a2, 1, bug_type);
|
||||
ReportErrorSummary(bug_type, &stack);
|
||||
}
|
||||
|
||||
static INLINE void CheckForInvalidPointerPair(void *p1, void *p2) {
|
||||
|
@ -1044,7 +1054,7 @@ void __asan_report_error(uptr pc, uptr bp, uptr sp, uptr addr, int is_write,
|
|||
GET_STACK_TRACE_FATAL(pc, bp);
|
||||
stack.Print();
|
||||
|
||||
DescribeAddress(addr, access_size);
|
||||
DescribeAddress(addr, access_size, bug_descr);
|
||||
ReportErrorSummary(bug_descr, &stack);
|
||||
PrintShadowMemoryForAddress(addr);
|
||||
}
|
||||
|
@ -1062,7 +1072,7 @@ void NOINLINE __asan_set_error_report_callback(void (*callback)(const char*)) {
|
|||
void __asan_describe_address(uptr addr) {
|
||||
// Thread registry must be locked while we're describing an address.
|
||||
asanThreadRegistry().Lock();
|
||||
DescribeAddress(addr, 1);
|
||||
DescribeAddress(addr, 1, "");
|
||||
asanThreadRegistry().Unlock();
|
||||
}
|
||||
|
||||
|
|
|
@ -35,7 +35,8 @@ struct AddressDescription {
|
|||
|
||||
// Returns the number of globals close to the provided address and copies
|
||||
// them to "globals" array.
|
||||
int GetGlobalsForAddress(uptr addr, __asan_global *globals, int max_globals);
|
||||
int GetGlobalsForAddress(uptr addr, __asan_global *globals, u32 *reg_sites,
|
||||
int max_globals);
|
||||
bool GetInfoForAddressIfGlobal(uptr addr, AddressDescription *descr);
|
||||
// The following functions prints address description depending
|
||||
// on the memory type (shadow/heap/stack/global).
|
||||
|
@ -45,9 +46,6 @@ bool DescribeAddressIfShadow(uptr addr, AddressDescription *descr = nullptr,
|
|||
bool ParseFrameDescription(const char *frame_descr,
|
||||
InternalMmapVector<StackVarDescr> *vars);
|
||||
bool DescribeAddressIfStack(uptr addr, uptr access_size);
|
||||
// Determines memory type on its own.
|
||||
void DescribeAddress(uptr addr, uptr access_size);
|
||||
|
||||
void DescribeThread(AsanThreadContext *context);
|
||||
|
||||
// Different kinds of error reports.
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// Test to make sure basic initialization order errors are caught.
|
||||
|
||||
// RUN: %clangxx_asan -O0 %s %p/Helpers/initialization-bug-extra2.cc -o %t
|
||||
// RUN: env ASAN_OPTIONS=check_initialization_order=true not %run %t 2>&1 | FileCheck %s
|
||||
// RUN: %clangxx_asan -O0 %s %p/Helpers/initialization-bug-extra2.cc -o %t-INIT-ORDER-EXE
|
||||
// RUN: env ASAN_OPTIONS=check_initialization_order=true not %run %t-INIT-ORDER-EXE 2>&1 | FileCheck %s
|
||||
|
||||
// Do not test with optimization -- the error may be optimized away.
|
||||
|
||||
|
@ -32,6 +32,8 @@ int __attribute__((noinline)) initX() {
|
|||
// CHECK: {{AddressSanitizer: initialization-order-fiasco}}
|
||||
// CHECK: {{READ of size .* at 0x.* thread T0}}
|
||||
// CHECK: {{0x.* is located 0 bytes inside of global variable .*(y|z).*}}
|
||||
// CHECK: registered at:
|
||||
// CHECK: 0x{{.*}} in asan.module_ctor {{.*}}INIT-ORDER-EXE
|
||||
}
|
||||
|
||||
// This initializer begins our initialization order problems.
|
||||
|
|
Loading…
Reference in New Issue