Skip to content

Commit a9d790f

Browse files
committed
add improvement
1 parent 1e1f577 commit a9d790f

File tree

4 files changed

+111
-56
lines changed

4 files changed

+111
-56
lines changed

source/loader/layers/sanitizer/asan_interceptor.cpp

Lines changed: 13 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
*/
1313

1414
#include "asan_interceptor.hpp"
15+
#include "asan_options.hpp"
1516
#include "asan_quarantine.hpp"
1617
#include "asan_report.hpp"
1718
#include "asan_shadow_setup.hpp"
@@ -144,36 +145,9 @@ ur_result_t enqueueMemSetShadow(ur_context_handle_t Context,
144145
} // namespace
145146

146147
SanitizerInterceptor::SanitizerInterceptor() {
147-
auto Options = getenv_to_map("UR_LAYER_ASAN_OPTIONS");
148-
if (!Options.has_value()) {
149-
return;
150-
}
151-
152-
auto KV = Options->find("debug");
153-
if (KV != Options->end()) {
154-
auto Value = KV->second.front();
155-
cl_Debug = Value == "1" || Value == "true" ? 1 : 0;
156-
}
157-
158-
KV = Options->find("quarantine_size_mb");
159-
if (KV != Options->end()) {
160-
auto Value = KV->second.front();
161-
try {
162-
cl_MaxQuarantineSizeMB = std::stoul(Value);
163-
} catch (...) {
164-
die("<SANITIZER>[ERROR]: \"cl_MaxQuarantineSizeMB\" should be an "
165-
"integer");
166-
}
167-
}
168-
if (cl_MaxQuarantineSizeMB) {
169-
m_Quarantine =
170-
std::make_unique<Quarantine>(cl_MaxQuarantineSizeMB * 1024 * 1024);
171-
}
172-
173-
KV = Options->find("detect_locals");
174-
if (KV != Options->end()) {
175-
auto Value = KV->second.front();
176-
cl_DetectLocals = Value == "1" || Value == "true" ? true : false;
148+
if (Options().MaxQuarantineSizeMB) {
149+
m_Quarantine = std::make_unique<Quarantine>(
150+
Options().MaxQuarantineSizeMB * 1024 * 1024);
177151
}
178152
}
179153

@@ -651,7 +625,8 @@ ur_result_t SanitizerInterceptor::prepareLaunch(
651625
};
652626

653627
// Write debug
654-
EnqueueWriteGlobal(kSPIR_AsanDebug, &cl_Debug, sizeof(cl_Debug));
628+
EnqueueWriteGlobal(kSPIR_AsanDebug, &(Options().Debug),
629+
sizeof(Options().Debug));
655630

656631
// Write shadow memory offset for global memory
657632
EnqueueWriteGlobal(kSPIR_AsanShadowMemoryGlobalStart,
@@ -711,7 +686,7 @@ ur_result_t SanitizerInterceptor::prepareLaunch(
711686
};
712687

713688
// Write shadow memory offset for local memory
714-
if (cl_DetectLocals) {
689+
if (Options().DetectLocals) {
715690
// CPU needn't this
716691
if (DeviceInfo->Type == DeviceType::GPU_PVC) {
717692
size_t LocalMemorySize = GetLocalMemorySize(DeviceInfo->Handle);
@@ -746,7 +721,12 @@ SanitizerInterceptor::findAllocInfoByAddress(uptr Address) {
746721
if (It == m_AllocationMap.begin()) {
747722
return std::optional<AllocationIterator>{};
748723
}
749-
return --It;
724+
--It;
725+
auto &AI = It->second;
726+
// Make sure we got the right AllocInfo
727+
assert(Address >= AI->AllocBegin &&
728+
Address < AI->AllocBegin + AI->AllocSize);
729+
return It;
750730
}
751731

752732
LaunchInfo::~LaunchInfo() {

source/loader/layers/sanitizer/asan_interceptor.hpp

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -219,11 +219,6 @@ class SanitizerInterceptor {
219219
AllocationMap m_AllocationMap;
220220
ur_shared_mutex m_AllocationMapMutex;
221221

222-
// We use "uint64_t" here because EnqueueWriteGlobal will fail when it's "uint32_t"
223-
uint64_t cl_Debug = 0;
224-
uint32_t cl_MaxQuarantineSizeMB = 0;
225-
bool cl_DetectLocals = true;
226-
227222
std::unique_ptr<Quarantine> m_Quarantine;
228223
};
229224

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/*
2+
*
3+
* Copyright (C) 2024 Intel Corporation
4+
*
5+
* Part of the Unified-Runtime Project, under the Apache License v2.0 with LLVM Exceptions.
6+
* See LICENSE.TXT
7+
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
8+
*
9+
* @file asan_options.hpp
10+
*
11+
*/
12+
13+
#pragma once
14+
15+
#include "common/ur_util.hpp"
16+
#include "ur/ur.hpp"
17+
18+
#include <cstdint>
19+
20+
namespace ur_sanitizer_layer {
21+
22+
struct AsanOptions {
23+
public:
24+
AsanOptions(AsanOptions &other) = delete;
25+
void operator=(const AsanOptions &) = delete;
26+
27+
static AsanOptions &getInstance() {
28+
static AsanOptions instance;
29+
return instance;
30+
}
31+
32+
// We use "uint64_t" here because EnqueueWriteGlobal will fail when it's "uint32_t"
33+
uint64_t Debug = 0;
34+
uint32_t MaxQuarantineSizeMB = 0;
35+
bool DetectLocals = true;
36+
37+
private:
38+
AsanOptions() {
39+
auto OptionsEnvMap = getenv_to_map("UR_LAYER_ASAN_OPTIONS");
40+
if (!OptionsEnvMap.has_value()) {
41+
return;
42+
}
43+
44+
auto KV = OptionsEnvMap->find("debug");
45+
if (KV != OptionsEnvMap->end()) {
46+
auto Value = KV->second.front();
47+
Debug = Value == "1" || Value == "true" ? 1 : 0;
48+
}
49+
50+
KV = OptionsEnvMap->find("quarantine_size_mb");
51+
if (KV != OptionsEnvMap->end()) {
52+
auto Value = KV->second.front();
53+
try {
54+
MaxQuarantineSizeMB = std::stoul(Value);
55+
} catch (...) {
56+
die("<SANITIZER>[ERROR]: \"quarantine_size_mb\" should be "
57+
"an positive integer");
58+
}
59+
}
60+
61+
KV = OptionsEnvMap->find("detect_locals");
62+
if (KV != OptionsEnvMap->end()) {
63+
auto Value = KV->second.front();
64+
DetectLocals = Value == "1" || Value == "true" ? true : false;
65+
}
66+
}
67+
};
68+
69+
inline AsanOptions &Options() { return AsanOptions::getInstance(); }
70+
71+
} // namespace ur_sanitizer_layer

source/loader/layers/sanitizer/asan_report.cpp

Lines changed: 27 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
*/
1212

1313
#include "asan_report.hpp"
14+
#include "asan_options.hpp"
1415

1516
#include "asan_allocator.hpp"
1617
#include "asan_interceptor.hpp"
@@ -131,27 +132,35 @@ void ReportUseAfterFree(const DeviceSanitizerReport &Report,
131132
context.logger.always(" #0 {} {}:{}", Func, File, Report.Line);
132133
context.logger.always("");
133134

134-
auto AllocInfoItOp =
135-
context.interceptor->findAllocInfoByAddress(Report.Address);
136-
if (!AllocInfoItOp) {
137-
context.logger.always("Failed to find which chunck {} is allocated",
138-
(void *)Report.Address);
139-
} else {
140-
auto &AllocInfo = (*AllocInfoItOp)->second;
141-
if (AllocInfo->Context != Context) {
135+
if (Options().MaxQuarantineSizeMB > 0) {
136+
auto AllocInfoItOp =
137+
context.interceptor->findAllocInfoByAddress(Report.Address);
138+
139+
if (!AllocInfoItOp) {
142140
context.logger.always("Failed to find which chunck {} is allocated",
143141
(void *)Report.Address);
142+
} else {
143+
auto &AllocInfo = (*AllocInfoItOp)->second;
144+
if (AllocInfo->Context != Context) {
145+
context.logger.always(
146+
"Failed to find which chunck {} is allocated",
147+
(void *)Report.Address);
148+
}
149+
assert(AllocInfo->IsReleased);
150+
151+
context.logger.always(
152+
"{} is located inside of {} region [{}, {})",
153+
(void *)Report.Address, ToString(AllocInfo->Type),
154+
(void *)AllocInfo->UserBegin, (void *)AllocInfo->UserEnd);
155+
context.logger.always("allocated here:");
156+
AllocInfo->AllocStack.print();
157+
context.logger.always("released here:");
158+
AllocInfo->ReleaseStack.print();
144159
}
145-
assert(AllocInfo->IsReleased);
146-
147-
context.logger.always("{} is located inside of {} region [{}, {})",
148-
(void *)Report.Address, ToString(AllocInfo->Type),
149-
(void *)AllocInfo->UserBegin,
150-
(void *)AllocInfo->UserEnd);
151-
context.logger.always("allocated here:");
152-
AllocInfo->AllocStack.print();
153-
context.logger.always("released here:");
154-
AllocInfo->ReleaseStack.print();
160+
} else {
161+
context.logger.always(
162+
"Please enable quarantine to get more information like memory "
163+
"chunck's kind and where the chunck was allocated and released.");
155164
}
156165

157166
exit(1);

0 commit comments

Comments
 (0)