posit-dev / positron

Positron, a next-generation data science IDE
Other
2.5k stars 77 forks source link

R crashes when connecting to Oracle database via odbc #4051

Open simonpcouch opened 2 months ago

simonpcouch commented 2 months ago

Positron Version:

Positron Version: 2024.07.0 (Universal) build 59

Steps to reproduce the issue:

  1. Create a connection to an Oracle database via odbc in RStudio—MacOS ARM64, Oracle's driver (rather than Posit's Pro Driver). My setup reflects https://github.com/r-dbi/odbc/pull/829, with code:
library(odbc)

con <- dbConnect(
  odbc(), 
  dsn = "Oracle", 
  DBQ = "db", 
  UID = "test", 
  PWD = "odbc"
)
  1. Use the same code to connect in Positron, observe "R 4.3.3 exited unexpectedly and was automatically restarted. You may have lost unsaved work. Exit code: 139."

What did you expect to happen?

Successful connection to the database.

One piece of information I'm looking into at the moment: Oracle connections depend on a few environmental variables being properly set, and I see a difference in the values of those envvars between RStudio and Positron sessions. In RStudio, I see:

Sys.getenv("LD_LIBRARY_PATH")
#> [1] "/Users/simoncouch/instantclient_23_3"
Sys.getenv("PATH")
#> [1] "/Users/simoncouch/instantclient_23_3:/opt/homebrew/bin:/opt/homebrew/sbin:/usr/local/gfortran/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/local/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/appleinternal/bin:/opt/X11/bin:/Library/TeX/texbin:/Applications/quarto/bin:/Users/simoncouch/.local/bin:/usr/texbin:/Applications/RStudio.app/Contents/Resources/app/bin/postback"
Sys.getenv("OCI_INC_DIR")
#> [1] ""
Sys.getenv("OCI_LIB_DIR")
#> [1] ""

Created on 2024-07-17 with reprex v2.1.0

PATH and LD_LIBRARY_PATH are set in my global .Rprofile.

In Positron, I see:

Sys.getenv("LD_LIBRARY_PATH")
#> [1] "/Users/simoncouch/instantclient_23_3"
Sys.getenv("PATH")
#> [1] "/Users/simoncouch/instantclient_23_3:/Users/simoncouch/.pyenv/versions/3.10.4/bin:/Users/simoncouch/instantclient_19_6:/opt/homebrew/opt/protobuf@21/bin:/opt/homebrew/bin:/opt/homebrew/sbin:/usr/local/gfortran/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/local/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/appleinternal/bin:/opt/X11/bin:/Library/TeX/texbin:/Applications/quarto/bin:/Users/simoncouch/.local/bin:/Users/simoncouch/.local/bin"
Sys.getenv("OCI_INC_DIR")
#> [1] "/Users/simoncouch/instantclient_19_6/sdk/include"
Sys.getenv("OCI_LIB_DIR")
#> [1] "/Users/simoncouch/instantclient_19_6"

In both the PATH and OCI_*, there are old Instant Client installations that don't exist anymore.

In RStudio, I have:

dbGetInfo(con)
#> $dbname
#> [1] ""
#> 
#> $dbms.name
#> [1] "Oracle"
#> 
#> $db.version
#> [1] "19.00.0000"
#> 
#> $username
#> [1] "test"
#> 
#> $host
#> [1] ""
#> 
#> $port
#> [1] ""
#> 
#> $sourcename
#> [1] "Oracle"
#> 
#> $servername
#> [1] "db"
#> 
#> $drivername
#> [1] "SQORA32.DLL"
#> 
#> $odbc.version
#> [1] "03.52"
#> 
#> $driver.version
#> [1] "23.03.00239"
#> 
#> $odbcdriver.version
#> [1] "03.52"
#> 
#> $supports.transactions
#> [1] TRUE
#> 
#> $supports.catalogs
#> [1] FALSE
#> 
#> $supports.schema
#> [1] TRUE
#> 
#> $getdata.extensions.any_column
#> [1] TRUE
#> 
#> $getdata.extensions.any_order
#> [1] TRUE

Created on 2024-07-17 with reprex v2.1.0

Were there any error messages in the Output panel or Developer Tools console?

Yes—GitHub is showing "There was an error creating your Issue: body is too long (maximum is 65536 characters)," so I just pasted the logs in this gist. :)

DavisVaughan commented 2 months ago

In particular in the gist logs i see this, which is finally a backtrace for this crash

[Positron] All 5 sockets disconnected; kernel exited
[R]    2: __simple_esappend
[R]    3: _CRYPTO_THREAD_read_lock
[R]    4: _ossl_property_string
[R]    5: _ossl_property_parse_init
[R]    6: _context_init
[R]    7: _OSSL_LIB_CTX_new
[R]    8: _ztca_osl_DefaultLoad
[R]    9: _ztca_osl_CreateCtx
[R]   10: _ztca_Init
[R]   11: _ztca_GetRandomMC
[R]   12: _ztca_GetRandom
[R]   13: _ztcr2rnd
[R]   14: _ztcsh
[R]   15: _kpusattr0
[R]   16: _kpusattr
[R]   17: _bcoSQLConnect
[R]   18: _bcoSQLConnectCP
[R]   19: _bcoSQLDriverConnect
[R]   20: _SQLDriverConnectW
[R]   21: _SQLDriverConnect
[R]   22: __ZN7nanodbc10connection15connection_impl7connectERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEERKNS2_4listINS2_5tupleIJllPvEEENS6_ISE_EEEE
[R]   23: __ZN7nanodbc10connection15connection_implC2ERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEENS2_4listINS2_5tupleIJllPvEEENS6_ISE_EEEE
[R]   24: __ZN7nanodbc10connectionC2ERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEERKNS1_4listINS1_5tupleIJllPvEEENS5_ISD_EEEE
[R]   25: __ZN4odbc15odbc_connectionC2ENSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEES7_S7_S7_NS_12bigint_map_tElRKN4Rcpp8NullableINS9_6VectorILi19ENS9_15PreserveStorageEEEEERKb
[R]   26: __Z12odbc_connectRKNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEES7_S7_S7_ilRKN4Rcpp8NullableINS8_6VectorILi19ENS8_15PreserveStorageEEEEERKb
[R]   27: __odbc_odbc_connect
[R]   28: R_doDotCall
simonpcouch commented 2 months ago

Sys.unsetenv("LD_LIBRARY_PATH") and then connecting results in a successful connection in both RStudio and Positron.🏄

simonpcouch commented 2 months ago

Just so as not to leave this in an ambiguous state—I left this open as the Instant Client and ODBC installation instructions from Oracle tell users to set the LD_LIBRARY_PATH envvar:

On Linux/Unix the directory path of the shared library should be set in the environment variable LD_LIBRARY_PATH, or platform equivalent.

Setting this envvar didn't cause any issues in RStudio, so folks migrating from RStudio will see their connection code newly failing (and rather uninformatively). One option could be to make changes in the odbc R package to detect that envvar and some Positron-is-running envvar inside of dbConnect(odbc(), ...) and raise a more informative error there, though that wouldn't help folks who see R crashes in some other part of their workflow from having set that envvar. Not sure how challenging/invasive it would be for yall to address this from the Positron side, or what the implications are generally for that variable being set by the user.