From 9e20df163c0c608026498b8fb5beab35e8a049c6 Mon Sep 17 00:00:00 2001 From: Jason Evans Date: Wed, 26 Feb 2014 10:19:18 -0800 Subject: Remove duplicate 'static' keyword. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reported by İsmail Dönmez. --- test/include/test/SFMT-alti.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/include/test/SFMT-alti.h b/test/include/test/SFMT-alti.h index 2f86f67..0005df6 100644 --- a/test/include/test/SFMT-alti.h +++ b/test/include/test/SFMT-alti.h @@ -61,7 +61,7 @@ * @return output */ JEMALLOC_ALWAYS_INLINE -static vector unsigned int vec_recursion(vector unsigned int a, +vector unsigned int vec_recursion(vector unsigned int a, vector unsigned int b, vector unsigned int c, vector unsigned int d) { -- cgit v0.12 From bf543df20ccd9e2c422751908cabf073bc7f5d4b Mon Sep 17 00:00:00 2001 From: Harald Weppner Date: Mon, 17 Mar 2014 23:53:00 -0700 Subject: Enable profiling / leak detection in FreeBSD * Assumes procfs is mounted at /proc, cf. --- bin/pprof | 22 ++++++++++++++++++++-- src/prof.c | 8 +++++++- 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/bin/pprof b/bin/pprof index 727eb43..08c9ea3 100755 --- a/bin/pprof +++ b/bin/pprof @@ -4197,8 +4197,12 @@ sub FindLibrary { # For libc libraries, the copy in /usr/lib/debug contains debugging symbols sub DebuggingLibrary { my $file = shift; - if ($file =~ m|^/| && -f "/usr/lib/debug$file") { - return "/usr/lib/debug$file"; + if ($file =~ m|^/|) { + if (-f "/usr/lib/debug$file") { + return "/usr/lib/debug$file"; + } elsif (-f "/usr/lib/debug$file.debug") { + return "/usr/lib/debug$file.debug"; + } } return undef; } @@ -4360,6 +4364,19 @@ sub ParseLibraries { $finish = HexExtend($2); $offset = $zero_offset; $lib = $3; + } + # FreeBSD 10.0 virtual memory map /proc/curproc/map as defined in + # function procfs_doprocmap (sys/fs/procfs/procfs_map.c) + # + # Example: + # 0x800600000 0x80061a000 26 0 0xfffff800035a0000 r-x 75 33 0x1004 COW NC vnode /libexec/ld-elf.s + # o.1 NCH -1 + elsif ($l =~ /^(0x$h)\s(0x$h)\s\d+\s\d+\s0x$h\sr-x\s\d+\s\d+\s0x\d+\s(COW|NCO)\s(NC|NNC)\svnode\s(\S+\.so(\.\d+)*)/) { + $start = HexExtend($1); + $finish = HexExtend($2); + $offset = $zero_offset; + $lib = FindLibrary($5); + } else { next; } @@ -4382,6 +4399,7 @@ sub ParseLibraries { } } + if($main::opt_debug) { printf STDERR "$start:$finish ($offset) $lib\n"; } push(@{$result}, [$lib, $start, $finish, $offset]); } diff --git a/src/prof.c b/src/prof.c index 1d8ccbd..ede89a7 100644 --- a/src/prof.c +++ b/src/prof.c @@ -11,6 +11,12 @@ #include #endif +#ifdef __FreeBSD__ +#define PROCESS_VMEM_MAP "/proc/curproc/map" +#else +#define PROCESS_VMEM_MAP "/proc/%d/maps" +#endif + /******************************************************************************/ /* Data. */ @@ -936,7 +942,7 @@ prof_dump_maps(bool propagate_err) cassert(config_prof); - malloc_snprintf(filename, sizeof(filename), "/proc/%d/maps", + malloc_snprintf(filename, sizeof(filename), PROCESS_VMEM_MAP, (int)getpid()); mfd = open(filename, O_RDONLY); if (mfd != -1) { -- cgit v0.12 From 4bbf8181f384d6bd8a634b22543f83e5b949b609 Mon Sep 17 00:00:00 2001 From: Harald Weppner Date: Tue, 18 Mar 2014 00:00:14 -0700 Subject: Consistently use debug lib(s) if present Fixes a situation where nm uses the debug lib but addr2line does not, which completely messes up the symbol lookup. --- bin/pprof | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/bin/pprof b/bin/pprof index 08c9ea3..a309943 100755 --- a/bin/pprof +++ b/bin/pprof @@ -4607,6 +4607,12 @@ sub ExtractSymbols { my $finish = $lib->[2]; my $offset = $lib->[3]; + # Use debug library if it exists + my $debug_libname = DebuggingLibrary($libname); + if ($debug_libname) { + $libname = $debug_libname; + } + # Get list of pcs that belong in this library. my $contained = []; my ($start_pc_index, $finish_pc_index); @@ -5037,7 +5043,7 @@ sub GetProcedureBoundariesViaNm { # Tag this routine with the starting address in case the image # has multiple occurrences of this routine. We use a syntax - # that resembles template paramters that are automatically + # that resembles template parameters that are automatically # stripped out by ShortFunctionName() $this_routine .= "<$start_val>"; -- cgit v0.12 From 20a8c78bfe3310e0f0f72b596d4e10ca7336063b Mon Sep 17 00:00:00 2001 From: Chris Pride Date: Tue, 25 Mar 2014 22:36:05 -0700 Subject: Fix a crashing case where arena_chunk_init_hard returns NULL. This happens when it fails to allocate a new chunk. Which arena_chunk_alloc then passes into arena_avail_insert without any checks. This then causes a crash when arena_avail_insert tries to check chunk->ndirty. This was introduced by the refactoring of arena_chunk_alloc which previously would have returned NULL immediately after calling chunk_alloc. This is now the return from arena_chunk_init_hard so we need to check that return, and not continue if it was NULL. --- src/arena.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/arena.c b/src/arena.c index 390ab0f..dad707b 100644 --- a/src/arena.c +++ b/src/arena.c @@ -614,8 +614,11 @@ arena_chunk_alloc(arena_t *arena) if (arena->spare != NULL) chunk = arena_chunk_init_spare(arena); - else + else { chunk = arena_chunk_init_hard(arena); + if (chunk == NULL) + return (NULL); + } /* Insert the run into the runs_avail tree. */ arena_avail_insert(arena, chunk, map_bias, chunk_npages-map_bias, -- cgit v0.12 From c2dcfd8ded8162cddb143836c12d003840fdeaeb Mon Sep 17 00:00:00 2001 From: Jason Evans Date: Fri, 28 Mar 2014 10:40:03 -0700 Subject: Convert ALLOCM_ARENA() test to MALLOCX_ARENA() test. --- Makefile.in | 2 +- test/integration/ALLOCM_ARENA.c | 58 ---------------------------------------- test/integration/MALLOCX_ARENA.c | 58 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 59 insertions(+), 59 deletions(-) delete mode 100644 test/integration/ALLOCM_ARENA.c create mode 100644 test/integration/MALLOCX_ARENA.c diff --git a/Makefile.in b/Makefile.in index 7399f27..d6b7d6e 100644 --- a/Makefile.in +++ b/Makefile.in @@ -141,7 +141,7 @@ TESTS_INTEGRATION := $(srcroot)test/integration/aligned_alloc.c \ $(srcroot)test/integration/xallocx.c ifeq ($(enable_experimental), 1) TESTS_INTEGRATION += $(srcroot)test/integration/allocm.c \ - $(srcroot)test/integration/ALLOCM_ARENA.c \ + $(srcroot)test/integration/MALLOCX_ARENA.c \ $(srcroot)test/integration/rallocm.c endif TESTS_STRESS := diff --git a/test/integration/ALLOCM_ARENA.c b/test/integration/ALLOCM_ARENA.c deleted file mode 100644 index 5bf3c4a..0000000 --- a/test/integration/ALLOCM_ARENA.c +++ /dev/null @@ -1,58 +0,0 @@ -#include "test/jemalloc_test.h" - -#define NTHREADS 10 - -void * -thd_start(void *arg) -{ - unsigned thread_ind = (unsigned)(uintptr_t)arg; - unsigned arena_ind; - void *p; - size_t rsz, sz; - - sz = sizeof(arena_ind); - assert_d_eq(mallctl("arenas.extend", &arena_ind, &sz, NULL, 0), 0, - "Error in arenas.extend"); - - if (thread_ind % 4 != 3) { - size_t mib[3]; - size_t miblen = sizeof(mib) / sizeof(size_t); - const char *dss_precs[] = {"disabled", "primary", "secondary"}; - const char *dss = dss_precs[thread_ind % - (sizeof(dss_precs)/sizeof(char*))]; - assert_d_eq(mallctlnametomib("arena.0.dss", mib, &miblen), 0, - "Error in mallctlnametomib()"); - mib[1] = arena_ind; - assert_d_eq(mallctlbymib(mib, miblen, NULL, NULL, (void *)&dss, - sizeof(const char *)), 0, "Error in mallctlbymib()"); - } - - assert_d_eq(allocm(&p, &rsz, 1, ALLOCM_ARENA(arena_ind)), - ALLOCM_SUCCESS, "Unexpected allocm() error"); - dallocm(p, 0); - - return (NULL); -} - -TEST_BEGIN(test_ALLOCM_ARENA) -{ - thd_t thds[NTHREADS]; - unsigned i; - - for (i = 0; i < NTHREADS; i++) { - thd_create(&thds[i], thd_start, - (void *)(uintptr_t)i); - } - - for (i = 0; i < NTHREADS; i++) - thd_join(thds[i], NULL); -} -TEST_END - -int -main(void) -{ - - return (test( - test_ALLOCM_ARENA)); -} diff --git a/test/integration/MALLOCX_ARENA.c b/test/integration/MALLOCX_ARENA.c new file mode 100644 index 0000000..71cf6f2 --- /dev/null +++ b/test/integration/MALLOCX_ARENA.c @@ -0,0 +1,58 @@ +#include "test/jemalloc_test.h" + +#define NTHREADS 10 + +void * +thd_start(void *arg) +{ + unsigned thread_ind = (unsigned)(uintptr_t)arg; + unsigned arena_ind; + void *p; + size_t sz; + + sz = sizeof(arena_ind); + assert_d_eq(mallctl("arenas.extend", &arena_ind, &sz, NULL, 0), 0, + "Error in arenas.extend"); + + if (thread_ind % 4 != 3) { + size_t mib[3]; + size_t miblen = sizeof(mib) / sizeof(size_t); + const char *dss_precs[] = {"disabled", "primary", "secondary"}; + const char *dss = dss_precs[thread_ind % + (sizeof(dss_precs)/sizeof(char*))]; + assert_d_eq(mallctlnametomib("arena.0.dss", mib, &miblen), 0, + "Error in mallctlnametomib()"); + mib[1] = arena_ind; + assert_d_eq(mallctlbymib(mib, miblen, NULL, NULL, (void *)&dss, + sizeof(const char *)), 0, "Error in mallctlbymib()"); + } + + p = mallocx(1, MALLOCX_ARENA(arena_ind)); + assert_ptr_not_null(p, "Unexpected mallocx() error"); + dallocx(p, 0); + + return (NULL); +} + +TEST_BEGIN(test_ALLOCM_ARENA) +{ + thd_t thds[NTHREADS]; + unsigned i; + + for (i = 0; i < NTHREADS; i++) { + thd_create(&thds[i], thd_start, + (void *)(uintptr_t)i); + } + + for (i = 0; i < NTHREADS; i++) + thd_join(thds[i], NULL); +} +TEST_END + +int +main(void) +{ + + return (test( + test_ALLOCM_ARENA)); +} -- cgit v0.12 From fbb31029a5c2f556f39e04a8781340d4ee4cf16c Mon Sep 17 00:00:00 2001 From: Max Wang Date: Thu, 27 Mar 2014 14:46:00 -0700 Subject: Use arena dss prec instead of default for huge allocs. Pass a dss_prec_t parameter to huge_{m,p,r}alloc instead of defaulting to the chunk dss prec. --- include/jemalloc/internal/huge.h | 8 +++++--- include/jemalloc/internal/jemalloc_internal.h.in | 10 ++++----- src/huge.c | 26 +++++++++++++++--------- src/jemalloc.c | 2 +- 4 files changed, 27 insertions(+), 19 deletions(-) diff --git a/include/jemalloc/internal/huge.h b/include/jemalloc/internal/huge.h index ddf1313..a2b9c77 100644 --- a/include/jemalloc/internal/huge.h +++ b/include/jemalloc/internal/huge.h @@ -17,18 +17,20 @@ extern size_t huge_allocated; /* Protects chunk-related data structures. */ extern malloc_mutex_t huge_mtx; -void *huge_malloc(size_t size, bool zero); -void *huge_palloc(size_t size, size_t alignment, bool zero); +void *huge_malloc(size_t size, bool zero, dss_prec_t dss_prec); +void *huge_palloc(size_t size, size_t alignment, bool zero, + dss_prec_t dss_prec); bool huge_ralloc_no_move(void *ptr, size_t oldsize, size_t size, size_t extra); void *huge_ralloc(void *ptr, size_t oldsize, size_t size, size_t extra, - size_t alignment, bool zero, bool try_tcache_dalloc); + size_t alignment, bool zero, bool try_tcache_dalloc, dss_prec_t dss_prec); #ifdef JEMALLOC_JET typedef void (huge_dalloc_junk_t)(void *, size_t); extern huge_dalloc_junk_t *huge_dalloc_junk; #endif void huge_dalloc(void *ptr, bool unmap); size_t huge_salloc(const void *ptr); +dss_prec_t huge_dss_prec_get(arena_t *arena); prof_ctx_t *huge_prof_ctx_get(const void *ptr); void huge_prof_ctx_set(const void *ptr, prof_ctx_t *ctx); bool huge_boot(void); diff --git a/include/jemalloc/internal/jemalloc_internal.h.in b/include/jemalloc/internal/jemalloc_internal.h.in index d24a1fe..574bbb1 100644 --- a/include/jemalloc/internal/jemalloc_internal.h.in +++ b/include/jemalloc/internal/jemalloc_internal.h.in @@ -770,7 +770,7 @@ imalloct(size_t size, bool try_tcache, arena_t *arena) if (size <= arena_maxclass) return (arena_malloc(arena, size, false, try_tcache)); else - return (huge_malloc(size, false)); + return (huge_malloc(size, false, huge_dss_prec_get(arena))); } JEMALLOC_ALWAYS_INLINE void * @@ -787,7 +787,7 @@ icalloct(size_t size, bool try_tcache, arena_t *arena) if (size <= arena_maxclass) return (arena_malloc(arena, size, true, try_tcache)); else - return (huge_malloc(size, true)); + return (huge_malloc(size, true, huge_dss_prec_get(arena))); } JEMALLOC_ALWAYS_INLINE void * @@ -813,9 +813,9 @@ ipalloct(size_t usize, size_t alignment, bool zero, bool try_tcache, ret = arena_palloc(choose_arena(arena), usize, alignment, zero); } else if (alignment <= chunksize) - ret = huge_malloc(usize, zero); + ret = huge_malloc(usize, zero, huge_dss_prec_get(arena)); else - ret = huge_palloc(usize, alignment, zero); + ret = huge_palloc(usize, alignment, zero, huge_dss_prec_get(arena)); } assert(ALIGNMENT_ADDR2BASE(ret, alignment) == ret); @@ -984,7 +984,7 @@ iralloct(void *ptr, size_t size, size_t extra, size_t alignment, bool zero, try_tcache_dalloc)); } else { return (huge_ralloc(ptr, oldsize, size, extra, - alignment, zero, try_tcache_dalloc)); + alignment, zero, try_tcache_dalloc, huge_dss_prec_get(arena))); } } diff --git a/src/huge.c b/src/huge.c index 6d86aed..d72f213 100644 --- a/src/huge.c +++ b/src/huge.c @@ -16,14 +16,14 @@ malloc_mutex_t huge_mtx; static extent_tree_t huge; void * -huge_malloc(size_t size, bool zero) +huge_malloc(size_t size, bool zero, dss_prec_t dss_prec) { - return (huge_palloc(size, chunksize, zero)); + return (huge_palloc(size, chunksize, zero, dss_prec)); } void * -huge_palloc(size_t size, size_t alignment, bool zero) +huge_palloc(size_t size, size_t alignment, bool zero, dss_prec_t dss_prec) { void *ret; size_t csize; @@ -48,8 +48,7 @@ huge_palloc(size_t size, size_t alignment, bool zero) * it is possible to make correct junk/zero fill decisions below. */ is_zeroed = zero; - ret = chunk_alloc(csize, alignment, false, &is_zeroed, - chunk_dss_prec_get()); + ret = chunk_alloc(csize, alignment, false, &is_zeroed, dss_prec); if (ret == NULL) { base_node_dealloc(node); return (NULL); @@ -98,7 +97,7 @@ huge_ralloc_no_move(void *ptr, size_t oldsize, size_t size, size_t extra) void * huge_ralloc(void *ptr, size_t oldsize, size_t size, size_t extra, - size_t alignment, bool zero, bool try_tcache_dalloc) + size_t alignment, bool zero, bool try_tcache_dalloc, dss_prec_t dss_prec) { void *ret; size_t copysize; @@ -113,18 +112,18 @@ huge_ralloc(void *ptr, size_t oldsize, size_t size, size_t extra, * space and copying. */ if (alignment > chunksize) - ret = huge_palloc(size + extra, alignment, zero); + ret = huge_palloc(size + extra, alignment, zero, dss_prec); else - ret = huge_malloc(size + extra, zero); + ret = huge_malloc(size + extra, zero, dss_prec); if (ret == NULL) { if (extra == 0) return (NULL); /* Try again, this time without extra. */ if (alignment > chunksize) - ret = huge_palloc(size, alignment, zero); + ret = huge_palloc(size, alignment, zero, dss_prec); else - ret = huge_malloc(size, zero); + ret = huge_malloc(size, zero, dss_prec); if (ret == NULL) return (NULL); @@ -264,6 +263,13 @@ huge_salloc(const void *ptr) return (ret); } +dss_prec_t +huge_dss_prec_get(arena_t *arena) +{ + + return (arena_dss_prec_get(choose_arena(arena))); +} + prof_ctx_t * huge_prof_ctx_get(const void *ptr) { diff --git a/src/jemalloc.c b/src/jemalloc.c index 563d99f..204778b 100644 --- a/src/jemalloc.c +++ b/src/jemalloc.c @@ -2076,7 +2076,7 @@ a0alloc(size_t size, bool zero) if (size <= arena_maxclass) return (arena_malloc(arenas[0], size, zero, false)); else - return (huge_malloc(size, zero)); + return (huge_malloc(size, zero, huge_dss_prec_get(arenas[0]))); } void * -- cgit v0.12 From c2da2591befa5574cf8c930a5a2cd7f56138658e Mon Sep 17 00:00:00 2001 From: Harald Weppner Date: Tue, 18 Mar 2014 00:00:14 -0700 Subject: Consistently use debug lib(s) if present Fixes a situation where nm uses the debug lib but addr2line does not, which completely messes up the symbol lookup. --- src/prof.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/prof.c b/src/prof.c index ede89a7..7722b7b 100644 --- a/src/prof.c +++ b/src/prof.c @@ -11,12 +11,6 @@ #include #endif -#ifdef __FreeBSD__ -#define PROCESS_VMEM_MAP "/proc/curproc/map" -#else -#define PROCESS_VMEM_MAP "/proc/%d/maps" -#endif - /******************************************************************************/ /* Data. */ @@ -941,9 +935,12 @@ prof_dump_maps(bool propagate_err) char filename[PATH_MAX + 1]; cassert(config_prof); - - malloc_snprintf(filename, sizeof(filename), PROCESS_VMEM_MAP, +#ifdef __FreeBSD__ + malloc_snprintf(filename, sizeof(filename), "/proc/curproc/map"); +#else + malloc_snprintf(filename, sizeof(filename), "/proc/%d/maps", (int)getpid()); +#endif mfd = open(filename, O_RDONLY); if (mfd != -1) { ssize_t nread; -- cgit v0.12 From e3f27cfced57ac9c3b5306947d37411479a68c2e Mon Sep 17 00:00:00 2001 From: Jason Evans Date: Sat, 29 Mar 2014 23:14:32 -0700 Subject: Fix p_test_fail()'s va_list abuse. p_test_fail() was passing a va_list to two separate functions with the expectation that no reset would occur. Refactor p_test_fail()'s callers to instead format two strings and pass them to p_test_fail(). Add a missing parameter to an assert_u64_eq() call, which the compiler warned about after the assertion macro refactoring. --- test/include/test/test.h | 53 ++++++++++++++++++++++++++++++++++++------------ test/src/test.c | 10 ++------- test/unit/SFMT.c | 2 +- 3 files changed, 43 insertions(+), 22 deletions(-) diff --git a/test/include/test/test.h b/test/include/test/test.h index 8cc97af..a32ec07 100644 --- a/test/include/test/test.h +++ b/test/include/test/test.h @@ -1,13 +1,19 @@ +#define ASSERT_BUFSIZE 256 + #define assert_cmp(t, a, b, cmp, neg_cmp, pri, fmt...) do { \ t a_ = (a); \ t b_ = (b); \ if (!(a_ cmp b_)) { \ - p_test_fail( \ + char prefix[ASSERT_BUFSIZE]; \ + char message[ASSERT_BUFSIZE]; \ + malloc_snprintf(prefix, sizeof(prefix), \ "%s:%s:%d: Failed assertion: " \ "(%s) "#cmp" (%s) --> " \ "%"pri" "#neg_cmp" %"pri": ", \ __func__, __FILE__, __LINE__, \ - #a, #b, a_, b_, fmt); \ + #a, #b, a_, b_); \ + malloc_snprintf(message, sizeof(message), fmt); \ + p_test_fail(prefix, message); \ } \ } while (0) @@ -208,24 +214,32 @@ bool a_ = (a); \ bool b_ = (b); \ if (!(a_ == b_)) { \ - p_test_fail( \ + char prefix[ASSERT_BUFSIZE]; \ + char message[ASSERT_BUFSIZE]; \ + malloc_snprintf(prefix, sizeof(prefix), \ "%s:%s:%d: Failed assertion: " \ "(%s) == (%s) --> %s != %s: ", \ __func__, __FILE__, __LINE__, \ #a, #b, a_ ? "true" : "false", \ - b_ ? "true" : "false", fmt); \ + b_ ? "true" : "false"); \ + malloc_snprintf(message, sizeof(message), fmt); \ + p_test_fail(prefix, message); \ } \ } while (0) #define assert_b_ne(a, b, fmt...) do { \ bool a_ = (a); \ bool b_ = (b); \ if (!(a_ != b_)) { \ - p_test_fail( \ + char prefix[ASSERT_BUFSIZE]; \ + char message[ASSERT_BUFSIZE]; \ + malloc_snprintf(prefix, sizeof(prefix), \ "%s:%s:%d: Failed assertion: " \ "(%s) != (%s) --> %s == %s: ", \ __func__, __FILE__, __LINE__, \ #a, #b, a_ ? "true" : "false", \ - b_ ? "true" : "false", fmt); \ + b_ ? "true" : "false"); \ + malloc_snprintf(message, sizeof(message), fmt); \ + p_test_fail(prefix, message); \ } \ } while (0) #define assert_true(a, fmt...) assert_b_eq(a, true, fmt) @@ -233,26 +247,39 @@ #define assert_str_eq(a, b, fmt...) do { \ if (strcmp((a), (b))) { \ - p_test_fail( \ + char prefix[ASSERT_BUFSIZE]; \ + char message[ASSERT_BUFSIZE]; \ + malloc_snprintf(prefix, sizeof(prefix), \ "%s:%s:%d: Failed assertion: " \ "(%s) same as (%s) --> " \ "\"%s\" differs from \"%s\": ", \ - __func__, __FILE__, __LINE__, #a, #b, a, b, fmt); \ + __func__, __FILE__, __LINE__, #a, #b, a, b); \ + malloc_snprintf(message, sizeof(message), fmt); \ + p_test_fail(prefix, message); \ } \ } while (0) #define assert_str_ne(a, b, fmt...) do { \ if (!strcmp((a), (b))) { \ - p_test_fail( \ + char prefix[ASSERT_BUFSIZE]; \ + char message[ASSERT_BUFSIZE]; \ + malloc_snprintf(prefix, sizeof(prefix), \ "%s:%s:%d: Failed assertion: " \ "(%s) differs from (%s) --> " \ "\"%s\" same as \"%s\": ", \ - __func__, __FILE__, __LINE__, #a, #b, a, b, fmt); \ + __func__, __FILE__, __LINE__, #a, #b, a, b); \ + malloc_snprintf(message, sizeof(message), fmt); \ + p_test_fail(prefix, message); \ } \ } while (0) #define assert_not_reached(fmt...) do { \ - p_test_fail("%s:%s:%d: Unreachable code reached: ", \ - __func__, __FILE__, __LINE__, fmt); \ + char prefix[ASSERT_BUFSIZE]; \ + char message[ASSERT_BUFSIZE]; \ + malloc_snprintf(prefix, sizeof(prefix), \ + "%s:%s:%d: Unreachable code reached: ", \ + __func__, __FILE__, __LINE__); \ + malloc_snprintf(message, sizeof(message), fmt); \ + p_test_fail(prefix, message); \ } while (0) /* @@ -299,4 +326,4 @@ void test_fail(const char *format, ...) JEMALLOC_ATTR(format(printf, 1, 2)); test_status_t p_test(test_t* t, ...); void p_test_init(const char *name); void p_test_fini(void); -void p_test_fail(const char *format, ...); +void p_test_fail(const char *prefix, const char *message); diff --git a/test/src/test.c b/test/src/test.c index 6552e37..528d858 100644 --- a/test/src/test.c +++ b/test/src/test.c @@ -86,15 +86,9 @@ p_test(test_t* t, ...) } void -p_test_fail(const char *format, ...) +p_test_fail(const char *prefix, const char *message) { - va_list ap; - va_start(ap, format); - malloc_vcprintf(NULL, NULL, format, ap); - format = va_arg(ap, const char *); - malloc_vcprintf(NULL, NULL, format, ap); - va_end(ap); - malloc_printf("\n"); + malloc_cprintf(NULL, NULL, "%s%s\n", prefix, message); test_status = test_status_fail; } diff --git a/test/unit/SFMT.c b/test/unit/SFMT.c index 4805f8e..c57bd68 100644 --- a/test/unit/SFMT.c +++ b/test/unit/SFMT.c @@ -1576,7 +1576,7 @@ TEST_BEGIN(test_by_array_64) for (i = 0; i < BLOCK_SIZE64; i++) { if (i < COUNT_1) { assert_u64_eq(array64[i], init_by_array_64_expected[i], - "Output mismatch for i=%d"); + "Output mismatch for i=%d", i); } r = gen_rand64(ctx); assert_u64_eq(r, array64[i], -- cgit v0.12 From ab8c79fdafd6d1ee722c1277ef32c14c6e0c9dd3 Mon Sep 17 00:00:00 2001 From: Jason Evans Date: Sun, 30 Mar 2014 11:21:09 -0700 Subject: Fix message formatting errors uncovered by p_test_fail() refactoring. --- test/unit/ckh.c | 12 ++++++------ test/unit/junk.c | 2 +- test/unit/quarantine.c | 2 +- test/unit/rtree.c | 5 +++-- test/unit/zero.c | 2 +- 5 files changed, 12 insertions(+), 11 deletions(-) diff --git a/test/unit/ckh.c b/test/unit/ckh.c index 69fd7f5..b214c27 100644 --- a/test/unit/ckh.c +++ b/test/unit/ckh.c @@ -29,7 +29,7 @@ TEST_BEGIN(test_count_insert_search_remove) assert_false(ckh_new(&ckh, 2, ckh_string_hash, ckh_string_keycomp), "Unexpected ckh_new() error"); assert_zu_eq(ckh_count(&ckh), 0, - "ckh_count() should return %zu, but it returned %zu", 0, + "ckh_count() should return %zu, but it returned %zu", ZU(0), ckh_count(&ckh)); /* Insert. */ @@ -101,11 +101,11 @@ TEST_END TEST_BEGIN(test_insert_iter_remove) { -#define NITEMS 1000 +#define NITEMS ZU(1000) ckh_t ckh; void **p[NITEMS]; void *q, *r; - unsigned i; + size_t i; assert_false(ckh_new(&ckh, 2, ckh_pointer_hash, ckh_pointer_keycomp), "Unexpected ckh_new() error"); @@ -116,7 +116,7 @@ TEST_BEGIN(test_insert_iter_remove) } for (i = 0; i < NITEMS; i++) { - unsigned j; + size_t j; for (j = i; j < NITEMS; j++) { assert_false(ckh_insert(&ckh, p[j], p[j]), @@ -152,7 +152,7 @@ TEST_BEGIN(test_insert_iter_remove) for (tabind = 0; ckh_iter(&ckh, &tabind, &q, &r) == false;) { - unsigned k; + size_t k; assert_ptr_eq(q, r, "Key and val not equal"); @@ -188,7 +188,7 @@ TEST_BEGIN(test_insert_iter_remove) } assert_zu_eq(ckh_count(&ckh), 0, - "ckh_count() should return %zu, but it returned %zu", 0, + "ckh_count() should return %zu, but it returned %zu", ZU(0), ckh_count(&ckh)); ckh_delete(&ckh); #undef NITEMS diff --git a/test/unit/junk.c b/test/unit/junk.c index ef8f9c1..85bbf9e 100644 --- a/test/unit/junk.c +++ b/test/unit/junk.c @@ -73,7 +73,7 @@ test_junk(size_t sz_min, size_t sz_max) if (sz_prev > 0) { assert_c_eq(s[0], 'a', "Previously allocated byte %zu/%zu is corrupted", - 0, sz_prev); + ZU(0), sz_prev); assert_c_eq(s[sz_prev-1], 'a', "Previously allocated byte %zu/%zu is corrupted", sz_prev-1, sz_prev); diff --git a/test/unit/quarantine.c b/test/unit/quarantine.c index 4534923..bbd48a5 100644 --- a/test/unit/quarantine.c +++ b/test/unit/quarantine.c @@ -21,7 +21,7 @@ quarantine_clear(void) TEST_BEGIN(test_quarantine) { -#define SZ 256 +#define SZ ZU(256) #define NQUARANTINED (QUARANTINE_SIZE/SZ) void *quarantined[NQUARANTINED+1]; size_t i, j; diff --git a/test/unit/rtree.c b/test/unit/rtree.c index 5e7a411..5463055 100644 --- a/test/unit/rtree.c +++ b/test/unit/rtree.c @@ -48,8 +48,9 @@ TEST_BEGIN(test_rtree_bits) assert_u_eq(rtree_get(rtree, keys[k]), 1, "rtree_get() should return previously set " "value and ignore insignificant key bits; " - "i=%u, j=%u, k=%u, set key=%#x, " - "get key=%#x", i, j, k, keys[j], keys[k]); + "i=%u, j=%u, k=%u, set key=%#"PRIxPTR", " + "get key=%#"PRIxPTR, i, j, k, keys[j], + keys[k]); } assert_u_eq(rtree_get(rtree, (((uintptr_t)1) << (sizeof(uintptr_t)*8-i))), 0, diff --git a/test/unit/zero.c b/test/unit/zero.c index 2fdae2f..65a8f0c 100644 --- a/test/unit/zero.c +++ b/test/unit/zero.c @@ -20,7 +20,7 @@ test_zero(size_t sz_min, size_t sz_max) if (sz_prev > 0) { assert_c_eq(s[0], 'a', "Previously allocated byte %zu/%zu is corrupted", - 0, sz_prev); + ZU(0), sz_prev); assert_c_eq(s[sz_prev-1], 'a', "Previously allocated byte %zu/%zu is corrupted", sz_prev-1, sz_prev); -- cgit v0.12 From ada8447cf6fb2c1f976b6311dade2e91026b3d83 Mon Sep 17 00:00:00 2001 From: Jason Evans Date: Sun, 30 Mar 2014 11:22:23 -0700 Subject: Reduce maximum tested alignment. Reduce maximum tested alignment from 2^29 to 2^25. Some systems may not have enough contiguous virtual memory to satisfy the larger alignment, but the smaller alignment is still adequate to test multi-chunk alignment. --- test/integration/allocm.c | 3 +-- test/integration/mallocx.c | 3 +-- test/integration/rallocx.c | 4 ++-- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/test/integration/allocm.c b/test/integration/allocm.c index 66ecf86..7b4ea0c 100644 --- a/test/integration/allocm.c +++ b/test/integration/allocm.c @@ -1,8 +1,7 @@ #include "test/jemalloc_test.h" #define CHUNK 0x400000 -/* #define MAXALIGN ((size_t)UINT64_C(0x80000000000)) */ -#define MAXALIGN ((size_t)0x2000000LU) +#define MAXALIGN (((size_t)1) << 25) #define NITER 4 TEST_BEGIN(test_basic) diff --git a/test/integration/mallocx.c b/test/integration/mallocx.c index f37a74b..123e041 100644 --- a/test/integration/mallocx.c +++ b/test/integration/mallocx.c @@ -1,8 +1,7 @@ #include "test/jemalloc_test.h" #define CHUNK 0x400000 -/* #define MAXALIGN ((size_t)UINT64_C(0x80000000000)) */ -#define MAXALIGN ((size_t)0x2000000LU) +#define MAXALIGN (((size_t)1) << 25) #define NITER 4 TEST_BEGIN(test_basic) diff --git a/test/integration/rallocx.c b/test/integration/rallocx.c index b4b6780..ee21aed 100644 --- a/test/integration/rallocx.c +++ b/test/integration/rallocx.c @@ -112,7 +112,7 @@ TEST_BEGIN(test_align) { void *p, *q; size_t align; -#define MAX_ALIGN (ZU(1) << 29) +#define MAX_ALIGN (ZU(1) << 25) align = ZU(1); p = mallocx(1, MALLOCX_ALIGN(align)); @@ -137,7 +137,7 @@ TEST_BEGIN(test_lg_align_and_zero) { void *p, *q; size_t lg_align, sz; -#define MAX_LG_ALIGN 29 +#define MAX_LG_ALIGN 25 #define MAX_VALIDATE (ZU(1) << 22) lg_align = ZU(0); -- cgit v0.12 From df3f27024f193b7baeedcd9f3799b4774dd20bbf Mon Sep 17 00:00:00 2001 From: Jason Evans Date: Sun, 30 Mar 2014 16:27:08 -0700 Subject: Adapt hash tests to big-endian systems. The hash code, which has MurmurHash3 at its core, generates different output depending on system endianness, so adapt the expected output on big-endian systems. MurmurHash3 code also makes the assumption that unaligned access is okay (not true on all systems), but jemalloc only hashes data structures that have sufficient alignment to dodge this limitation. --- configure.ac | 5 +++++ include/jemalloc/internal/hash.h | 2 +- include/jemalloc/internal/jemalloc_internal_defs.h.in | 3 +++ test/unit/hash.c | 6 ++++++ 4 files changed, 15 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 3837a78..d5c663e 100644 --- a/configure.ac +++ b/configure.ac @@ -150,6 +150,11 @@ if test "x$EXTRA_CFLAGS" != "x" ; then fi AC_PROG_CPP +AC_C_BIGENDIAN([ac_cv_big_endian=1], [ac_cv_big_endian=0]) +if test "x${ac_cv_big_endian}" = "x1" ; then + AC_DEFINE_UNQUOTED([JEMALLOC_BIG_ENDIAN], [ ]) +fi + AC_CHECK_SIZEOF([void *]) if test "x${ac_cv_sizeof_void_p}" = "x8" ; then LG_SIZEOF_PTR=3 diff --git a/include/jemalloc/internal/hash.h b/include/jemalloc/internal/hash.h index 09b69df..c7183ed 100644 --- a/include/jemalloc/internal/hash.h +++ b/include/jemalloc/internal/hash.h @@ -320,7 +320,7 @@ hash_x64_128(const void *key, const int len, const uint32_t seed, JEMALLOC_INLINE void hash(const void *key, size_t len, const uint32_t seed, size_t r_hash[2]) { -#if (LG_SIZEOF_PTR == 3) +#if (LG_SIZEOF_PTR == 3 && !defined(JEMALLOC_BIG_ENDIAN)) hash_x64_128(key, len, seed, (uint64_t *)r_hash); #else uint64_t hashes[2]; diff --git a/include/jemalloc/internal/jemalloc_internal_defs.h.in b/include/jemalloc/internal/jemalloc_internal_defs.h.in index e3758e4..c166fbd 100644 --- a/include/jemalloc/internal/jemalloc_internal_defs.h.in +++ b/include/jemalloc/internal/jemalloc_internal_defs.h.in @@ -190,6 +190,9 @@ /* C99 restrict keyword supported. */ #undef JEMALLOC_HAS_RESTRICT +/* For use by hash code. */ +#undef JEMALLOC_BIG_ENDIAN + /* sizeof(int) == 2^LG_SIZEOF_INT. */ #undef LG_SIZEOF_INT diff --git a/test/unit/hash.c b/test/unit/hash.c index 0446e52..abb394a 100644 --- a/test/unit/hash.c +++ b/test/unit/hash.c @@ -122,9 +122,15 @@ hash_variant_verify(hash_variant_t variant) (final[3] << 24); switch (variant) { +#ifdef JEMALLOC_BIG_ENDIAN + case hash_variant_x86_32: expected = 0x6213303eU; break; + case hash_variant_x86_128: expected = 0x266820caU; break; + case hash_variant_x64_128: expected = 0xcc622b6fU; break; +#else case hash_variant_x86_32: expected = 0xb0f57ee3U; break; case hash_variant_x86_128: expected = 0xb3ece62aU; break; case hash_variant_x64_128: expected = 0x6384ba69U; break; +#endif default: not_reached(); } -- cgit v0.12 From e64b1b7be9319b187360306ceff17ce6cb2d530c Mon Sep 17 00:00:00 2001 From: Jason Evans Date: Sun, 30 Mar 2014 17:24:24 -0700 Subject: Enable big-endian mode for SFMT. Add cpp logic to enable big-endian mode in SFMT. This should fix SFMT tests on e.g. MIPS and SPARC. --- test/src/SFMT.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/src/SFMT.c b/test/src/SFMT.c index 433d7f6..e6f8dee 100644 --- a/test/src/SFMT.c +++ b/test/src/SFMT.c @@ -49,6 +49,9 @@ #include "test/jemalloc_test.h" #include "test/SFMT-params.h" +#if defined(JEMALLOC_BIG_ENDIAN) && !defined(BIG_ENDIAN64) +#define BIG_ENDIAN64 1 +#endif #if defined(__BIG_ENDIAN__) && !defined(__amd64) && !defined(BIG_ENDIAN64) #define BIG_ENDIAN64 1 #endif -- cgit v0.12 From e181f5aa76d3a9d59a4e0ce46867349334f286d1 Mon Sep 17 00:00:00 2001 From: Jason Evans Date: Sun, 30 Mar 2014 18:58:32 -0700 Subject: Keep frame pointers if using gcc frame intrinsics. Specify -fno-omit-frame-pointer when using __builtin_frame_address() and __builtin_return_address() for backtracing. This fixes backtracing failures on e.g. i686 for optimized builds. --- configure.ac | 1 + 1 file changed, 1 insertion(+) diff --git a/configure.ac b/configure.ac index d5c663e..3521a70 100644 --- a/configure.ac +++ b/configure.ac @@ -784,6 +784,7 @@ fi ) if test "x$backtrace_method" = "x" -a "x$enable_prof_gcc" = "x1" \ -a "x$GCC" = "xyes" ; then + JE_CFLAGS_APPEND([-fno-omit-frame-pointer]) backtrace_method="gcc intrinsics" AC_DEFINE([JEMALLOC_PROF_GCC], [ ]) else -- cgit v0.12 From 82abf6fe6913a0f8bccc5ad8aeab081a8d9a5ed8 Mon Sep 17 00:00:00 2001 From: Jason Evans Date: Sun, 30 Mar 2014 20:35:50 -0700 Subject: Allow libgcc-based backtracing on x86. Remove autoconf code that explicitly disabled libgcc-based backtracing on i[3456]86. There is no mention of which platforms/compilers exhibited problems when this code was added, and chances are good that any gcc toolchain issues have long since been fixed. --- configure.ac | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/configure.ac b/configure.ac index 3521a70..4de81dc 100644 --- a/configure.ac +++ b/configure.ac @@ -747,22 +747,6 @@ if test "x$backtrace_method" = "x" -a "x$enable_prof_libgcc" = "x1" \ -a "x$GCC" = "xyes" ; then AC_CHECK_HEADERS([unwind.h], , [enable_prof_libgcc="0"]) AC_CHECK_LIB([gcc], [_Unwind_Backtrace], [LIBS="$LIBS -lgcc"], [enable_prof_libgcc="0"]) - dnl The following is conservative, in that it only has entries for CPUs on - dnl which jemalloc has been tested. - AC_MSG_CHECKING([libgcc-based backtracing reliability on ${host_cpu}]) - case "${host_cpu}" in - i[[3456]]86) - AC_MSG_RESULT([unreliable]) - enable_prof_libgcc="0"; - ;; - x86_64) - AC_MSG_RESULT([reliable]) - ;; - *) - AC_MSG_RESULT([unreliable]) - enable_prof_libgcc="0"; - ;; - esac if test "x${enable_prof_libgcc}" = "x1" ; then backtrace_method="libgcc" AC_DEFINE([JEMALLOC_PROF_LIBGCC], [ ]) -- cgit v0.12 From 9c62ed44b04610bd5465c8aaeec5623280015d41 Mon Sep 17 00:00:00 2001 From: Jason Evans Date: Mon, 31 Mar 2014 09:16:59 -0700 Subject: Document how dss precedence affects huge allocation. --- doc/jemalloc.xml.in | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/doc/jemalloc.xml.in b/doc/jemalloc.xml.in index c7e2e87..d8e2e71 100644 --- a/doc/jemalloc.xml.in +++ b/doc/jemalloc.xml.in @@ -1439,8 +1439,12 @@ malloc_conf = "xmalloc:true";]]> Set the precedence of dss allocation as related to mmap allocation for arena <i>, or for all arenas if <i> equals arenas.narenas. See - opt.dss for supported + linkend="arenas.narenas">arenas.narenas. Note + that even during huge allocation this setting is read from the arena + that would be chosen for small or large allocation so that applications + can depend on consistent dss versus mmap allocation regardless of + allocation size. See opt.dss for supported settings. -- cgit v0.12 From ff53631535707c79bbd7e0fd255f954aaf2b5268 Mon Sep 17 00:00:00 2001 From: Jason Evans Date: Mon, 31 Mar 2014 09:23:10 -0700 Subject: Update ChangeLog for 3.6.0. --- ChangeLog | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/ChangeLog b/ChangeLog index c0ca338..d56ee99 100644 --- a/ChangeLog +++ b/ChangeLog @@ -5,6 +5,30 @@ found in the git revision history: https://github.com/jemalloc/jemalloc +* 3.6.0 (March 31, 2014) + + This version contains a critical bug fix for a regression present in 3.5.0 and + 3.5.1. + + Bug fixes: + - Fix a regression in arena_chunk_alloc() that caused crashes during + small/large allocation if chunk allocation failed. In the absence of this + bug, chunk allocation failure would result in allocation failure, e.g. NULL + return from malloc(). This regression was introduced in 3.5.0. + - Fix backtracing for gcc intrinsics-based backtracing by specifying + -fno-omit-frame-pointer to gcc. Note that the application (and all the + libraries it links to) must also be compiled with this option for + backtracing to be reliable. + - Use dss allocation precedence for huge allocations as well as small/large + allocations. + - Fix test assertion failure message formatting. This bug did not manifect on + x86_64 systems because of implementation subtleties in va_list. + - Fix inconsequential test failures for hash and SFMT code. + + New features: + - Support heap profiling on FreeBSD. This feature depends on the proc + filesystem being mounted during heap profile dumping. + * 3.5.1 (February 25, 2014) This version primarily addresses minor bugs in test code. -- cgit v0.12 From 8a26eaca7f4c95771ecbf096caeeba14fbe1122f Mon Sep 17 00:00:00 2001 From: Jason Evans Date: Mon, 31 Mar 2014 09:31:38 -0700 Subject: Add private namespace mangling for huge_dss_prec_get(). --- include/jemalloc/internal/private_symbols.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/include/jemalloc/internal/private_symbols.txt b/include/jemalloc/internal/private_symbols.txt index 1e64ed5..93516d2 100644 --- a/include/jemalloc/internal/private_symbols.txt +++ b/include/jemalloc/internal/private_symbols.txt @@ -197,6 +197,7 @@ huge_allocated huge_boot huge_dalloc huge_dalloc_junk +huge_dss_prec_get huge_malloc huge_mtx huge_ndalloc -- cgit v0.12