[PATCH] Make zero size allocation result consistent

Gedare Bloom gedare at rtems.org
Tue May 4 06:49:51 UTC 2021


ok. This could break applications in strange ways if they depended on
the old behavior. A clear note will be needed in release.

On Mon, May 3, 2021 at 1:21 AM Sebastian Huber
<sebastian.huber at embedded-brains.de> wrote:
>
> 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
>
> _______________________________________________
> devel mailing list
> devel at rtems.org
> http://lists.rtems.org/mailman/listinfo/devel


More information about the devel mailing list