Fix deferring free object that refcount is more than 1 (#14738)
Some checks are pending
CI / test-ubuntu-latest (push) Waiting to run
CI / test-sanitizer-address (push) Waiting to run
CI / build-debian-old (push) Waiting to run
CI / build-macos-latest (push) Waiting to run
CI / build-32bit (push) Waiting to run
CI / build-libc-malloc (push) Waiting to run
CI / build-centos-jemalloc (push) Waiting to run
CI / build-old-chain-jemalloc (push) Waiting to run
Codecov / code-coverage (push) Waiting to run
External Server Tests / test-external-standalone (push) Waiting to run
External Server Tests / test-external-cluster (push) Waiting to run
External Server Tests / test-external-nodebug (push) Waiting to run
Spellcheck / Spellcheck (push) Waiting to run

in https://github.com/redis/redis/pull/14440, we remove the refcount
check in
[tryDeferFreeClientObject](235e688b01 (diff-252bce0cc340542712f0c1adf62e9035ea47a4a064321fbf40ec3dd4b814aaf2R1509)),
it is ok in 8.4 version, since after command execution, the refcount of
a kvobject always is 1.
but in #14608 (8.6 RC1) we change this assumption, increment refcount
when a client refer a kvobject in reply, so now if the refcount of
kvobject is more than 1, we may let the io thread call `decrRefCount`,
there is data race, maybe it causes memory leak.
This commit is contained in:
Yuan Wang 2026-01-25 18:41:16 +08:00 committed by GitHub
parent 18538461d1
commit 6e2cbd51c3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -687,7 +687,7 @@ static void dbSetValue(redisDb *db, robj *key, robj **valref, dictEntryLink link
}
}
if (server.io_threads_num > 1 && old->encoding == OBJ_ENCODING_RAW) {
if (server.io_threads_num > 1 && old->encoding == OBJ_ENCODING_RAW && old->refcount == 1) {
/* In multi-threaded mode, the OBJ_ENCODING_RAW string object usually is
* allocated in the IO thread, so we defer the free to the IO thread.
* Besides, we never free a string object in BIO threads, so, even with