Movatterモバイル変換


[0]ホーム

URL:


winch

Lifecycle: experimentalR build statusCRAN status

Winch provides stack traces for call chains that cross between R andC function calls. This is a useful tool for developers of R packageswhere a substantial portion of the code is C or C++.

Installation

Install the released version of winch fromCRAN with:

install.packages("winch")

Install the development version from GitHub with:

devtools::install_github("r-lib/winch")

Example

Below is an example where an R function calls into C which calls backinto R. Note the second-to-last entry in the trace:

library(winch)foo<-function() {winch_call(bar)}bar<-function() {winch_trace_back()}foo()#>                  func               ip#> 1  Rf_NewFrameConfirm 00007ffa45274480#> 2             Rf_eval 00007ffa452be4f0#> 3        R_execMethod 00007ffa452c3550#> 4             Rf_eval 00007ffa452be4f0#> 5        R_execMethod 00007ffa452c1e90#> 6             Rf_eval 00007ffa452be4f0#> 7             Rf_eval 00007ffa452c0170#> 8     Rf_applyClosure 00007ffa452c1090#> 9             Rf_eval 00007ffa452be4f0#> 10       R_execMethod 00007ffa452c1e90#> 11            Rf_eval 00007ffa452be4f0#> 12            Rf_eval 00007ffa452c0170#> 13    Rf_applyClosure 00007ffa452c1090#> 14            Rf_eval 00007ffa452be4f0#> 15         winch_call 00007ffa32145240#> 16 Rf_NewFrameConfirm 00007ffa452728a0#> 17 Rf_NewFrameConfirm 00007ffa45274480#> 18            Rf_eval 00007ffa452be4f0#> 19       R_execMethod 00007ffa452c1e90#> 20            Rf_eval 00007ffa452be4f0#> 21            Rf_eval 00007ffa452c0170#> 22    Rf_applyClosure 00007ffa452c1090#> 23            Rf_eval 00007ffa452be4f0#> 24       R_execMethod 00007ffa452c1e90#> 25            Rf_eval 00007ffa452be4f0#> 26            Rf_eval 00007ffa452c0170#> 27    Rf_applyClosure 00007ffa452c1090#> 28            Rf_eval 00007ffa452be4f0#> 29     R_forceAndCall 00007ffa452c43a0#> 30           do_Rprof 00007ffa452a8b80#> 31            Rf_eval 00007ffa452be4f0#> 32            Rf_eval 00007ffa452c0170#> 33    Rf_applyClosure 00007ffa452c1090#>                                        pathname#> 1                        /usr/lib/R/lib/libR.so#> 2                        /usr/lib/R/lib/libR.so#> 3                        /usr/lib/R/lib/libR.so#> 4                        /usr/lib/R/lib/libR.so#> 5                        /usr/lib/R/lib/libR.so#> 6                        /usr/lib/R/lib/libR.so#> 7                        /usr/lib/R/lib/libR.so#> 8                        /usr/lib/R/lib/libR.so#> 9                        /usr/lib/R/lib/libR.so#> 10                       /usr/lib/R/lib/libR.so#> 11                       /usr/lib/R/lib/libR.so#> 12                       /usr/lib/R/lib/libR.so#> 13                       /usr/lib/R/lib/libR.so#> 14                       /usr/lib/R/lib/libR.so#> 15 /home/kirill/git/R/r-prof/winch/src/winch.so#> 16                       /usr/lib/R/lib/libR.so#> 17                       /usr/lib/R/lib/libR.so#> 18                       /usr/lib/R/lib/libR.so#> 19                       /usr/lib/R/lib/libR.so#> 20                       /usr/lib/R/lib/libR.so#> 21                       /usr/lib/R/lib/libR.so#> 22                       /usr/lib/R/lib/libR.so#> 23                       /usr/lib/R/lib/libR.so#> 24                       /usr/lib/R/lib/libR.so#> 25                       /usr/lib/R/lib/libR.so#> 26                       /usr/lib/R/lib/libR.so#> 27                       /usr/lib/R/lib/libR.so#> 28                       /usr/lib/R/lib/libR.so#> 29                       /usr/lib/R/lib/libR.so#> 30                       /usr/lib/R/lib/libR.so#> 31                       /usr/lib/R/lib/libR.so#> 32                       /usr/lib/R/lib/libR.so#> 33                       /usr/lib/R/lib/libR.so#>  [ reached 'max' / getOption("max.print") -- omitted 99 rows ]

rlang::entrace()checks if winch is installed, and adds a native backtrace. As thiscannot be easily demonstrated in a knitr document, the output is copiedfrom a GitHub Actions run.

options(  error =rlang::entrace,  rlang_backtrace_on_error ="full",  rlang_trace_use_winch =TRUE)vctrs::vec_as_location(quote,2)
Error: Must subset elements with a valid subscript vector.✖ Subscript has the wrong type `function`.ℹ It must be logical, numeric, or character.Backtrace:    █ 1. └─vctrs::vec_as_location(quote, 2) 2.   └─`/vctrs.so`::vctrs_as_location() 3.     └─`/vctrs.so`::vec_as_location_opts()

How does it work?

winch uses a very simple heuristic. R’s traceback (and alsoprofiling) infrastructure introduces the notion of a “context”. Everycall to an R function opens a new context and closes it when executionof the function ends. Unfortunately, no new context is established fornative code called with.Call()or.External().Establishing contexts expends precious run time, so this may be thereason for the omission.

To work around this limitation, the source code of all R functionsalong the call chain is scanned for instances of.Call and.External. The native call stack (obtained vialibunwind orlibbacktrace)is scanned for chunks of code outside oflibR.so (R’s mainlibrary) – these are assumed to correspond to.Call()or.External().The native traces are embedded as artificial calls into the R stacktrace.

Limitations


Code of Conduct

Please note that the winch project is released with aContributorCode of Conduct. By contributing to this project, you agree to abideby its terms.


[8]ページ先頭

©2009-2025 Movatter.jp