Closed wch closed 6 years ago
I'm able to reproduce this reliably, although it requires some pretty quick timing.
First, run:
R -e "radiant:::radiant_window()"
Next, close the browser window after it is mostly loaded. Then, in the terminal, within ~0.5s, press Ctrl-C. It's easier to do when the Makevars file is edited to enable tracing and thread assertions. I'm then able to get this output reliably:
HttpRequest::_on_headers_complete
HttpRequest::sendWSFrame
on_ws_message_sent
HttpRequest::sendWSFrame
on_ws_message_sent
HttpRequest::close
HttpRequest::_on_closed
WebSocketConnection::~WebSocketConnection
WebSocketConnection::onFrameComplete
HttpRequest::closeWSSocket
HttpRequest::close
HttpRequest::onWSClose
HttpRequest::_on_closed
^CHttpRequest::schedule_close
HttpRequest::close
close() called twice on HttpRequest object
HttpRequest::_on_closed
Assertion failed: (px != 0), function operator->, file /Users/winston/R/3.4/BH/include/boost/smart_ptr/shared_ptr.hpp, line 734.
Abort trap: 6
HttpRequest::close()
is indeed getting called twice: Once from HttpRequest::closeWSSocket()
, and once from a callback scheduled by HttpRequest::schedule_close()
.
Here's a minimal example that can cause the crash. To do it, run R in two terminals. In the first terminal, start the server:
library(httpuv)
app <- startServer("0.0.0.0", 8000, list(
onWSOpen = function(ws) {
ws$onMessage(function(binary, message) {
message("onMessage start")
Sys.sleep(5)
message("onMessage next")
ws$send(message)
})
}
))
In the second terminal, run the following websocket client code (this first requires devtools::install_github('rstudio/websocket')
). It will send a message, then close the connection from the client side.
library(websocket)
ws <- WebsocketClient$new("ws://localhost:8000/", function(msg) cat(msg, "\n"))
ws$send("foo")
ws$close()
Finally, within 5 seconds, go to the terminal running the server and press Ctrl-C. This will immediately trigger a segfault.
From rstudio/shiny#1967. Sometimes a segfault can happen when an app is closed during loading.
Trace from lldb:
I believe the problem happens when
HttpRequest::close()
is called twice. The logic here does not match the comment, and looks like it's incorrect: https://github.com/rstudio/httpuv/blob/8a28cdb/src/httprequest.cpp#L600-L604