Fix witness/fork() interactions.
Fix witness to clear its list of owned mutexes in the child if platform-specific malloc_mutex code re-initializes mutexes rather than unlocking them.
This commit is contained in:
parent
174c0c3a9c
commit
108c4a11e9
@ -594,7 +594,8 @@ witness_lock_error
|
||||
witness_lockless_error
|
||||
witness_not_owner_error
|
||||
witness_owner_error
|
||||
witness_postfork
|
||||
witness_postfork_child
|
||||
witness_postfork_parent
|
||||
witness_prefork
|
||||
witness_unlock
|
||||
witnesses_cleanup
|
||||
|
@ -96,7 +96,8 @@ void witness_assert_lockless(tsd_t *tsd);
|
||||
void witnesses_cleanup(tsd_t *tsd);
|
||||
void witness_fork_cleanup(tsd_t *tsd);
|
||||
void witness_prefork(tsd_t *tsd);
|
||||
void witness_postfork(tsd_t *tsd);
|
||||
void witness_postfork_parent(tsd_t *tsd);
|
||||
void witness_postfork_child(tsd_t *tsd);
|
||||
|
||||
#endif /* JEMALLOC_H_EXTERNS */
|
||||
/******************************************************************************/
|
||||
|
@ -2770,8 +2770,8 @@ _malloc_prefork(void)
|
||||
|
||||
narenas = narenas_total_get();
|
||||
|
||||
/* Acquire all mutexes in a safe order. */
|
||||
witness_prefork(tsd);
|
||||
/* Acquire all mutexes in a safe order. */
|
||||
ctl_prefork(tsd);
|
||||
malloc_mutex_prefork(tsd, &arenas_lock);
|
||||
prof_prefork0(tsd);
|
||||
@ -2815,6 +2815,7 @@ _malloc_postfork(void)
|
||||
|
||||
tsd = tsd_fetch();
|
||||
|
||||
witness_postfork_parent(tsd);
|
||||
/* Release all mutexes, now that fork() has completed. */
|
||||
chunk_postfork_parent(tsd);
|
||||
base_postfork_parent(tsd);
|
||||
@ -2827,7 +2828,6 @@ _malloc_postfork(void)
|
||||
prof_postfork_parent(tsd);
|
||||
malloc_mutex_postfork_parent(tsd, &arenas_lock);
|
||||
ctl_postfork_parent(tsd);
|
||||
witness_postfork(tsd);
|
||||
}
|
||||
|
||||
void
|
||||
@ -2840,6 +2840,7 @@ jemalloc_postfork_child(void)
|
||||
|
||||
tsd = tsd_fetch();
|
||||
|
||||
witness_postfork_child(tsd);
|
||||
/* Release all mutexes, now that fork() has completed. */
|
||||
chunk_postfork_child(tsd);
|
||||
base_postfork_child(tsd);
|
||||
@ -2852,7 +2853,6 @@ jemalloc_postfork_child(void)
|
||||
prof_postfork_child(tsd);
|
||||
malloc_mutex_postfork_child(tsd, &arenas_lock);
|
||||
ctl_postfork_child(tsd);
|
||||
witness_postfork(tsd);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
@ -222,8 +222,20 @@ witness_prefork(tsd_t *tsd)
|
||||
}
|
||||
|
||||
void
|
||||
witness_postfork(tsd_t *tsd)
|
||||
witness_postfork_parent(tsd_t *tsd)
|
||||
{
|
||||
|
||||
tsd_witness_fork_set(tsd, false);
|
||||
}
|
||||
|
||||
void
|
||||
witness_postfork_child(tsd_t *tsd)
|
||||
{
|
||||
#ifndef JEMALLOC_MUTEX_INIT_CB
|
||||
witness_list_t *witnesses;
|
||||
|
||||
witnesses = tsd_witnessesp_get(tsd);
|
||||
ql_new(witnesses);
|
||||
#endif
|
||||
tsd_witness_fork_set(tsd, false);
|
||||
}
|
||||
|
@ -11,6 +11,13 @@ TEST_BEGIN(test_fork)
|
||||
assert_ptr_not_null(p, "Unexpected malloc() failure");
|
||||
|
||||
pid = fork();
|
||||
|
||||
free(p);
|
||||
|
||||
p = malloc(64);
|
||||
assert_ptr_not_null(p, "Unexpected malloc() failure");
|
||||
free(p);
|
||||
|
||||
if (pid == -1) {
|
||||
/* Error. */
|
||||
test_fail("Unexpected fork() failure");
|
||||
@ -21,11 +28,23 @@ TEST_BEGIN(test_fork)
|
||||
int status;
|
||||
|
||||
/* Parent. */
|
||||
free(p);
|
||||
do {
|
||||
while (true) {
|
||||
if (waitpid(pid, &status, 0) == -1)
|
||||
test_fail("Unexpected waitpid() failure");
|
||||
} while (!WIFEXITED(status) && !WIFSIGNALED(status));
|
||||
if (WIFSIGNALED(status)) {
|
||||
test_fail("Unexpected child termination due to "
|
||||
"signal %d", WTERMSIG(status));
|
||||
break;
|
||||
}
|
||||
if (WIFEXITED(status)) {
|
||||
if (WEXITSTATUS(status) != 0) {
|
||||
test_fail(
|
||||
"Unexpected child exit value %d",
|
||||
WEXITSTATUS(status));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
TEST_END
|
||||
|
Loading…
Reference in New Issue
Block a user