Skip to content

Commit e226873

Browse files
committed
[ASAN] fix recursive initialization of sanitizer context
The AsanOptions class, a singleton, was being instantiated inside of the sanitizer context constructor, but, inside of its contructor, it was using the logger from inside of the context. This only worked before because the context variable was a global and the logger just so happened to be initialized prior to the AsanOptions. Now that the layer contexts are not globals, this was causing a deadlock on trying to retrieve a context while it was being initialized. The fix is to pass the logger manually to the AsanOptions class. A better fix might be to refactor AsanOptions to no longer be a static, but I was trying to minimize changes since this is blocking intel/llvm update.
1 parent a7920ef commit e226873

File tree

5 files changed

+24
-20
lines changed

5 files changed

+24
-20
lines changed

source/loader/layers/sanitizer/asan_interceptor.cpp

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -146,10 +146,12 @@ ur_result_t enqueueMemSetShadow(ur_context_handle_t Context,
146146

147147
} // namespace
148148

149-
SanitizerInterceptor::SanitizerInterceptor() {
150-
if (Options().MaxQuarantineSizeMB) {
149+
SanitizerInterceptor::SanitizerInterceptor(logger::Logger &logger)
150+
: logger(logger) {
151+
if (Options(logger).MaxQuarantineSizeMB) {
151152
m_Quarantine = std::make_unique<Quarantine>(
152-
static_cast<uint64_t>(Options().MaxQuarantineSizeMB) * 1024 * 1024);
153+
static_cast<uint64_t>(Options(logger).MaxQuarantineSizeMB) * 1024 *
154+
1024);
153155
}
154156
}
155157

@@ -189,7 +191,8 @@ ur_result_t SanitizerInterceptor::allocateMemory(
189191
Alignment = MinAlignment;
190192
}
191193

192-
uptr RZLog = ComputeRZLog(Size, Options().MinRZSize, Options().MaxRZSize);
194+
uptr RZLog = ComputeRZLog(Size, Options(logger).MinRZSize,
195+
Options(logger).MaxRZSize);
193196
uptr RZSize = RZLog2Size(RZLog);
194197
uptr RoundedSize = RoundUpTo(Size, Alignment);
195198
uptr NeededSize = RoundedSize + RZSize * 2;
@@ -706,7 +709,7 @@ ur_result_t SanitizerInterceptor::prepareLaunch(
706709

707710
// Write debug
708711
// We use "uint64_t" here because EnqueueWriteGlobal will fail when it's "uint32_t"
709-
uint64_t Debug = Options().Debug ? 1 : 0;
712+
uint64_t Debug = Options(logger).Debug ? 1 : 0;
710713
EnqueueWriteGlobal(kSPIR_AsanDebug, &Debug, sizeof(Debug));
711714

712715
// Write shadow memory offset for global memory
@@ -779,7 +782,7 @@ ur_result_t SanitizerInterceptor::prepareLaunch(
779782
LocalMemoryUsage, PrivateMemoryUsage);
780783

781784
// Write shadow memory offset for local memory
782-
if (Options().DetectLocals) {
785+
if (Options(logger).DetectLocals) {
783786
// CPU needn't this
784787
if (DeviceInfo->Type == DeviceType::GPU_PVC) {
785788
const size_t LocalMemorySize =
@@ -818,7 +821,7 @@ ur_result_t SanitizerInterceptor::prepareLaunch(
818821
}
819822

820823
// Write shadow memory offset for private memory
821-
if (Options().DetectPrivates) {
824+
if (Options(logger).DetectPrivates) {
822825
if (DeviceInfo->Type == DeviceType::CPU) {
823826
LaunchInfo.Data->PrivateShadowOffset = DeviceInfo->ShadowOffset;
824827
} else if (DeviceInfo->Type == DeviceType::GPU_PVC) {

source/loader/layers/sanitizer/asan_interceptor.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ struct DeviceGlobalInfo {
164164

165165
class SanitizerInterceptor {
166166
public:
167-
explicit SanitizerInterceptor();
167+
explicit SanitizerInterceptor(logger::Logger &logger);
168168

169169
~SanitizerInterceptor();
170170

@@ -261,6 +261,7 @@ class SanitizerInterceptor {
261261
ur_shared_mutex m_AllocationMapMutex;
262262

263263
std::unique_ptr<Quarantine> m_Quarantine;
264+
logger::Logger &logger;
264265
};
265266

266267
} // namespace ur_sanitizer_layer

source/loader/layers/sanitizer/asan_options.hpp

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ struct AsanOptions {
2727
AsanOptions(AsanOptions &other) = delete;
2828
void operator=(const AsanOptions &) = delete;
2929

30-
static AsanOptions &getInstance() {
31-
static AsanOptions instance;
30+
static AsanOptions &getInstance(logger::Logger &logger) {
31+
static AsanOptions instance(logger);
3232
return instance;
3333
}
3434

@@ -40,7 +40,7 @@ struct AsanOptions {
4040
bool DetectPrivates = true;
4141

4242
private:
43-
AsanOptions() {
43+
AsanOptions(logger::Logger &logger) {
4444
auto OptionsEnvMap = getenv_to_map("UR_LAYER_ASAN_OPTIONS");
4545
if (!OptionsEnvMap.has_value()) {
4646
return;
@@ -117,9 +117,8 @@ struct AsanOptions {
117117
MinRZSize = std::stoul(Value);
118118
if (MinRZSize < 16) {
119119
MinRZSize = 16;
120-
getContext()->logger.warning(
121-
"Trying to set redzone size to a "
122-
"value less than 16 is ignored");
120+
logger.warning("Trying to set redzone size to a "
121+
"value less than 16 is ignored");
123122
}
124123
} catch (...) {
125124
die("<SANITIZER>[ERROR]: \"redzone\" should be an integer");
@@ -133,9 +132,8 @@ struct AsanOptions {
133132
MaxRZSize = std::stoul(Value);
134133
if (MaxRZSize > 2048) {
135134
MaxRZSize = 2048;
136-
getContext()->logger.warning(
137-
"Trying to set max redzone size to a "
138-
"value greater than 2048 is ignored");
135+
logger.warning("Trying to set max redzone size to a "
136+
"value greater than 2048 is ignored");
139137
}
140138
} catch (...) {
141139
die("<SANITIZER>[ERROR]: \"max_redzone\" should be an integer");
@@ -144,6 +142,8 @@ struct AsanOptions {
144142
}
145143
};
146144

147-
inline const AsanOptions &Options() { return AsanOptions::getInstance(); }
145+
inline const AsanOptions &Options(logger::Logger &logger) {
146+
return AsanOptions::getInstance(logger);
147+
}
148148

149149
} // namespace ur_sanitizer_layer

source/loader/layers/sanitizer/asan_report.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ void ReportUseAfterFree(const DeviceSanitizerReport &Report,
124124
getContext()->logger.always(" #0 {} {}:{}", Func, File, Report.Line);
125125
getContext()->logger.always("");
126126

127-
if (Options().MaxQuarantineSizeMB > 0) {
127+
if (Options(getContext()->logger).MaxQuarantineSizeMB > 0) {
128128
auto AllocInfoItOp =
129129
getContext()->interceptor->findAllocInfoByAddress(Report.Address);
130130

source/loader/layers/sanitizer/ur_sanitizer_layer.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ context_t *getContext() { return context_t::get_direct(); }
2020
context_t::context_t()
2121
: logger(logger::create_logger("sanitizer", false, false,
2222
logger::Level::WARN)),
23-
interceptor(std::make_unique<SanitizerInterceptor>()) {}
23+
interceptor(std::make_unique<SanitizerInterceptor>(logger)) {}
2424

2525
ur_result_t context_t::tearDown() { return UR_RESULT_SUCCESS; }
2626

0 commit comments

Comments
 (0)