mirror of
https://github.com/esp8266/Arduino.git
synced 2026-10-23 19:08:55 +03:00
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.
This commit is contained in:
committed by
GitHub
parent
7b0ac41694
commit
f946290ea9
@@ -44,7 +44,10 @@ public:
|
|||||||
_sock = mockUDPSocket();
|
_sock = mockUDPSocket();
|
||||||
}
|
}
|
||||||
|
|
||||||
~UdpContext() { }
|
~UdpContext()
|
||||||
|
{
|
||||||
|
disconnect();
|
||||||
|
}
|
||||||
|
|
||||||
void ref()
|
void ref()
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user