Skip to content

WebSocket methods crash when used after save / load #110

@kevinushey

Description

@kevinushey

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?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions