Skip to content

Commit f946290

Browse files
authored
Mock - clean up in UdpContext destructor (#9312)
* Fix possible crash in UdpContext host mocking. I saw this crash in UdpContext.h happen after some hours of regular NTP requests.... ``` [17:38:51] ADE: voltage spike: phase A, factor=0.81, cycles=1 (mock) ClientContext::connect: ::connect(): Connection refused (mock) ClientContext::connect: ::connect(): Connection refused (mock) ClientContext::connect: ::connect(): Connection refused (mock) ClientContext::connect: ::connect(): Connection refused [17:41:14] ADE: voltage spike: phase A, factor=0.86, cycles=2 (mock) ClientContext::connect: ::connect(): Connection refused (mock) ClientContext::connect: ::connect(): Connection refused (mock) ClientContext::connect: ::connect(): Connection refused (mock) ClientContext::connect: ::connect(): Connection refused [17:43:49] ADE: voltage spike: phase B, factor=1.12, cycles=3 (mock) ClientContext::connect: ::connect(): Connection refused (mock) =====> UdpServer port: 2390 <===== [17:44:31] NTP: waiting for response from '81.169.233.252' timed out Program received signal SIGSEGV, Segmentation fault. 0x000055555556848c in std::_Function_base::_M_empty() const () (gdb) where #0 0x000055555556848c in std::_Function_base::_M_empty() const () #1 0x00005555555685be in std::function<void ()>::operator bool() const () #2 0x00005555555684b8 in UdpContext::mock_cb() () #3 0x00005555555683af in check_incoming_udp() () #4 0x0000555555567fa6 in main () ``` I tracked it down to UdpContext::mock_cb() which is calling a std::function callback that's been destroyed thus used-after-free. I believe what happens is: 1. UdpContext::unref() calls delete this when refcount hits 0 (line 56) 2. The destructor (~UdpContext(), line 47) is empty — it never calls register_udp(_sock, nullptr) to remove itself from the global udps map 3. check_incoming_udp() iterates udps, finds the dangling pointer, calls mock_cb() on freed memory 4. _on_rx (a destroyed std::function) → segfault in _M_empty() The disconnect() method already does the right thing (lines 78-84: closes socket + unregisters), but it's never called before the object is destroyed via unref(). The fix is to make the destructor clean up properly. I tested intensely, no crashes since. * Format destructor for UdpContext for clarity Fixes code-style CI.
1 parent 7b0ac41 commit f946290

1 file changed

Lines changed: 4 additions & 1 deletion

File tree

tests/host/common/include/UdpContext.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,10 @@ class UdpContext
4444
_sock = mockUDPSocket();
4545
}
4646

47-
~UdpContext() { }
47+
~UdpContext()
48+
{
49+
disconnect();
50+
}
4851

4952
void ref()
5053
{

0 commit comments

Comments
 (0)