Skip to content
This repository was archived by the owner on May 21, 2019. It is now read-only.

Commit 969b529

Browse files
committed
[lsan] Add exitcode flag. Kill the process if leaks are found.
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@182641 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 46efcb0 commit 969b529

File tree

2 files changed

+28
-10
lines changed

2 files changed

+28
-10
lines changed

lib/lsan/lsan_common.cc

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ static void InitializeFlags() {
3232
f->report_blocks = false;
3333
f->resolution = 0;
3434
f->max_leaks = 0;
35+
f->exitcode = 23;
3536
f->log_pointers = false;
3637
f->log_threads = false;
3738

@@ -47,6 +48,7 @@ static void InitializeFlags() {
4748
CHECK_GE(&f->max_leaks, 0);
4849
ParseFlag(options, &f->log_pointers, "log_pointers");
4950
ParseFlag(options, &f->log_threads, "log_threads");
51+
ParseFlag(options, &f->exitcode, "exitcode");
5052
}
5153
}
5254

@@ -269,28 +271,42 @@ static void PrintLeaked() {
269271
ForEachChunk(PrintLeakedCb());
270272
}
271273

274+
enum LeakCheckResult {
275+
kFatalError,
276+
kLeaksFound,
277+
kNoLeaks
278+
};
279+
272280
static void DoLeakCheckCallback(const SuspendedThreadsList &suspended_threads,
273281
void *arg) {
282+
LeakCheckResult *result = reinterpret_cast<LeakCheckResult *>(arg);
283+
CHECK_EQ(*result, kFatalError);
274284
// Allocator must not be locked when we call GetRegionBegin().
275285
UnlockAllocator();
276-
bool *success = reinterpret_cast<bool *>(arg);
277286
ClassifyAllChunks(suspended_threads);
278287
LeakReport leak_report;
279288
CollectLeaks(&leak_report);
280-
if (!leak_report.IsEmpty()) {
281-
leak_report.PrintLargest(flags()->max_leaks);
282-
if (flags()->report_blocks)
283-
PrintLeaked();
289+
if (leak_report.IsEmpty()) {
290+
*result = kNoLeaks;
291+
return;
284292
}
293+
leak_report.PrintLargest(flags()->max_leaks);
294+
if (flags()->report_blocks)
295+
PrintLeaked();
285296
ForEachChunk(ClearTagCb());
286-
*success = true;
297+
*result = kLeaksFound;
287298
}
288299

289300
void DoLeakCheck() {
290-
bool success = false;
291-
LockAndSuspendThreads(DoLeakCheckCallback, &success);
292-
if (!success)
293-
Report("Leak check failed!\n");
301+
LeakCheckResult result = kFatalError;
302+
LockAndSuspendThreads(DoLeakCheckCallback, &result);
303+
if (result == kFatalError) {
304+
Report("LeakSanitizer has encountered a fatal error.\n");
305+
Die();
306+
} else if (result == kLeaksFound) {
307+
if (flags()->exitcode)
308+
internal__exit(flags()->exitcode);
309+
}
294310
}
295311

296312
///// Reporting of leaked blocks' addresses (for testing). /////

lib/lsan/lsan_common.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,8 @@ struct Flags {
6868
int resolution;
6969
// The number of leaks reported.
7070
int max_leaks;
71+
// If nonzero kill the process with this exit code upon finding leaks.
72+
int exitcode;
7173

7274
// Debug logging.
7375
bool log_pointers;

0 commit comments

Comments
 (0)