Skip to content

Commit 2e0dbb5

Browse files
committed
Report leak when context is released
1 parent 71d123c commit 2e0dbb5

File tree

3 files changed

+45
-16
lines changed

3 files changed

+45
-16
lines changed

source/loader/layers/sanitizer/asan_interceptor.cpp

Lines changed: 37 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,8 @@ ur_result_t enqueueMemSetShadow(ur_context_handle_t Context,
146146

147147
} // namespace
148148

149+
bool SanitizerInterceptor::AbnormalExit = false;
150+
149151
SanitizerInterceptor::SanitizerInterceptor(logger::Logger &logger)
150152
: logger(logger) {
151153
if (Options(logger).MaxQuarantineSizeMB) {
@@ -159,15 +161,7 @@ SanitizerInterceptor::~SanitizerInterceptor() {
159161
DestroyShadowMemoryOnCPU();
160162
DestroyShadowMemoryOnPVC();
161163

162-
std::shared_lock<ur_shared_mutex> Guard(m_AllocationMapMutex);
163-
bool HasLeak = false;
164-
for (const auto &[_, AI] : m_AllocationMap) {
165-
if (!AI->IsReleased) {
166-
HasLeak = true;
167-
ReportMemoryLeak(AI);
168-
}
169-
}
170-
if (HasLeak) {
164+
if (AbnormalExit) {
171165
exit(1);
172166
}
173167
}
@@ -887,6 +881,40 @@ SanitizerInterceptor::findAllocInfoByAddress(uptr Address) {
887881
return It;
888882
}
889883

884+
std::vector<AllocationIterator>
885+
SanitizerInterceptor::findAllocInfoByContext(ur_context_handle_t Context) {
886+
std::shared_lock<ur_shared_mutex> Guard(m_AllocationMapMutex);
887+
std::vector<AllocationIterator> AllocInfos;
888+
for (auto It = m_AllocationMap.begin(); It != m_AllocationMap.end(); It++) {
889+
const auto &[_, AI] = *It;
890+
if (AI->Context == Context) {
891+
AllocInfos.emplace_back(It);
892+
}
893+
}
894+
return AllocInfos;
895+
}
896+
897+
ContextInfo::~ContextInfo() {
898+
[[maybe_unused]] auto Result =
899+
getContext()->urDdiTable.Context.pfnRelease(Handle);
900+
assert(Result == UR_RESULT_SUCCESS);
901+
902+
bool HasLeak = false;
903+
std::vector<AllocationIterator> AllocInfos =
904+
getContext()->interceptor->findAllocInfoByContext(Handle);
905+
for (const auto &It : AllocInfos) {
906+
const auto &[_, AI] = *It;
907+
if (AI->IsReleased) {
908+
ReportMemoryLeak(AI);
909+
HasLeak = true;
910+
}
911+
}
912+
913+
if (HasLeak) {
914+
SanitizerInterceptor::AbnormalExit = true;
915+
}
916+
}
917+
890918
ur_result_t USMLaunchInfo::initialize() {
891919
UR_CALL(getContext()->urDdiTable.Context.pfnRetain(Context));
892920
UR_CALL(getContext()->urDdiTable.Device.pfnRetain(Device));

source/loader/layers/sanitizer/asan_interceptor.hpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -119,11 +119,7 @@ struct ContextInfo {
119119
assert(Result == UR_RESULT_SUCCESS);
120120
}
121121

122-
~ContextInfo() {
123-
[[maybe_unused]] auto Result =
124-
getContext()->urDdiTable.Context.pfnRelease(Handle);
125-
assert(Result == UR_RESULT_SUCCESS);
126-
}
122+
~ContextInfo();
127123

128124
void insertAllocInfo(const std::vector<ur_device_handle_t> &Devices,
129125
std::shared_ptr<AllocInfo> &AI) {
@@ -169,6 +165,8 @@ struct DeviceGlobalInfo {
169165

170166
class SanitizerInterceptor {
171167
public:
168+
static bool AbnormalExit;
169+
172170
explicit SanitizerInterceptor(logger::Logger &logger);
173171

174172
~SanitizerInterceptor();
@@ -208,6 +206,9 @@ class SanitizerInterceptor {
208206

209207
std::optional<AllocationIterator> findAllocInfoByAddress(uptr Address);
210208

209+
std::vector<AllocationIterator>
210+
findAllocInfoByContext(ur_context_handle_t Context);
211+
211212
std::shared_ptr<ContextInfo> getContextInfo(ur_context_handle_t Context) {
212213
std::shared_lock<ur_shared_mutex> Guard(m_ContextMapMutex);
213214
assert(m_ContextMap.find(Context) != m_ContextMap.end());

source/loader/layers/sanitizer/asan_report.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,10 +77,10 @@ void ReportDoubleFree(uptr Addr, const StackTrace &Stack,
7777
}
7878

7979
void ReportMemoryLeak(const std::shared_ptr<AllocInfo> &AI) {
80-
context.logger.always(
80+
getContext()->logger.always(
8181
"\n====ERROR: DeviceSanitizer: detected memory leaks of {}",
8282
ToString(AI->Type));
83-
context.logger.always("Direct leak of {} byte(s) at {} allocated from:",
83+
getContext()->logger.always("Direct leak of {} byte(s) at {} allocated from:",
8484
AI->UserEnd - AI->UserBegin, (void *)AI->UserBegin);
8585
AI->AllocStack.print();
8686
}

0 commit comments

Comments
 (0)