Add test coverage for ConnectStream#298
Conversation
|
The following sections might be updated with supplementary metadata relevant to reviewers and maintainers. ReviewsSee the guideline and AI policy for information on the review process. ConflictsNo conflicts as of last run. |
ConnectStream
|
Thanks for following up to #183 with these tests. They do seem potentially useful. Here is feedback I'd have:
Overall the tests here seem reasonable to add. It seems good to have at least 1-2 tests verifying disconnects are processed when a capnproto client connects to a non-capnproto server. (Relatedly, there are also other disconnect tests that could be added at different points during capnproto connections, which I started to write in #201 (comment) and https://github.com/ryanofsky/libmultiprocess/commits/pr/distest.2 but was never able to really finish due to complexity of trying to set up and cover all of the relevant cases. Just mentioning this for completeness, though. There's probably not an obviously place to follow up with this at the moment.) |
d3390db to
cdada78
Compare
cdada78 to
4f05dbe
Compare
595e258 to
bc85c9a
Compare
ConnectStreamConnectStream
02b300c to
7c24708
Compare
|
Thanks for the feedback @ryanofsky! I've just rebased to master now that #269 has been merged and added a new commit to move Also, I've made changes to the tests (please check the description), keeping the first 2 tests (Notice that I've dropped the
This is my current focus. I'm looking more into it, but I think this work might need its own branch so we keep test coverage scoped to this PR.
Good, these ideas are great and definitely worth exploring. Happy to tackle them after this. |
|
This PR is now ready for review. I've updated the description as well! |
02f2822 to
bd3c83d
Compare
Previously, the `onDisconnect` handler responsible for deleting the `Connection` was registered before the `ProxyClient<InitInterface>` instance was constructed. If the peer was already disconnected, the event loop could run the handler and delete the `Connection` before the client constructor registered its cleanup callbacks, resulting in the constructor accessing freed memory. To resolve this, register the handler in a second `.sync()` call after the client is constructed.
Next commit will consume the `UnixListener` class in another test file, so move it to a shared one.
aa095c1 to
a648c51
Compare
|
The netbsd 9.4 job exposed a use-after-free race condition in |
| }); | ||
| loop = loop_promise.get_future().get(); | ||
|
|
||
| // Initalize and store sockets |
There was a problem hiding this comment.
LLM Linter (✨ experimental)
Possible typos and grammar issues:
Initalize -> Initialize [misspelling in the socket setup comment; intended meaning is clear but the word is misspelled]
2026-07-10 05:29:42
This commit introduces a new test file `connect_tests.cpp` for testing the `ConnectStream` client method.
a648c51 to
aee480b
Compare
Updated the description expanding more on this issue. |
ref: #183
This PR adds test coverage for the client method
ConnectStream, as suggested by @ryanofsky.The following cases are tested:
Additionally, the
UnixListenerclass introduced in #269 to set up listening tests is extracted to a shared file so the newconnect_tests.cppfile can consume it.Use-after-free race found in the NetBSD 9.4 job
The NetBSD 9.4 job was crashing in the new test
connect_tests.cpp:94with:Asked Claude to try to reproduce it locally and came up with placing (in
ConnectStream)between the
loop.sync(...)block and the client construction to widen the race window so that the event loop thread wins the race (as it consistently did in the failing job), thereby exposing the issue.The sequence of events was as follows: passing a disconnected socket fd causes the RPC system to hit EOF on the first read. The event loop resumes right after the
loop.sync(...)block, resolvesm_network.onDisconnect(), whose handler (registered inside the same sync block) runsdelete connection_ptr.Connection::~Connectionresets itsEventLoopRef m_loopmember, and the memory is freed.The caller thread then wakes up and constructs the
ProxyClient<InitInterface>, whoseProxyContextconstructor reads the freedConnection:libmultiprocess/src/mp/proxy.cpp
Line 82 in 8412fcd
The fix is included in this PR as the first commit. It moves the
onDisconnecthandler registration to a secondloop.sync(...)call just after the proxy client has been constructed.