summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorQi Wang <interwq@gwu.edu>2019-07-16 21:35:53 (GMT)
committerQi Wang <interwq@gmail.com>2019-07-18 07:43:23 (GMT)
commitf32f23d6cc3ac9e663983ae62371acd47405c886 (patch)
tree5ce2fa13d76e8a742c0991e5acf31e9a47a8f180
parenta2a693e722d3ec0f0fb7dfcac54e775b1837efda (diff)
downloadjemalloc-f32f23d6cc3ac9e663983ae62371acd47405c886.zip
jemalloc-f32f23d6cc3ac9e663983ae62371acd47405c886.tar.gz
jemalloc-f32f23d6cc3ac9e663983ae62371acd47405c886.tar.bz2
Fix posix_memalign with input size 0.
Return a valid pointer instead of failed assertion.
-rw-r--r--src/jemalloc.c22
-rw-r--r--test/integration/posix_memalign.c5
2 files changed, 20 insertions, 7 deletions
diff --git a/src/jemalloc.c b/src/jemalloc.c
index 1e99a59..b6c8d99 100644
--- a/src/jemalloc.c
+++ b/src/jemalloc.c
@@ -1817,6 +1817,11 @@ struct static_opts_s {
bool may_overflow;
/*
+ * Whether or not allocations (with alignment) of size 0 should be
+ * treated as size 1.
+ */
+ bool bump_empty_aligned_alloc;
+ /*
* Whether to assert that allocations are not of size 0 (after any
* bumping).
*/
@@ -1857,6 +1862,7 @@ struct static_opts_s {
JEMALLOC_ALWAYS_INLINE void
static_opts_init(static_opts_t *static_opts) {
static_opts->may_overflow = false;
+ static_opts->bump_empty_aligned_alloc = false;
static_opts->assert_nonempty_alloc = false;
static_opts->null_out_result_on_error = false;
static_opts->set_errno_on_error = false;
@@ -2044,11 +2050,6 @@ imalloc_body(static_opts_t *sopts, dynamic_opts_t *dopts, tsd_t *tsd) {
goto label_oom;
}
- /* Validate the user input. */
- if (sopts->assert_nonempty_alloc) {
- assert (size != 0);
- }
-
if (unlikely(dopts->alignment < sopts->min_alignment
|| (dopts->alignment & (dopts->alignment - 1)) != 0)) {
goto label_invalid_alignment;
@@ -2068,6 +2069,11 @@ imalloc_body(static_opts_t *sopts, dynamic_opts_t *dopts, tsd_t *tsd) {
<= SC_LARGE_MAXCLASS);
}
} else {
+ if (sopts->bump_empty_aligned_alloc) {
+ if (unlikely(size == 0)) {
+ size = 1;
+ }
+ }
usize = sz_sa2u(size, dopts->alignment);
dopts->usize = usize;
if (unlikely(usize == 0
@@ -2075,6 +2081,10 @@ imalloc_body(static_opts_t *sopts, dynamic_opts_t *dopts, tsd_t *tsd) {
goto label_oom;
}
}
+ /* Validate the user input. */
+ if (sopts->assert_nonempty_alloc) {
+ assert (size != 0);
+ }
check_entry_exit_locking(tsd_tsdn(tsd));
@@ -2390,6 +2400,7 @@ je_posix_memalign(void **memptr, size_t alignment, size_t size) {
static_opts_init(&sopts);
dynamic_opts_init(&dopts);
+ sopts.bump_empty_aligned_alloc = true;
sopts.min_alignment = sizeof(void *);
sopts.oom_string =
"<jemalloc>: Error allocating aligned memory: out of memory\n";
@@ -2430,6 +2441,7 @@ je_aligned_alloc(size_t alignment, size_t size) {
static_opts_init(&sopts);
dynamic_opts_init(&dopts);
+ sopts.bump_empty_aligned_alloc = true;
sopts.null_out_result_on_error = true;
sopts.set_errno_on_error = true;
sopts.min_alignment = 1;
diff --git a/test/integration/posix_memalign.c b/test/integration/posix_memalign.c
index 2c2726d..d992260 100644
--- a/test/integration/posix_memalign.c
+++ b/test/integration/posix_memalign.c
@@ -85,9 +85,10 @@ TEST_BEGIN(test_alignment_and_size) {
alignment <= MAXALIGN;
alignment <<= 1) {
total = 0;
- for (size = 1;
+ for (size = 0;
size < 3 * alignment && size < (1U << 31);
- size += (alignment >> (LG_SIZEOF_PTR-1)) - 1) {
+ size += ((size == 0) ? 1 :
+ (alignment >> (LG_SIZEOF_PTR-1)) - 1)) {
for (i = 0; i < NITER; i++) {
err = posix_memalign(&ps[i],
alignment, size);