Skip to content

std_out_err doesn't capture executed code #563

@JosiahParry

Description

@JosiahParry

I am purposefully trying to cause a fatal error and capture the output. In this case I am running library() on a package from R 4.4 trying to use R 4.6 (r-devel) and show the error message. However the code that was run is not captured.

reprex::reprex({
getRversion()
#> '4.4.0'

library(
  renv,
  lib.loc = "/Library/Frameworks/R.framework/Versions/4.6-arm64/Resources/library"
)

}, std_out_err = TRUE)

Instead I get the below. I would quite like if the code i used to cause the error (stdin i think?) was included.

This reprex appears to crash R.
See standard output and standard error for more details.

#### Standard output and error

``` sh

 *** caught segfault ***
address 0x45350, cause 'invalid permissions'

Traceback:
 1: dyn.load(file, DLLpath = DLLpath, ...)
 2: library.dynam("renv", pkgname, libname)
 3: renv_ext_onload(libname, pkgname)
 4: fun(libname, pkgname)
 5: doTryCatch(return(expr), name, parentenv, handler)
 6: tryCatchOne(expr, names, parentenv, handlers[[1L]])
 7: tryCatchList(expr, classes, parentenv, handlers)
 8: tryCatch(fun(libname, pkgname), error = identity)
 9: runHook(".onLoad", env, package.lib, package)
10: loadNamespace(package, lib.loc)
11: doTryCatch(return(expr), name, parentenv, handler)
12: tryCatchOne(expr, names, parentenv, handlers[[1L]])
13: tryCatchList(expr, classes, parentenv, handlers)
14: tryCatch({    attr(package, "LibPath") <- which.lib.loc    ns <- loadNamespace(package, lib.loc)    env <- attachNamespace(ns, pos = pos, deps, exclude, include.only)}, error = function(e) {    P <- if (!is.null(cc <- conditionCall(e)))         paste(" in", deparse(cc)[1L])    else ""    msg <- gettextf("package or namespace load failed for %s%s:\n %s",         sQuote(package), P, conditionMessage(e))    if (logical.return && !quietly)         message(paste("Error:", msg), domain = NA)    else stop(msg, call. = FALSE, domain = NA)})
15: library(renv, lib.loc = "/Library/Frameworks/R.framework/Versions/4.6-arm64/Resources/library")
16: eval(expr, envir)
17: eval(expr, envir)
18: withVisible(eval(expr, envir))
19: withCallingHandlers(code, message = function (cnd) {    watcher$capture_plot_and_output()    if (on_message$capture) {        watcher$push(cnd)    }    if (on_message$silence) {        invokeRestart("muffleMessage")    }}, warning = function (cnd) {    if (getOption("warn") >= 2 || getOption("warn") < 0) {        return()    }    watcher$capture_plot_and_output()    if (on_warning$capture) {        cnd <- sanitize_call(cnd)        watcher$push(cnd)    }    if (on_warning$silence) {        invokeRestart("muffleWarning")    }}, error = function (cnd) {    watcher$capture_plot_and_output()    cnd <- sanitize_call(cnd)    watcher$push(cnd)    switch(on_error, continue = invokeRestart("eval_continue"),         stop = invokeRestart("eval_stop"), error = invokeRestart("eval_error",             cnd))})
20: eval(call)
21: eval(call)
22: with_handlers({    for (expr in tle$exprs) {        ev <- withVisible(eval(expr, envir))        watcher$capture_plot_and_output()        watcher$print_value(ev$value, ev$visible, envir)    }    TRUE}, handlers)
23: doWithOneRestart(return(expr), restart)
24: withOneRestart(expr, restarts[[1L]])
25: withRestartList(expr, restarts[-nr])
26: doWithOneRestart(return(expr), restart)
27: withOneRestart(withRestartList(expr, restarts[-nr]), restarts[[nr]])
28: withRestartList(expr, restarts[-nr])
29: doWithOneRestart(return(expr), restart)
30: withOneRestart(withRestartList(expr, restarts[-nr]), restarts[[nr]])
31: withRestartList(expr, restarts)
32: withRestarts(with_handlers({    for (expr in tle$exprs) {        ev <- withVisible(eval(expr, envir))        watcher$capture_plot_and_output()        watcher$print_value(ev$value, ev$visible, envir)    }    TRUE}, handlers), eval_continue = function() TRUE, eval_stop = function() FALSE,     eval_error = function(cnd) {        signalCondition(cnd)        stop(cnd)    })
33: evaluate::evaluate(...)
34: evaluate(code, envir = env, new_device = FALSE, keep_warning = if (is.numeric(options$warning)) TRUE else options$warning,     keep_message = if (is.numeric(options$message)) TRUE else options$message,     stop_on_error = if (is.numeric(options$error)) options$error else {        if (options$error && options$include)             0L        else 2L    }, output_handler = knit_handlers(options$render, options))
35: in_dir(input_dir(), expr)
36: in_input_dir(evaluate(code, envir = env, new_device = FALSE,     keep_warning = if (is.numeric(options$warning)) TRUE else options$warning,     keep_message = if (is.numeric(options$message)) TRUE else options$message,     stop_on_error = if (is.numeric(options$error)) options$error else {        if (options$error && options$include)             0L        else 2L    }, output_handler = knit_handlers(options$render, options)))
37: eng_r(options)
38: block_exec(params)
39: call_block(x)
40: process_group(group)
41: withCallingHandlers(if (tangle) process_tangle(group) else process_group(group),     error = function(e) if (xfun::pkg_available("rlang", "1.0.0")) rlang::entrace(e))
42: xfun:::handle_error(withCallingHandlers(if (tangle) process_tangle(group) else process_group(group),     error = function(e) if (xfun::pkg_available("rlang", "1.0.0")) rlang::entrace(e)),     function(loc) {        setwd(wd)        write_utf8(res, output %n% stdout())        paste0("\nQuitting from lines ", loc)    }, if (labels[i] != "") sprintf(" [%s]", labels[i]), get_loc)
43: process_file(text, output)
44: knitr::knit(knit_input, knit_output, envir = envir, quiet = quiet)
45: rmarkdown::render(input, quiet = TRUE, envir = globalenv(), encoding = "UTF-8")
46: (function (input) {    rmarkdown::render(input, quiet = TRUE, envir = globalenv(),         encoding = "UTF-8")})(input = base::quote("dopey-nyala_reprex.R"))
47: (function (what, args, quote = FALSE, envir = parent.frame()) {    if (!is.list(args))         stop("second argument must be a list")    if (quote)         args <- lapply(args, enquote)    .Internal(do.call(what, args, envir))})(base::quote(function (input) {    rmarkdown::render(input, quiet = TRUE, envir = globalenv(),         encoding = "UTF-8")}), base::quote(list(input = "dopey-nyala_reprex.R")), envir = base::quote(<environment>),     quote = base::quote(TRUE))
48: base::do.call(base::do.call, base::c(base::readRDS("/var/folders/wd/xq999jjj3bx2w8cpg7lkfxlm0000gn/T//RtmpaW1t1X/callr-fun-576bee2084d"),     base::list(envir = .GlobalEnv, quote = TRUE)), envir = .GlobalEnv,     quote = TRUE)
49: base::saveRDS(base::do.call(base::do.call, base::c(base::readRDS("/var/folders/wd/xq999jjj3bx2w8cpg7lkfxlm0000gn/T//RtmpaW1t1X/callr-fun-576bee2084d"),     base::list(envir = .GlobalEnv, quote = TRUE)), envir = .GlobalEnv,     quote = TRUE), file = "/var/folders/wd/xq999jjj3bx2w8cpg7lkfxlm0000gn/T//RtmpaW1t1X/callr-res-576b198efedd",     compress = FALSE)
50: base::withCallingHandlers({    NULL    base::saveRDS(base::do.call(base::do.call, base::c(base::readRDS("/var/folders/wd/xq999jjj3bx2w8cpg7lkfxlm0000gn/T//RtmpaW1t1X/callr-fun-576bee2084d"),         base::list(envir = .GlobalEnv, quote = TRUE)), envir = .GlobalEnv,         quote = TRUE), file = "/var/folders/wd/xq999jjj3bx2w8cpg7lkfxlm0000gn/T//RtmpaW1t1X/callr-res-576b198efedd",         compress = FALSE)    base::flush(base::stdout())    base::flush(base::stderr())    NULL    base::invisible()}, error = function(e) {    {        callr_data <- base::as.environment("tools:callr")$`__callr_data__`        err <- callr_data$err        if (FALSE) {            base::assign(".Traceback", base::.traceback(4), envir = callr_data)            utils::dump.frames("__callr_dump__")            base::assign(".Last.dump", .GlobalEnv$`__callr_dump__`,                 envir = callr_data)            base::rm("__callr_dump__", envir = .GlobalEnv)        }        e <- err$process_call(e)        e2 <- err$new_error("error in callr subprocess")        class <- base::class        class(e2) <- base::c("callr_remote_error", class(e2))        e2 <- err$add_trace_back(e2)        cut <- base::which(e2$trace$scope == "global")[1]        if (!base::is.na(cut)) {            e2$trace <- e2$trace[-(1:cut), ]        }        base::saveRDS(base::list("error", e2, e), file = base::paste0("/var/folders/wd/xq999jjj3bx2w8cpg7lkfxlm0000gn/T//RtmpaW1t1X/callr-res-576b198efedd",             ".error"))    }}, interrupt = function(e) {    {        callr_data <- base::as.environment("tools:callr")$`__callr_data__`        err <- callr_data$err        if (FALSE) {            base::assign(".Traceback", base::.traceback(4), envir = callr_data)            utils::dump.frames("__callr_dump__")            base::assign(".Last.dump", .GlobalEnv$`__callr_dump__`,                 envir = callr_data)            base::rm("__callr_dump__", envir = .GlobalEnv)        }        e <- err$process_call(e)        e2 <- err$new_error("error in callr subprocess")        class <- base::class        class(e2) <- base::c("callr_remote_error", class(e2))        e2 <- err$add_trace_back(e2)        cut <- base::which(e2$trace$scope == "global")[1]        if (!base::is.na(cut)) {            e2$trace <- e2$trace[-(1:cut), ]        }        base::saveRDS(base::list("error", e2, e), file = base::paste0("/var/folders/wd/xq999jjj3bx2w8cpg7lkfxlm0000gn/T//RtmpaW1t1X/callr-res-576b198efedd",             ".error"))    }}, callr_message = function(e) {    base::try(base::signalCondition(e))})
51: doTryCatch(return(expr), name, parentenv, handler)
52: tryCatchOne(expr, names, parentenv, handlers[[1L]])
53: tryCatchList(expr, names[-nh], parentenv, handlers[-nh])
54: doTryCatch(return(expr), name, parentenv, handler)
55: tryCatchOne(tryCatchList(expr, names[-nh], parentenv, handlers[-nh]),     names[nh], parentenv, handlers[[nh]])
56: tryCatchList(expr, classes, parentenv, handlers)
57: base::tryCatch(base::withCallingHandlers({    NULL    base::saveRDS(base::do.call(base::do.call, base::c(base::readRDS("/var/folders/wd/xq999jjj3bx2w8cpg7lkfxlm0000gn/T//RtmpaW1t1X/callr-fun-576bee2084d"),         base::list(envir = .GlobalEnv, quote = TRUE)), envir = .GlobalEnv,         quote = TRUE), file = "/var/folders/wd/xq999jjj3bx2w8cpg7lkfxlm0000gn/T//RtmpaW1t1X/callr-res-576b198efedd",         compress = FALSE)    base::flush(base::stdout())    base::flush(base::stderr())    NULL    base::invisible()}, error = function(e) {    {        callr_data <- base::as.environment("tools:callr")$`__callr_data__`        err <- callr_data$err        if (FALSE) {            base::assign(".Traceback", base::.traceback(4), envir = callr_data)            utils::dump.frames("__callr_dump__")            base::assign(".Last.dump", .GlobalEnv$`__callr_dump__`,                 envir = callr_data)            base::rm("__callr_dump__", envir = .GlobalEnv)        }        e <- err$process_call(e)        e2 <- err$new_error("error in callr subprocess")        class <- base::class        class(e2) <- base::c("callr_remote_error", class(e2))        e2 <- err$add_trace_back(e2)        cut <- base::which(e2$trace$scope == "global")[1]        if (!base::is.na(cut)) {            e2$trace <- e2$trace[-(1:cut), ]        }        base::saveRDS(base::list("error", e2, e), file = base::paste0("/var/folders/wd/xq999jjj3bx2w8cpg7lkfxlm0000gn/T//RtmpaW1t1X/callr-res-576b198efedd",             ".error"))    }}, interrupt = function(e) {    {        callr_data <- base::as.environment("tools:callr")$`__callr_data__`        err <- callr_data$err        if (FALSE) {            base::assign(".Traceback", base::.traceback(4), envir = callr_data)            utils::dump.frames("__callr_dump__")            base::assign(".Last.dump", .GlobalEnv$`__callr_dump__`,                 envir = callr_data)            base::rm("__callr_dump__", envir = .GlobalEnv)        }        e <- err$process_call(e)        e2 <- err$new_error("error in callr subprocess")        class <- base::class        class(e2) <- base::c("callr_remote_error", class(e2))        e2 <- err$add_trace_back(e2)        cut <- base::which(e2$trace$scope == "global")[1]        if (!base::is.na(cut)) {            e2$trace <- e2$trace[-(1:cut), ]        }        base::saveRDS(base::list("error", e2, e), file = base::paste0("/var/folders/wd/xq999jjj3bx2w8cpg7lkfxlm0000gn/T//RtmpaW1t1X/callr-res-576b198efedd",             ".error"))    }}, callr_message = function(e) {    base::try(base::signalCondition(e))}), error = function(e) {    NULL    if (TRUE) {        base::try(base::stop(e))    }    else {        base::invisible()    }}, interrupt = function(e) {    NULL    if (TRUE) {        e    }    else {        base::invisible()    }})
An irrecoverable exception occurred. R is aborting now ...
```

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