Skip to content

Check we can load duckdb extensions in a separate process #94

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

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

dfalbel
Copy link
Collaborator

@dfalbel dfalbel commented Jul 31, 2025

DuckDB extensions are shared libraries downloaded when
running INSTAll <name>. They are pre-built by the DuckDB
team https://github.com/duckdb/extension-ci-tools

They are built for the major platforms using the standard
compilers.

One of the CRAN test server is a Linux machine with R compiled
with clang instead of GCC. Since the compilers have different
ABIs, a crash happens when trying to execute extensions that are
pre-built on GCC.

To avoid the crash on CRAN machines, we check if the extensions can
be loaded in a separate process and proceed if that's possible. This follows the same pattern that's used by duckplyr in tidyverse/duckplyr#620

For reference this is how the crash looks on CRAN machines:

 *** caught segfault ***
address 0x6575716170, cause 'memory not mapped'

Traceback:
 1: rapi_execute(stmt, convert_opts)
 2: withCallingHandlers(expr, condition = function(cnd) {    {        .__handler_frame__. <- TRUE        .__setup_frame__. <- frame        if (inherits(cnd, "message")) {            except <- c("warning", "error")        }        else if (inherits(cnd, "warning")) {            except <- "error"        }        else {            except <- ""        }    }    while (!is_null(cnd)) {        if (inherits(cnd, "error")) {            out <- handlers[[1L]](cnd)            if (!inherits(out, "rlang_zap"))                 throw(out)        }        inherit <- .subset2(.subset2(cnd, "rlang"), "inherit")        if (is_false(inherit)) {            return()        }        cnd <- .subset2(cnd, "parent")    }})
 3: doTryCatch(return(expr), name, parentenv, handler)
 4: tryCatchOne(expr, names, parentenv, handlers[[1L]])
 5: tryCatchList(expr, classes, parentenv, handlers)
 6: tryCatch(withCallingHandlers(expr, condition = function(cnd) {    {        .__handler_frame__. <- TRUE        .__setup_frame__. <- frame        if (inherits(cnd, "message")) {            except <- c("warning", "error")        }        else if (inherits(cnd, "warning")) {            except <- "error"        }        else {            except <- ""        }    }    while (!is_null(cnd)) {        if (inherits(cnd, "error")) {            out <- handlers[[1L]](cnd)            if (!inherits(out, "rlang_zap"))                 throw(out)        }        inherit <- .subset2(.subset2(cnd, "rlang"), "inherit")        if (is_false(inherit)) {            return()        }        cnd <- .subset2(cnd, "parent")    }}), stackOverflowError = handlers[[1L]])
 7: rlang::try_fetch(rapi_execute(stmt, convert_opts), error = function(e) {    rethrow_error_from_rapi(e, call)})
 8: rethrow_rapi_execute(res@stmt_lst$ref, duckdb_convert_opts_impl(res@connection@convert_opts,     arrow = res@arrow))
 9: duckdb_execute(res)
10: duckdb_result(connection = conn, stmt_lst = stmt_lst, arrow = arrow)
11: .local(conn, statement, ...)
12: dbSendQuery(conn, statement, ...)
13: dbSendQuery(conn, statement, ...)
14: dbSendStatement(conn, statement, ...)
15: dbSendStatement(conn, statement, ...)
16: dbExecute(con, "INSTALL fts; LOAD fts;")
17: dbExecute(con, "INSTALL fts; LOAD fts;")
18: ragnar_store_build_index_v2(store, type)
19: ragnar_store_build_index(store)
An irrecoverable exception occurred. R is aborting now ...

@t-kalinowski
Copy link
Collaborator

Can you please add NEWS?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants