rstudio / websocket

WebSocket client for R
https://rstudio.github.io/websocket/
Other
92 stars 19 forks source link

WebSocket methods crash when used after save / load #110

Open kevinushey opened 2 weeks ago

kevinushey commented 2 weeks ago

To reproduce:

library(websocket)
ws <- WebSocket$new("ws://echo.websocket.org/")

file <- tempfile(fileext = ".rds")
saveRDS(ws, file = file)
ws <- readRDS(file)
ws$send("uh oh")

Backtrace:

(lldb) bt
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x0)
  * frame #0: 0x0000000105d0b3ec websocket.so`wsSend(SEXPREC*, SEXPREC*) [inlined] std::__1::shared_ptr<WebsocketConnection>::shared_ptr(this=<unavailable>, __r=nullptr) at memory:3769:18 [opt]
    frame #1: 0x0000000105d0b3ec websocket.so`wsSend(SEXPREC*, SEXPREC*) [inlined] std::__1::shared_ptr<WebsocketConnection>::shared_ptr(this=<unavailable>, __r=nullptr) at memory:3771:1 [opt]
    frame #2: 0x0000000105d0b3ec websocket.so`wsSend(SEXPREC*, SEXPREC*) [inlined] xptrGetWsConn(wsc_xptr=0x00000001038d7238) at websocket.cpp:28:10 [opt]
    frame #3: 0x0000000105d0b3d8 websocket.so`wsSend(wsc_xptr=0x00000001038d7238, msg=0x0000000103ca04d8) at websocket.cpp:103:41 [opt]
    frame #4: 0x0000000105d09368 websocket.so`_websocket_wsSend(wsc_xptr=<unavailable>, msg=<unavailable>) at cpp11.cpp:43:5 [opt]
    frame #5: 0x00000001009dba0c libR.dylib`R_doDotCall(fun=<unavailable>, nargs=2, cargs=<unavailable>, call=0x000000010391e0a8) at dotcode.c:757:11 [opt]
    frame #6: 0x0000000100a382a4 libR.dylib`bcEval_loop(ploc=0x000000016fdfc758) at eval.c:8691:21 [opt]
    frame #7: 0x0000000100a0b46c libR.dylib`bcEval(body=0x000000010391a2e8, rho=0x000000010391dc80) at eval.c:7524:16 [opt]
    frame #8: 0x0000000100a0ab6c libR.dylib`Rf_eval(e=0x000000010391a2e8, rho=0x000000010391dc80) at eval.c:1167:8 [opt]
    frame #9: 0x0000000100a0d72c libR.dylib`R_execClosure(call=0x00000001038eeeb8, newrho=0x000000010391dc80, sysparent=<unavailable>, rho=0x000000010391a908, arglist=<unavailable>, op=0x000000010391a7b8) at eval.c:2398:22 [opt]
    frame #10: 0x0000000100a0c824 libR.dylib`applyClosure_core(call=0x00000001038eeeb8, op=0x000000010391a7b8, arglist=0x000000010391dee8, rho=0x000000010391a908, suppliedvars=<unavailable>, unpromise=TRUE) at eval.c:2311:16 [opt]
    frame #11: 0x0000000100a0ae08 libR.dylib`Rf_eval [inlined] Rf_applyClosure(call=0x00000001038eeeb8, op=0x000000010391a7b8, arglist=<unavailable>, rho=0x000000010391a908, suppliedvars=<unavailable>, unpromise=TRUE) at eval.c:2333:16 [opt]
    frame #12: 0x0000000100a0adf4 libR.dylib`Rf_eval(e=0x00000001038eeeb8, rho=0x000000010391a908) at eval.c:1285:12 [opt]
    frame #13: 0x0000000100a0ffcc libR.dylib`do_begin(call=0x00000001038eef28, op=0x0000000123816120, args=0x00000001038eeef0, rho=0x000000010391a908) at eval.c:3010:10 [opt]
    frame #14: 0x0000000100a0ad34 libR.dylib`Rf_eval(e=0x00000001038eef28, rho=0x000000010391a908) at eval.c:1237:12 [opt]
    frame #15: 0x0000000100a0d72c libR.dylib`R_execClosure(call=0x000000010391ada0, newrho=0x000000010391a908, sysparent=<unavailable>, rho=0x00000001238454b8, arglist=<unavailable>, op=0x00000001038eef98) at eval.c:2398:22 [opt]
    frame #16: 0x0000000100a0c824 libR.dylib`applyClosure_core(call=0x000000010391ada0, op=0x00000001038eef98, arglist=0x000000010391a978, rho=0x00000001238454b8, suppliedvars=<unavailable>, unpromise=TRUE) at eval.c:2311:16 [opt]
    frame #17: 0x0000000100a0ae08 libR.dylib`Rf_eval [inlined] Rf_applyClosure(call=0x000000010391ada0, op=0x00000001038eef98, arglist=<unavailable>, rho=0x00000001238454b8, suppliedvars=<unavailable>, unpromise=TRUE) at eval.c:2333:16 [opt]
    frame #18: 0x0000000100a0adf4 libR.dylib`Rf_eval(e=0x000000010391ada0, rho=0x00000001238454b8) at eval.c:1285:12 [opt]
    frame #19: 0x0000000100a67034 libR.dylib`Rf_ReplIteration(rho=0x00000001238454b8, savestack=<unavailable>, browselevel=<unavailable>, state=0x000000016fdfd850) at main.c:262:2 [opt]
    frame #20: 0x0000000100a68668 libR.dylib`R_ReplConsole(rho=0x00000001238454b8, savestack=0, browselevel=0) at main.c:314:11 [opt]
    frame #21: 0x0000000100a685a4 libR.dylib`run_Rmainloop at main.c:1216:5 [opt]
    frame #22: 0x0000000100a68710 libR.dylib`Rf_mainloop at main.c:1223:5 [opt]
    frame #23: 0x0000000100003ea0 R`main + 32
    frame #24: 0x000000019c6f20e0 dyld`start + 2360

Could we check for null pointers and emit an R error in this scenario?