Use Get/SetLastError on Win32

Using errno on win32 doesn't quite work, because the value set in a shared
library can't be read from e.g. an executable calling the function setting
errno.

At the same time, since buferror always uses errno/GetLastError, don't pass
it.
This commit is contained in:
Mike Hommey 2012-04-30 12:38:26 +02:00 committed by Jason Evans
parent af04b744bd
commit a14bce85e8
7 changed files with 71 additions and 33 deletions

View File

@ -1,8 +1,17 @@
#ifndef JEMALLOC_INTERNAL_H #ifndef JEMALLOC_INTERNAL_H
#define JEMALLOC_INTERNAL_H #define JEMALLOC_INTERNAL_H
#include <sys/param.h> #include <sys/param.h>
#include <math.h>
#ifdef _WIN32 #ifdef _WIN32
# include <windows.h> # include <windows.h>
# define ENOENT ERROR_PATH_NOT_FOUND
# define EINVAL ERROR_BAD_ARGUMENTS
# define EAGAIN ERROR_OUTOFMEMORY
# define EPERM ERROR_WRITE_FAULT
# define EFAULT ERROR_INVALID_ADDRESS
# define ENOMEM ERROR_NOT_ENOUGH_MEMORY
# undef ERANGE
# define ERANGE ERROR_INVALID_DATA
#else #else
# include <sys/mman.h> # include <sys/mman.h>
# include <sys/syscall.h> # include <sys/syscall.h>
@ -11,10 +20,10 @@
# endif # endif
# include <sys/uio.h> # include <sys/uio.h>
# include <pthread.h> # include <pthread.h>
# include <errno.h>
#endif #endif
#include <sys/types.h> #include <sys/types.h>
#include <errno.h>
#include <limits.h> #include <limits.h>
#ifndef SIZE_T_MAX #ifndef SIZE_T_MAX
# define SIZE_T_MAX SIZE_MAX # define SIZE_T_MAX SIZE_MAX
@ -34,7 +43,6 @@
#include <ctype.h> #include <ctype.h>
#include <unistd.h> #include <unistd.h>
#include <fcntl.h> #include <fcntl.h>
#include <math.h>
#define JEMALLOC_NO_DEMANGLE #define JEMALLOC_NO_DEMANGLE
#include "../jemalloc@install_suffix@.h" #include "../jemalloc@install_suffix@.h"

View File

@ -84,7 +84,7 @@
extern void (*je_malloc_message)(void *wcbopaque, const char *s); extern void (*je_malloc_message)(void *wcbopaque, const char *s);
int buferror(int errnum, char *buf, size_t buflen); int buferror(char *buf, size_t buflen);
uintmax_t malloc_strtoumax(const char *nptr, char **endptr, int base); uintmax_t malloc_strtoumax(const char *nptr, char **endptr, int base);
/* /*
@ -109,6 +109,8 @@ void malloc_printf(const char *format, ...)
#ifndef JEMALLOC_ENABLE_INLINE #ifndef JEMALLOC_ENABLE_INLINE
size_t pow2_ceil(size_t x); size_t pow2_ceil(size_t x);
void malloc_write(const char *s); void malloc_write(const char *s);
void set_errno(int errnum);
int get_errno(void);
#endif #endif
#if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_UTIL_C_)) #if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_UTIL_C_))
@ -140,6 +142,30 @@ malloc_write(const char *s)
je_malloc_message(NULL, s); je_malloc_message(NULL, s);
} }
/* Sets error code */
JEMALLOC_INLINE void
set_errno(int errnum)
{
#ifdef _WIN32
SetLastError(errnum);
#else
errno = errnum;
#endif
}
/* Get last error code */
JEMALLOC_INLINE int
get_errno(void)
{
#ifdef _WIN32
return GetLastError();
#else
return errno;
#endif
}
#endif #endif
#endif /* JEMALLOC_H_INLINES */ #endif /* JEMALLOC_H_INLINES */

View File

@ -41,7 +41,7 @@ pages_map(void *addr, size_t size)
if (munmap(ret, size) == -1) { if (munmap(ret, size) == -1) {
char buf[BUFERROR_BUF]; char buf[BUFERROR_BUF];
buferror(errno, buf, sizeof(buf)); buferror(buf, sizeof(buf));
malloc_printf("<jemalloc: Error in munmap(): %s\n", malloc_printf("<jemalloc: Error in munmap(): %s\n",
buf); buf);
if (opt_abort) if (opt_abort)
@ -67,7 +67,7 @@ pages_unmap(void *addr, size_t size)
{ {
char buf[BUFERROR_BUF]; char buf[BUFERROR_BUF];
buferror(errno, buf, sizeof(buf)); buferror(buf, sizeof(buf));
malloc_printf("<jemalloc>: Error in " malloc_printf("<jemalloc>: Error in "
#ifdef _WIN32 #ifdef _WIN32
"VirtualFree" "VirtualFree"

View File

@ -168,7 +168,7 @@ huge_ralloc(void *ptr, size_t oldsize, size_t size, size_t extra,
*/ */
char buf[BUFERROR_BUF]; char buf[BUFERROR_BUF];
buferror(errno, buf, sizeof(buf)); buferror(buf, sizeof(buf));
malloc_printf("<jemalloc>: Error in mremap(): %s\n", malloc_printf("<jemalloc>: Error in mremap(): %s\n",
buf); buf);
if (opt_abort) if (opt_abort)

View File

@ -472,9 +472,9 @@ malloc_conf_init(void)
uintmax_t um; \ uintmax_t um; \
char *end; \ char *end; \
\ \
errno = 0; \ set_errno(0); \
um = malloc_strtoumax(v, &end, 0); \ um = malloc_strtoumax(v, &end, 0); \
if (errno != 0 || (uintptr_t)end - \ if (get_errno() != 0 || (uintptr_t)end -\
(uintptr_t)v != vlen) { \ (uintptr_t)v != vlen) { \
malloc_conf_error( \ malloc_conf_error( \
"Invalid conf value", \ "Invalid conf value", \
@ -493,9 +493,9 @@ malloc_conf_init(void)
long l; \ long l; \
char *end; \ char *end; \
\ \
errno = 0; \ set_errno(0); \
l = strtol(v, &end, 0); \ l = strtol(v, &end, 0); \
if (errno != 0 || (uintptr_t)end - \ if (get_errno() != 0 || (uintptr_t)end -\
(uintptr_t)v != vlen) { \ (uintptr_t)v != vlen) { \
malloc_conf_error( \ malloc_conf_error( \
"Invalid conf value", \ "Invalid conf value", \
@ -831,7 +831,7 @@ label_oom:
"out of memory\n"); "out of memory\n");
abort(); abort();
} }
errno = ENOMEM; set_errno(ENOMEM);
} }
if (config_prof && opt_prof && ret != NULL) if (config_prof && opt_prof && ret != NULL)
prof_malloc(ret, usize, cnt); prof_malloc(ret, usize, cnt);
@ -959,7 +959,7 @@ je_aligned_alloc(size_t alignment, size_t size)
if ((err = imemalign(&ret, alignment, size, 1)) != 0) { if ((err = imemalign(&ret, alignment, size, 1)) != 0) {
ret = NULL; ret = NULL;
errno = err; set_errno(err);
} }
JEMALLOC_VALGRIND_MALLOC(err == 0, ret, isalloc(ret, config_prof), JEMALLOC_VALGRIND_MALLOC(err == 0, ret, isalloc(ret, config_prof),
false); false);
@ -1029,7 +1029,7 @@ label_return:
"memory\n"); "memory\n");
abort(); abort();
} }
errno = ENOMEM; set_errno(ENOMEM);
} }
if (config_prof && opt_prof && ret != NULL) if (config_prof && opt_prof && ret != NULL)
@ -1130,7 +1130,7 @@ label_oom:
"out of memory\n"); "out of memory\n");
abort(); abort();
} }
errno = ENOMEM; set_errno(ENOMEM);
} }
} else { } else {
/* realloc(NULL, size) is equivalent to malloc(size). */ /* realloc(NULL, size) is equivalent to malloc(size). */
@ -1172,7 +1172,7 @@ label_oom:
"out of memory\n"); "out of memory\n");
abort(); abort();
} }
errno = ENOMEM; set_errno(ENOMEM);
} }
} }

View File

