Mark Wielaard 1c9a0bf58a PR217695 malloc/calloc/realloc/memalign failure doesn't set errno to ENOMEM
When one of the allocation functions in vg_replace_malloc failed
they return NULL, but didn't set errno. This is slightly tricky since
errno is implementation defined and might be a macro. In the case of
glibc ernno is defined as:

  extern int *__errno_location (void) __THROW __attribute__ ((__const__));
  #define errno (*__errno_location ())

We can use the same trick as we use for __libc_freeres in
coregrind/vg_preloaded.c. Define the function as "weak". This means
it will only be defined if another library (glibc in this case)
actually provides a definition. Otherwise it will be NULL.
So we will only call it if it is defined and one of the allocation
functions failed, returned NULL.

Include a new linux only memcheck testcase, enomem.vgtest.

https://bugs.kde.org/show_bug.cgi?id=217695
2021-02-17 13:14:41 +01:00

35 lines
712 B
C

/* Test malloc, calloc, realloc and memalign set errno to ENOMEM */
#include <errno.h>
#include <limits.h>
#include <malloc.h>
#include <stdio.h>
#include <stdlib.h>
int main ( void )
{
char* small = malloc (16);
char* p;
errno = 0;
p = malloc(SSIZE_MAX);
if (!p && errno == ENOMEM) puts("malloc: Cannot allocate memory");
errno = 0;
p = calloc(1, SSIZE_MAX);
if (!p && errno == ENOMEM) puts("calloc: Cannot allocate memory");
errno = 0;
p = realloc(small, SSIZE_MAX);
if (!p && errno == ENOMEM) puts("realloc: Cannot allocate memory");
errno = 0;
p = memalign(64, SSIZE_MAX);
if (!p && errno == ENOMEM) puts("memalign: Cannot allocate memory");
free(small);
return 0;
}