Skip to content

Commit

Permalink
Another tweak to avoid false positives with leak analyzer
Browse files Browse the repository at this point in the history
  • Loading branch information
rfm committed Jan 8, 2025
1 parent dfd1526 commit 7e66968
Showing 1 changed file with 40 additions and 4 deletions.
44 changes: 40 additions & 4 deletions Source/GSArray.m
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,23 @@
static SEL oaiSel;

static Class GSArrayClass;

/* Normally for immutable arrays we can use an array class where the buffer
* memory is allocated as part of the instance in a single allocation rather
* than being allocated separately (so each instance needs two allocations).
* However, this confuses the leak sanitizer, so if we are using that we
* need to disable the use of inline arrays to avoid false positives.
*/
#if !GNUSTEP_WITH_ASAN
static Class GSInlineArrayClass;
/* For runtime detection of LSAN, we use a weak symbol for one of its
* library functions. Then, if lsanCheck is not zero we try to change
* behavior to avoid false positives.
*/
int __lsan_do_recoverable_leak_check(void) __attribute__((weak));
static int (*lsanCheck)(void) = __lsan_do_recoverable_leak_check;
#endif

/* This class stores objects inline in data beyond the end of the instance.
*/
@interface GSInlineArray : GSArray
Expand Down Expand Up @@ -495,7 +509,14 @@ - (id) copyWithZone: (NSZone*)zone
#if GNUSTEP_WITH_ASAN
copy = (GSArray*)NSAllocateObject(GSArrayClass, 0, zone);
#else
copy = (id)NSAllocateObject(GSInlineArrayClass, _count*sizeof(id), zone);
if (lsanCheck)
{
copy = (GSArray*)NSAllocateObject(GSArrayClass, 0, zone);
}
else
{
copy = (id)NSAllocateObject(GSInlineArrayClass, _count*sizeof(id), zone);
}
#endif
return [copy initWithObjects: _contents_array count: _count];
}
Expand Down Expand Up @@ -1202,8 +1223,16 @@ - (id) initWithCoder: (NSCoder*)aCoder
a = (id)NSAllocateObject(GSArrayClass, 0, [self zone]);
a->_contents_array = (id*)NSZoneMalloc([self zone], c*sizeof(id));
#else
a = (id)NSAllocateObject(GSInlineArrayClass, c*sizeof(id), [self zone]);
a->_contents_array = (id*)(((void*)a) + class_getInstanceSize([a class]));
if (lsanCheck)

This comment has been minimized.

Copy link
@triplef

triplef Jan 9, 2025

Member

Since this check will only be true during testing, would it make sense to wrap it into unlikely() to aid with branch prediction?

This comment has been minimized.

Copy link
@rfm

rfm via email Jan 9, 2025

Author Contributor
{
a = (id)NSAllocateObject(GSArrayClass, 0, [self zone]);
a->_contents_array = (id*)NSZoneMalloc([self zone], c*sizeof(id));
}
else
{
a = (id)NSAllocateObject(GSInlineArrayClass, c*sizeof(id), [self zone]);
a->_contents_array = (id*)(((void*)a) + class_getInstanceSize([a class]));
}
#endif
if (c > 0)
{
Expand All @@ -1223,7 +1252,14 @@ - (id) initWithObjects: (const id[])objects count: (NSUInteger)count
#if GNUSTEP_WITH_ASAN
self = (id)NSAllocateObject(GSArrayClass, 0, z);
#else
self = (id)NSAllocateObject(GSInlineArrayClass, count*sizeof(id), z);
if (lsanCheck)
{
self = (id)NSAllocateObject(GSArrayClass, 0, z);
}
else
{
self = (id)NSAllocateObject(GSInlineArrayClass, count*sizeof(id), z);
}
#endif
return [self initWithObjects: objects count: count];
}
Expand Down

0 comments on commit 7e66968

Please sign in to comment.