summaryrefslogtreecommitdiffstats
path: root/test
diff options
context:
space:
mode:
authorJason Evans <jasone@canonware.com>2015-09-10 06:16:10 (GMT)
committerJason Evans <jasone@canonware.com>2015-09-10 06:16:10 (GMT)
commita00b10735a80f7070714b278c8acdad4473bea69 (patch)
tree85f469d89b9d910272bd1541bfa8e8cf216281f7 /test
parenta306a60651db0bd835d4009271e0be236b450fb3 (diff)
downloadjemalloc-a00b10735a80f7070714b278c8acdad4473bea69.zip
jemalloc-a00b10735a80f7070714b278c8acdad4473bea69.tar.gz
jemalloc-a00b10735a80f7070714b278c8acdad4473bea69.tar.bz2
Fix "prof.reset" mallctl-related corruption.
Fix heap profiling to distinguish among otherwise identical sample sites with interposed resets (triggered via the "prof.reset" mallctl). This bug could cause data structure corruption that would most likely result in a segfault.
Diffstat (limited to 'test')
-rw-r--r--test/unit/prof_reset.c81
1 files changed, 66 insertions, 15 deletions
diff --git a/test/unit/prof_reset.c b/test/unit/prof_reset.c
index da34d70..69983e5 100644
--- a/test/unit/prof_reset.c
+++ b/test/unit/prof_reset.c
@@ -16,6 +16,14 @@ prof_dump_open_intercept(bool propagate_err, const char *filename)
return (fd);
}
+static void
+set_prof_active(bool active)
+{
+
+ assert_d_eq(mallctl("prof.active", NULL, NULL, &active, sizeof(active)),
+ 0, "Unexpected mallctl failure");
+}
+
static size_t
get_lg_prof_sample(void)
{
@@ -97,15 +105,12 @@ prof_dump_header_intercept(bool propagate_err, const prof_cnt_t *cnt_all)
TEST_BEGIN(test_prof_reset_cleanup)
{
- bool active;
void *p;
prof_dump_header_t *prof_dump_header_orig;
test_skip_if(!config_prof);
- active = true;
- assert_d_eq(mallctl("prof.active", NULL, NULL, &active, sizeof(active)),
- 0, "Unexpected mallctl failure while activating profiling");
+ set_prof_active(true);
assert_zu_eq(prof_bt_count(), 0, "Expected 0 backtraces");
p = mallocx(1, 0);
@@ -133,9 +138,7 @@ TEST_BEGIN(test_prof_reset_cleanup)
dallocx(p, 0);
assert_zu_eq(prof_bt_count(), 0, "Expected 0 backtraces");
- active = false;
- assert_d_eq(mallctl("prof.active", NULL, NULL, &active, sizeof(active)),
- 0, "Unexpected mallctl failure while deactivating profiling");
+ set_prof_active(false);
}
TEST_END
@@ -192,7 +195,6 @@ thd_start(void *varg)
TEST_BEGIN(test_prof_reset)
{
size_t lg_prof_sample_orig;
- bool active;
thd_t thds[NTHREADS];
unsigned thd_args[NTHREADS];
unsigned i;
@@ -208,9 +210,7 @@ TEST_BEGIN(test_prof_reset)
lg_prof_sample_orig = get_lg_prof_sample();
do_prof_reset(5);
- active = true;
- assert_d_eq(mallctl("prof.active", NULL, NULL, &active, sizeof(active)),
- 0, "Unexpected mallctl failure while activating profiling");
+ set_prof_active(true);
for (i = 0; i < NTHREADS; i++) {
thd_args[i] = i;
@@ -224,9 +224,7 @@ TEST_BEGIN(test_prof_reset)
assert_zu_eq(prof_tdata_count(), tdata_count,
"Unexpected remaining tdata structures");
- active = false;
- assert_d_eq(mallctl("prof.active", NULL, NULL, &active, sizeof(active)),
- 0, "Unexpected mallctl failure while deactivating profiling");
+ set_prof_active(false);
do_prof_reset(lg_prof_sample_orig);
}
@@ -237,6 +235,58 @@ TEST_END
#undef RESET_INTERVAL
#undef DUMP_INTERVAL
+/* Test sampling at the same allocation site across resets. */
+#define NITER 10
+TEST_BEGIN(test_xallocx)
+{
+ size_t lg_prof_sample_orig;
+ unsigned i;
+ void *ptrs[NITER];
+
+ test_skip_if(!config_prof);
+
+ lg_prof_sample_orig = get_lg_prof_sample();
+ set_prof_active(true);
+
+ /* Reset profiling. */
+ do_prof_reset(0);
+
+ for (i = 0; i < NITER; i++) {
+ void *p;
+ size_t sz, nsz;
+
+ /* Reset profiling. */
+ do_prof_reset(0);
+
+ /* Allocate small object (which will be promoted). */
+ p = ptrs[i] = mallocx(1, 0);
+ assert_ptr_not_null(p, "Unexpected mallocx() failure");
+
+ /* Reset profiling. */
+ do_prof_reset(0);
+
+ /* Perform successful xallocx(). */
+ sz = sallocx(p, 0);
+ assert_zu_eq(xallocx(p, sz, 0, 0), sz,
+ "Unexpected xallocx() failure");
+
+ /* Perform unsuccessful xallocx(). */
+ nsz = nallocx(sz+1, 0);
+ assert_zu_eq(xallocx(p, nsz, 0, 0), sz,
+ "Unexpected xallocx() success");
+ }
+
+ for (i = 0; i < NITER; i++) {
+ /* dallocx. */
+ dallocx(ptrs[i], 0);
+ }
+
+ set_prof_active(false);
+ do_prof_reset(lg_prof_sample_orig);
+}
+TEST_END
+#undef NITER
+
int
main(void)
{
@@ -247,5 +297,6 @@ main(void)
return (test(
test_prof_reset_basic,
test_prof_reset_cleanup,
- test_prof_reset));
+ test_prof_reset,
+ test_xallocx));
}