[PATCH] Make zero size allocation result consistent
Sebastian Huber
sebastian.huber at embedded-brains.de
Mon May 3 07:21:32 UTC 2021
The zero size allocations had no consistent behaviour in RTEMS. For
example, malloc( 0 ) returned NULL and posix_memalign( &p, align, 0 )
retruned in p a unique pointer (or NULL if no memory is available). In
POSIX, zero size memory allocations are implementation-defined
behaviour. The implementation has two options:
https://pubs.opengroup.org/onlinepubs/9699919799/functions/malloc.html
https://pubs.opengroup.org/onlinepubs/9699919799/functions/posix_memalign.html
Linux and FreeBSD return a unique pointer for zero size memory
allocations. Use this approch for RTEMS as well throughout the memory
allocation directives
Close #4390.
---
cpukit/libcsupport/src/malloc.c | 6 --
cpukit/libcsupport/src/malloc_deferred.c | 4 -
cpukit/libcsupport/src/realloc.c | 8 +-
testsuites/libtests/malloctest/init.c | 106 ++++++++++++++++++++---
4 files changed, 100 insertions(+), 24 deletions(-)
diff --git a/cpukit/libcsupport/src/malloc.c b/cpukit/libcsupport/src/malloc.c
index e61128bf8c..795254fbab 100644
--- a/cpukit/libcsupport/src/malloc.c
+++ b/cpukit/libcsupport/src/malloc.c
@@ -30,12 +30,6 @@ void *malloc(
{
void *return_this;
- /*
- * Validate the parameters
- */
- if ( !size )
- return (void *) 0;
-
return_this = rtems_heap_allocate_aligned_with_boundary( size, 0, 0 );
if ( !return_this ) {
errno = ENOMEM;
diff --git a/cpukit/libcsupport/src/malloc_deferred.c b/cpukit/libcsupport/src/malloc_deferred.c
index b319d1213e..aab76406c7 100644
--- a/cpukit/libcsupport/src/malloc_deferred.c
+++ b/cpukit/libcsupport/src/malloc_deferred.c
@@ -106,10 +106,6 @@ void *rtems_heap_allocate_aligned_with_boundary(
void *rtems_malloc( size_t size )
{
- if ( size == 0 ) {
- return NULL;
- }
-
return rtems_heap_allocate_aligned_with_boundary( size, 0, 0 );
}
#endif
diff --git a/cpukit/libcsupport/src/realloc.c b/cpukit/libcsupport/src/realloc.c
index 1d9ae45c5d..e28e3fbc33 100644
--- a/cpukit/libcsupport/src/realloc.c
+++ b/cpukit/libcsupport/src/realloc.c
@@ -53,15 +53,15 @@ void *realloc( void *ptr, size_t size )
uintptr_t old_size;
uintptr_t avail_size;
+ if ( ptr == NULL ) {
+ return malloc( size );
+ }
+
if ( size == 0 ) {
free( ptr );
return NULL;
}
- if ( ptr == NULL ) {
- return malloc( size );
- }
-
heap = RTEMS_Malloc_Heap;
switch ( _Malloc_System_state() ) {
diff --git a/testsuites/libtests/malloctest/init.c b/testsuites/libtests/malloctest/init.c
index 4d0f421c02..c9dcb63b2c 100644
--- a/testsuites/libtests/malloctest/init.c
+++ b/testsuites/libtests/malloctest/init.c
@@ -1153,7 +1153,10 @@ static void test_rtems_malloc(void)
void *p;
p = rtems_malloc(0);
- rtems_test_assert(p == NULL);
+ rtems_test_assert(p != NULL);
+
+ RTEMS_OBFUSCATE_VARIABLE(p);
+ free(p);
errno = 0;
p = rtems_malloc(SIZE_MAX / 2);
@@ -1163,6 +1166,7 @@ static void test_rtems_malloc(void)
p = rtems_malloc(1);
rtems_test_assert(p != NULL);
+ RTEMS_OBFUSCATE_VARIABLE(p);
free(p);
}
@@ -1172,13 +1176,22 @@ static void test_rtems_calloc(void)
int *i;
p = rtems_calloc(0, 0);
- rtems_test_assert(p == NULL);
+ rtems_test_assert(p != NULL);
+
+ RTEMS_OBFUSCATE_VARIABLE(p);
+ free(p);
p = rtems_calloc(0, 1);
- rtems_test_assert(p == NULL);
+ rtems_test_assert(p != NULL);
+
+ RTEMS_OBFUSCATE_VARIABLE(p);
+ free(p);
p = rtems_calloc(1, 0);
- rtems_test_assert(p == NULL);
+ rtems_test_assert(p != NULL);
+
+ RTEMS_OBFUSCATE_VARIABLE(p);
+ free(p);
errno = 0;
p = rtems_calloc(1, SIZE_MAX / 2);
@@ -1202,6 +1215,8 @@ static void test_rtems_calloc(void)
rtems_test_assert(i != NULL);
rtems_test_assert(*i == 0);
+
+ RTEMS_OBFUSCATE_VARIABLE(p);
free(i);
}
@@ -1301,6 +1316,82 @@ static void test_greedy_allocate(void)
rtems_test_assert( p == NULL );
}
+static void test_alloc_zero_size(void)
+{
+ size_t size;
+ void *p;
+ int eno;
+
+ size = 0;
+
+ RTEMS_OBFUSCATE_VARIABLE( size );
+ p = malloc( size );
+ rtems_test_assert( p != NULL );
+
+ RTEMS_OBFUSCATE_VARIABLE( p );
+ free( p );
+
+ RTEMS_OBFUSCATE_VARIABLE( size );
+ p = calloc( 1, size );
+ rtems_test_assert( p != NULL );
+
+ RTEMS_OBFUSCATE_VARIABLE( p );
+ free( p );
+
+ RTEMS_OBFUSCATE_VARIABLE( size );
+ p = rtems_malloc( size );
+ rtems_test_assert( p != NULL );
+
+ RTEMS_OBFUSCATE_VARIABLE( p );
+ free( p );
+
+ RTEMS_OBFUSCATE_VARIABLE( size );
+ p = rtems_calloc( 1, size );
+ rtems_test_assert( p != NULL );
+
+ RTEMS_OBFUSCATE_VARIABLE( p );
+ free( p );
+
+ RTEMS_OBFUSCATE_VARIABLE( size );
+ p = NULL;
+ eno = posix_memalign( &p, 32, size );
+ rtems_test_assert( eno == 0 );
+ rtems_test_assert( p != NULL );
+
+ RTEMS_OBFUSCATE_VARIABLE( p );
+ free( p );
+
+ RTEMS_OBFUSCATE_VARIABLE( size );
+ p = NULL;
+ eno = rtems_memalign( &p, 32, size );
+ rtems_test_assert( eno == 0 );
+ rtems_test_assert( p != NULL );
+
+ RTEMS_OBFUSCATE_VARIABLE( p );
+ free( p );
+
+ RTEMS_OBFUSCATE_VARIABLE( size );
+ p = aligned_alloc( 32, size );
+ rtems_test_assert( p != NULL );
+
+ RTEMS_OBFUSCATE_VARIABLE( p );
+ free( p );
+
+ RTEMS_OBFUSCATE_VARIABLE( size );
+ p = realloc( NULL, size );
+ rtems_test_assert( p != NULL );
+
+ RTEMS_OBFUSCATE_VARIABLE( p );
+ free( p );
+
+ RTEMS_OBFUSCATE_VARIABLE( size );
+ p = reallocarray( NULL, 1, size );
+ rtems_test_assert( p != NULL );
+
+ RTEMS_OBFUSCATE_VARIABLE( p );
+ free( p );
+}
+
rtems_task Init(
rtems_task_argument argument
)
@@ -1327,12 +1418,6 @@ rtems_task Init(
rtems_test_assert( p1 == NULL );
#pragma GCC diagnostic pop
- /*
- * Verify error case where malloc of size 0.
- */
- p1 = malloc( 0 );
- rtems_test_assert( p1 == NULL );
-
test_heap_initialize();
test_heap_block_allocate();
test_heap_allocate();
@@ -1351,6 +1436,7 @@ rtems_task Init(
test_rtems_malloc();
test_rtems_calloc();
test_greedy_allocate();
+ test_alloc_zero_size();
test_posix_memalign();
--
2.26.2
More information about the devel
mailing list