-
Notifications
You must be signed in to change notification settings - Fork 173
fix(websocket): Fix websocket client race on abort and memory leak(IDFGH-16555) #924
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
|
|
67bd7e3 to
46871bf
Compare
| #else | ||
| // When separate TX lock is not configured, we already hold client->lock | ||
| // which protects the transport, so we can send PONG directly | ||
| esp_transport_ws_send_raw(client->transport, WS_TRANSPORT_OPCODES_PONG | WS_TRANSPORT_OPCODES_FIN, data, client->payload_len, |
Check warning
Code scanning / clang-tidy
The value '138' provided to the cast expression is not in the valid range of values for 'ws_transport_opcodes' [clang-analyzer-optin.core.EnumCastOutOfRange] Warning
46871bf to
5577e03
Compare
082b119 to
bff5cbe
Compare
- Add state check in abort_connection to prevent double-close - Fix memory leak: free errormsg_buffer on disconnect - Reset connection state on reconnect to prevent stale data - Implement lock ordering for separate TX lock mode - Added sdkconfig.ci.tx_lock config
ca2956e to
0e58789
Compare
| { | ||
| ESP_WS_CLIENT_STATE_CHECK(TAG, client, return ESP_FAIL); | ||
|
|
||
| // Note: This function must be called with client->lock already held |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If this is a pre-condition for the function, should we add a guard here? If a guard isn't possible this must be documented to user and not be a comment inside the function.
| esp_websocket_client_dispatch_event(client, WEBSOCKET_EVENT_DISCONNECTED, NULL, 0); | ||
|
|
||
| if (client->errormsg_buffer) { | ||
| ESP_LOGI(TAG, "Freeing error buffer (%d bytes) - Free heap: %" PRIu32 " bytes", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be Debug or verbose level.
| client->errormsg_buffer = NULL; | ||
| client->errormsg_size = 0; | ||
| } else { | ||
| ESP_LOGI(TAG, "Disconnect - Free heap: %" PRIu32 " bytes", esp_get_free_heap_size()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here.
| } | ||
| ESP_LOGD(TAG, "Calling abort_connection due to send error"); | ||
| #ifdef CONFIG_ESP_WS_CLIENT_SEPARATE_TX_LOCK | ||
| xSemaphoreGiveRecursive(client->tx_lock); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is better to move this verification to abort connection function.
| const char *data = (client->payload_len == 0) ? NULL : client->rx_buffer; | ||
| ESP_LOGD(TAG, "Sending PONG with payload len=%d", client->payload_len); | ||
| #ifdef CONFIG_ESP_WS_CLIENT_SEPARATE_TX_LOCK | ||
| // CRITICAL: To avoid deadlock, we must follow lock ordering: tx_lock BEFORE client->lock |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These comments are unnecessary.
TODO - Will remove comments after the review ( left it for easier review)
Description
This PR fixes critical memory leaks and crashes in the ESP WebSocket client that occur during reconnection scenarios(CONFIG_ESP_WS_CLIENT_SEPARATE_TX_LOCK = y).
Changes Made:
Related
#898
Checklist
Before submitting a Pull Request, please ensure the following: