@@ -32,6 +32,7 @@ static void InitializeFlags() {
32
32
f->report_blocks = false ;
33
33
f->resolution = 0 ;
34
34
f->max_leaks = 0 ;
35
+ f->exitcode = 23 ;
35
36
f->log_pointers = false ;
36
37
f->log_threads = false ;
37
38
@@ -47,6 +48,7 @@ static void InitializeFlags() {
47
48
CHECK_GE (&f->max_leaks , 0 );
48
49
ParseFlag (options, &f->log_pointers , " log_pointers" );
49
50
ParseFlag (options, &f->log_threads , " log_threads" );
51
+ ParseFlag (options, &f->exitcode , " exitcode" );
50
52
}
51
53
}
52
54
@@ -269,28 +271,42 @@ static void PrintLeaked() {
269
271
ForEachChunk (PrintLeakedCb ());
270
272
}
271
273
274
+ enum LeakCheckResult {
275
+ kFatalError ,
276
+ kLeaksFound ,
277
+ kNoLeaks
278
+ };
279
+
272
280
static void DoLeakCheckCallback (const SuspendedThreadsList &suspended_threads,
273
281
void *arg) {
282
+ LeakCheckResult *result = reinterpret_cast <LeakCheckResult *>(arg);
283
+ CHECK_EQ (*result, kFatalError );
274
284
// Allocator must not be locked when we call GetRegionBegin().
275
285
UnlockAllocator ();
276
- bool *success = reinterpret_cast <bool *>(arg);
277
286
ClassifyAllChunks (suspended_threads);
278
287
LeakReport leak_report;
279
288
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 ;
284
292
}
293
+ leak_report.PrintLargest (flags ()->max_leaks );
294
+ if (flags ()->report_blocks )
295
+ PrintLeaked ();
285
296
ForEachChunk (ClearTagCb ());
286
- *success = true ;
297
+ *result = kLeaksFound ;
287
298
}
288
299
289
300
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
+ }
294
310
}
295
311
296
312
// /// Reporting of leaked blocks' addresses (for testing). /////
0 commit comments