Commit cedc0c1
authored
Fix segfault caused by socket I/O on a closed io_service (#168)
Fixes #167
### Motivation
Here are some debugging info when the segfault happened in
`testCloseClient`. The outputs have been trimmed to make them clear.
An example crash at `async_write`:
```
#12 0x00007ffff7496dad in basic_stream_socket<...>::boost::asio::async_write /usr/include/boost/asio/impl/write.hpp:512
#13 0x00007ffff748e003 in ClientConnection::asyncWrite lib/ClientConnection.h:245
#14 0x00007ffff746e0b6 in ClientConnection::handleHandshake (this=0x555555e689d0) lib/ClientConnection.cc:502
```
Another example crash at `async_receive`:
```
#6 0x00007ffff7497247 in basic_stream_socket<...>::async_receive /usr/include/boost/asio/basic_stream_socket.hpp:677
#7 0x00007ffff748e647 in ClientConnection::asyncReceive lib/ClientConnection.h:258
#8 0x00007ffff746fa5d in ClientConnection::readNextCommand lib/ClientConnection.cc:606
```
The frame where it crashed:
```
245 if (descriptor_data->shutdown_)
(gdb) p descriptor_data
$2 = (boost::asio::detail::epoll_reactor::per_descriptor_data &) @0x555555e4a780: 0x0
```
We can see the socket descriptor is `nullptr`. The root cause is when
`async_receive` or `async_write` is called, the `io_service` object
might be closed. This case happened when `createProducerAsync` is
called, the actual producer creation continues in another thread, while
the `client.close()` happens in the current thread.
### Modifications
Check if the `ClientConnection` is closed before `async_receive` or
`async_write`. To avoid the use of lock, changing the `state_` field to
atomic.
### Verifications
```bash
./tests/pulsar-tests --gtest_filter='ClientTest.testCloseClient' --gtest_repeat=20
```
It never crashed after applying this patch.1 parent a46da16 commit cedc0c1
2 files changed
+9
-2
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
812 | 812 | | |
813 | 813 | | |
814 | 814 | | |
815 | | - | |
| 815 | + | |
816 | 816 | | |
817 | 817 | | |
818 | 818 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
22 | 22 | | |
23 | 23 | | |
24 | 24 | | |
| 25 | + | |
25 | 26 | | |
26 | 27 | | |
27 | 28 | | |
| |||
235 | 236 | | |
236 | 237 | | |
237 | 238 | | |
| 239 | + | |
| 240 | + | |
| 241 | + | |
238 | 242 | | |
239 | 243 | | |
240 | 244 | | |
| |||
248 | 252 | | |
249 | 253 | | |
250 | 254 | | |
| 255 | + | |
| 256 | + | |
| 257 | + | |
251 | 258 | | |
252 | 259 | | |
253 | 260 | | |
| |||
259 | 266 | | |
260 | 267 | | |
261 | 268 | | |
262 | | - | |
| 269 | + | |
263 | 270 | | |
264 | 271 | | |
265 | 272 | | |
| |||
0 commit comments