-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathREADME.Rmd
111 lines (79 loc) · 3.46 KB
/
README.Rmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
---
output: downlit::readme_document
---
<!-- README.md is generated from README.Rmd. Please edit that file -->
```{r, include = FALSE}
knitr::opts_chunk$set(
collapse = TRUE,
comment = "#>",
fig.path = "man/figures/README-",
out.width = "100%"
)
pkgload::load_all()
```
# winch
<!-- badges: start -->
[](https://lifecycle.r-lib.org/articles/stages.html)
[](https://github.com/r-prof/winch/actions)
[](https://CRAN.R-project.org/package=winch)
<!-- badges: end -->
Winch provides stack traces for call chains that cross between R and C function calls.
This is a useful tool for developers of R packages where a substantial portion of the code is C or C++.
## Installation
Install the released version of winch from [CRAN](https://cran.r-project.org/) with:
``` r
install.packages("winch")
```
Install the development version from GitHub with:
``` r
devtools::install_github("r-lib/winch")
```
## Example
Below is an example where an R function calls into C which calls back into R.
Note the second-to-last entry in the trace:
```{r example}
library(winch)
foo <- function() {
winch_call(bar)
}
bar <- function() {
winch_trace_back()
}
foo()
```
`rlang::entrace()` checks if winch is installed, and adds a native backtrace.
As this cannot be easily demonstrated in a knitr document, the output is copied from a GitHub Actions run.
```{r error, eval = FALSE}
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 also profiling) infrastructure introduces the notion of a "context".
Every call to an R function opens a new context and closes it when execution of the function ends.
Unfortunately, no new context is established for native code called with `.Call()` or `.External()`.
Establishing contexts expends precious run time, so this may be the reason for the omission.
To work around this limitation, the source code of all R functions along the call chain is scanned for instances of `.Call` and `.External`.
The native call stack (obtained via [libunwind](https://github.com/libunwind/libunwind) or [libbacktrace](https://github.com/ianlancetaylor/libbacktrace)) is scanned for chunks of code outside of `libR.so` (R's main library) -- these are assumed to correspond to `.Call()` or `.External()`.
The native traces are embedded as artificial calls into the R stack trace.
## Limitations
- The matching will not be perfect, but it may still lead to faster discovery of the cause of an error.
- On Windows winch only works on x64, and there the traces can be obtained only for one shared library at a time.
See `winch_init_library()` for details.
---
## Code of Conduct
Please note that the winch project is released with a [Contributor Code of Conduct](https://contributor-covenant.org/version/2/0/CODE_OF_CONDUCT.html). By contributing to this project, you agree to abide by its terms.