| 3579 | } |
| 3580 | |
| 3581 | static void * |
| 3582 | do_realloc_nonnull_zero(void *ptr) { |
| 3583 | if (config_stats) { |
| 3584 | atomic_fetch_add_zu(&zero_realloc_count, 1, ATOMIC_RELAXED); |
| 3585 | } |
| 3586 | if (opt_zero_realloc_action == zero_realloc_action_alloc) { |
| 3587 | /* |
| 3588 | * The user might have gotten an alloc setting while expecting a |
| 3589 | * free setting. If that's the case, we at least try to |
| 3590 | * reduce the harm, and turn off the tcache while allocating, so |
| 3591 | * that we'll get a true first fit. |
| 3592 | */ |
| 3593 | return do_rallocx(ptr, 1, MALLOCX_TCACHE_NONE, true); |
| 3594 | } else if (opt_zero_realloc_action == zero_realloc_action_free) { |
| 3595 | UTRACE(ptr, 0, 0); |
| 3596 | tsd_t *tsd = tsd_fetch(); |
| 3597 | check_entry_exit_locking(tsd_tsdn(tsd)); |
| 3598 | |
| 3599 | tcache_t *tcache = tcache_get_from_ind(tsd, |
| 3600 | TCACHE_IND_AUTOMATIC, /* slow */ true, |
| 3601 | /* is_alloc */ false); |
| 3602 | uintptr_t args[3] = {(uintptr_t)ptr, 0}; |
| 3603 | hook_invoke_dalloc(hook_dalloc_realloc, ptr, args); |
| 3604 | ifree(tsd, ptr, tcache, true); |
| 3605 | |
| 3606 | check_entry_exit_locking(tsd_tsdn(tsd)); |
| 3607 | return NULL; |
| 3608 | } else { |
| 3609 | safety_check_fail("Called realloc(non-null-ptr, 0) with " |
| 3610 | "zero_realloc:abort set\n"); |
| 3611 | /* In real code, this will never run; the safety check failure |
| 3612 | * will call abort. In the unit test, we just want to bail out |
| 3613 | * without corrupting internal state that the test needs to |
| 3614 | * finish. |
| 3615 | */ |
| 3616 | return NULL; |
| 3617 | } |
| 3618 | } |
| 3619 | |
| 3620 | JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN |
| 3621 | void JEMALLOC_NOTHROW * |
no test coverage detected