cpp_redis
cpp_redis copied to clipboard
Heap-use-after-free when deleting while callback is still running
Hey together,
currently I have a problem regarding the usage of two parallel redis connections from an application. After usage, I want to close the connection by calling the function --> client.disconnect(true);
From this point on, my address sanitizer build says there is a heap-use-after-free problem:
- 08/02/18 13:27:03 INFO [Redis] Disconnection of redis client... // Object 1 client.disconnect(true)
- ~Client: 0x0x61a00001e098 Running 0x0x61a00001e4f0 // Object 1 is deleted via destructor
- 08/02/18 13:27:03 INFO [Redis] Disconnection of redis client... // Object 2 client.disconnect(true)
- ~Client: 0x0x61a00001da98 Running 0x0x61a00001def0 // Object 2 is deleted via destructor
- Callback 0x0x61a00001e098 Running 0x0x61a00001e4f0 // Object 1 is still in use ================================================================= ==13580==ERROR: AddressSanitizer: heap-use-after-free on address 0x61a00001e4f0 at pc 0x0000006b8b79 bp 0x7fd5fe217d30 sp 0x7fd5fe217d20 WRITE of size 4 at 0x61a00001e4f0 thread T3
One can see that two redis client objects get disconnected and destroyed, but nevertheless we receive a callback of the already destroyed object.
Furthermore, one can see that this depends on the below mentioned function client::clear_callbacks
void client::clear_callbacks(void) { if (m_commands.empty()) { return; }
//! dequeue commands and move them to a local variable std::queue<command_request> commands = std::move(m_commands);
m_callbacks_running += __CPP_REDIS_LENGTH(commands.size());
std::thread t(= mutable { while (!commands.empty()) { const auto& callback = commands.front().callback;
if (callback) {
reply r = {"network failure", reply::string_type::error};
callback(r);
}
--m_callbacks_running; // 0x0x61a00001e4f0
commands.pop();
}
m_sync_condvar.notify_all();
}); t.detach(); }
The function clear_callbacks gets called while both objects are still valid. After calling the destructor of the objects, we get a callback from the thread created inside the function.
If there are any further questions, don´t hesitate to ask me.
Thanks in advance, Andy
I submitted a PR to fix this issue as I tracked it down to callbacks not being completed while the object is already destroyed. Looks like this issue https://github.com/Cylix/cpp_redis/issues/198 is reporting the same problem.