@ -65,7 +65,7 @@ void (*je_malloc_message)(void *, const char *s)
* provide a wrapper. * provide a wrapper.
*/ */
int int
buferror(int errnum, char *buf, size_t buflen) buferror(char *buf, size_t buflen)
{ {
#ifdef _WIN32 #ifdef _WIN32
@ -93,7 +93,7 @@ malloc_strtoumax(const char *nptr, char **endptr, int base)
const char *p, *ns; const char *p, *ns;
if (base < 0 || base == 1 || base > 36) { if (base < 0 || base == 1 || base > 36) {
errno = EINVAL; set_errno(EINVAL);
return (UINTMAX_MAX); return (UINTMAX_MAX);
} }
b = base; b = base;
@ -168,7 +168,7 @@ malloc_strtoumax(const char *nptr, char **endptr, int base)
ret += digit; ret += digit;
if (ret < pret) { if (ret < pret) {
/* Overflow. */ /* Overflow. */
errno = ERANGE; set_errno(ERANGE);
return (UINTMAX_MAX); return (UINTMAX_MAX);
} }
p++; p++;
@ -416,9 +416,9 @@ malloc_vsnprintf(char *str, size_t size, const char *format, va_list ap)
case '0': case '1': case '2': case '3': case '4': case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9': { case '5': case '6': case '7': case '8': case '9': {
uintmax_t uwidth; uintmax_t uwidth;
errno = 0; set_errno(0);
uwidth = malloc_strtoumax(f, (char **)&f, 10); uwidth = malloc_strtoumax(f, (char **)&f, 10);
assert(uwidth != UINTMAX_MAX || errno != assert(uwidth != UINTMAX_MAX || get_errno() !=
ERANGE); ERANGE);
width = (int)uwidth; width = (int)uwidth;
if (*f == '.') { if (*f == '.') {
@ -442,9 +442,10 @@ malloc_vsnprintf(char *str, size_t size, const char *format, va_list ap)
case '0': case '1': case '2': case '3': case '4': case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9': { case '5': case '6': case '7': case '8': case '9': {
uintmax_t uprec; uintmax_t uprec;
errno = 0; set_errno(0);
uprec = malloc_strtoumax(f, (char **)&f, 10); uprec = malloc_strtoumax(f, (char **)&f, 10);
assert(uprec != UINTMAX_MAX || errno != ERANGE); assert(uprec != UINTMAX_MAX || get_errno() !=
ERANGE);
prec = (int)uprec; prec = (int)uprec;
break; break;
} }

View File

@ -17,18 +17,18 @@ main(void)
/* Test error conditions. */ /* Test error conditions. */
alignment = 0; alignment = 0;
errno = 0; set_errno(0);
p = aligned_alloc(alignment, 1); p = aligned_alloc(alignment, 1);
if (p != NULL || errno != EINVAL) { if (p != NULL || get_errno() != EINVAL) {
malloc_printf( malloc_printf(
"Expected error for invalid alignment %zu\n", alignment); "Expected error for invalid alignment %zu\n", alignment);
} }
for (alignment = sizeof(size_t); alignment < MAXALIGN; for (alignment = sizeof(size_t); alignment < MAXALIGN;
alignment <<= 1) { alignment <<= 1) {
errno = 0; set_errno(0);
p = aligned_alloc(alignment + 1, 1); p = aligned_alloc(alignment + 1, 1);
if (p != NULL || errno != EINVAL) { if (p != NULL || get_errno() != EINVAL) {
malloc_printf( malloc_printf(
"Expected error for invalid alignment %zu\n", "Expected error for invalid alignment %zu\n",
alignment + 1); alignment + 1);
@ -42,9 +42,9 @@ main(void)
alignment = 0x80000000LU; alignment = 0x80000000LU;
size = 0x80000000LU; size = 0x80000000LU;
#endif #endif
errno = 0; set_errno(0);
p = aligned_alloc(alignment, size); p = aligned_alloc(alignment, size);
if (p != NULL || errno != ENOMEM) { if (p != NULL || get_errno() != ENOMEM) {
malloc_printf( malloc_printf(
"Expected error for aligned_alloc(%zu, %zu)\n", "Expected error for aligned_alloc(%zu, %zu)\n",
alignment, size); alignment, size);
@ -57,9 +57,9 @@ main(void)
alignment = 0x40000000LU; alignment = 0x40000000LU;
size = 0x84000001LU; size = 0x84000001LU;
#endif #endif
errno = 0; set_errno(0);
p = aligned_alloc(alignment, size); p = aligned_alloc(alignment, size);
if (p != NULL || errno != ENOMEM) { if (p != NULL || get_errno() != ENOMEM) {
malloc_printf( malloc_printf(
"Expected error for aligned_alloc(%zu, %zu)\n", "Expected error for aligned_alloc(%zu, %zu)\n",
alignment, size); alignment, size);
@ -71,9 +71,9 @@ main(void)
#else #else
size = 0xfffffff0LU; size = 0xfffffff0LU;
#endif #endif
errno = 0; set_errno(0);
p = aligned_alloc(alignment, size); p = aligned_alloc(alignment, size);
if (p != NULL || errno != ENOMEM) { if (p != NULL || get_errno() != ENOMEM) {
malloc_printf( malloc_printf(
"Expected error for aligned_alloc(&p, %zu, %zu)\n", "Expected error for aligned_alloc(&p, %zu, %zu)\n",
alignment, size); alignment, size);
@ -93,9 +93,12 @@ main(void)
for (i = 0; i < NITER; i++) { for (i = 0; i < NITER; i++) {
ps[i] = aligned_alloc(alignment, size); ps[i] = aligned_alloc(alignment, size);
if (ps[i] == NULL) { if (ps[i] == NULL) {
char buf[BUFERROR_BUF];
buferror(buf, sizeof(buf));
malloc_printf( malloc_printf(
"Error for size %zu (%#zx): %s\n", "Error for size %zu (%#zx): %s\n",
size, size, strerror(errno)); size, size, buf);
exit(1); exit(1);
} }
total += malloc_usable_size(ps[i]); total += malloc_usable_size(ps[i]);