Skip to content
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

Optionally call winch::winch_add_trace_back() when collecting stack trace #1039

Merged
merged 13 commits into from Oct 7, 2020

Conversation

@krlmlr
Copy link
Member

@krlmlr krlmlr commented Aug 8, 2020

This is for capturing a native stack trace when the error occurs. See the examples at https://github.com/r-prof/winch/pull/4/checks?check_run_id=961027969#step:10:28 and below. I hope to get better native stack traces with libunwind (r-prof/winch#2), I rather like how this seems to work already in all cases (stop(), Rf_error() and abort()).

Would you support this in rlang? I understand that we want to document and stabilize the structure of the "rlang_trace" before exposing it, and that we need tests. I don't mind marking this as "experimental".

@lionel-
Copy link
Member

@lionel- lionel- commented Aug 10, 2020

I would think the proper hook is globalCallingHandlers() (or options(error = ) on older Rs)?

@krlmlr
Copy link
Member Author

@krlmlr krlmlr commented Aug 10, 2020

I would have to rebuild a ton of rlang infrastructure to achieve compatibility with rlang::entrace(). I had my version of entrace() before, this PR is much easier.

Also I'm having a very hard time updating stack traces generated by rlang::abort() -- it's too late to do in the error handler, the stack traces are collected before that.

@lionel-
Copy link
Member

@lionel- lionel- commented Aug 10, 2020

it's too late to do in the error handler, the stack traces are collected before that.

It shouldn't be too late to use entrace() from a calling handler? What do you mean by too late?

@krlmlr
Copy link
Member Author

@krlmlr krlmlr commented Aug 10, 2020

rlang::abort() already calls trace_back() before the error handler kicks in?

trace <- trace_back()

@krlmlr
Copy link
Member Author

@krlmlr krlmlr commented Aug 10, 2020

Results with libunwind are much better, see /vctrs.so in the stack trace below:

> vctrs::vec_as_location(quote, 2)
##[error]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)
Backtrace:
    █
 1. └─vctrs::vec_as_location(quote, 2)
 2.   └─`/vctrs.so`::vctrs_as_location()
 3.     └─`/vctrs.so`::vec_as_location_opts()
 4.       ├─rlang::cnd_signal(...)
 5.       │ └─rlang:::signal_abort(cnd)
 6.       │   └─base::stop(fallback)
 7.       └─(function () ...

Test run: https://github.com/r-prof/winch/runs/965694700?check_suite_focus=true#step:11:171.

@lionel-
Copy link
Member

@lionel- lionel- commented Aug 10, 2020

rlang::abort() already calls trace_back() before the error handler kicks in?

Right but as a calling handler you can create another trace if you'd like. We may also move the trace capture at a later stage (after the signalCondition) in the future, I don't remember why we didn't end up doing that (it was the original plan).

@lionel-
Copy link
Member

@lionel- lionel- commented Aug 10, 2020

It would be good to add C stack support to the entracing in rlang, probably not with a hook though.

@hadley
Copy link
Member

@hadley hadley commented Sep 7, 2020

It would be good to come to some sort of conclusion here. I don't think we need a long-term solution immediately, but we do need something so that we all can start to try out the R/C tracebacks in our own work and see how they feel.

@lionel-
Copy link
Member

@lionel- lionel- commented Sep 7, 2020

Instead of a hook I think rlang should call winch if installed.

@hadley
Copy link
Member

@hadley hadley commented Sep 10, 2020

That's fine with me too

krlmlr added 2 commits Sep 11, 2020
@krlmlr
Copy link
Member Author

@krlmlr krlmlr commented Sep 12, 2020

Done now.

R/trace.R Outdated
@@ -92,6 +92,13 @@ trace_back <- function(top = NULL, bottom = NULL) {
trace <- new_trace(calls, parents)
trace <- trace_trim_env(trace, frames, top)

if (is_installed("winch")) {

This comment has been minimized.

@lionel-

lionel- Sep 14, 2020
Member

This should probably be opt-in during development? I.e. is_true(peek_option("rlang_trace_use_winch")).

Can you document what winch is doing? Is it making any assumptions about the trace internals? Note that these internals are not stable yet, we still have some work to do to match Gabor's traces.

This comment has been minimized.

@krlmlr

krlmlr Sep 14, 2020
Author Member

I'm adding and modifying rows in the data frame, relying on the internal structure. Would it be better to provide a drop-in replacement for sys.calls() and sys.frames() instead?

R/trace.R Outdated
@@ -92,6 +92,13 @@ trace_back <- function(top = NULL, bottom = NULL) {
trace <- new_trace(calls, parents)
trace <- trace_trim_env(trace, frames, top)

if (is_installed("winch")) {
new_trace <- winch::winch_add_trace_back(trace)
if (inherits(new_trace, "rlang_trace")) {

This comment has been minimized.

@lionel-

lionel- Sep 14, 2020
Member

Why would this not inherit from rlang_trace?

@krlmlr krlmlr changed the title Add rlang:::trace_hook option Optionally call winch::winch_add_trace_back() when collecting stack trace Sep 20, 2020
@krlmlr
Copy link
Member Author

@krlmlr krlmlr commented Sep 21, 2020

Fixed now. Added versioned option to allow for incompatible changes.

@krlmlr
Copy link
Member Author

@krlmlr krlmlr commented Oct 5, 2020

winch 0.0.1 is on CRAN now.

@lionel-
Copy link
Member

@lionel- lionel- commented Oct 6, 2020

Can you take a quick look at these changes @krlmlr? I'm sending rlang to CRAN today

@lionel- lionel- merged commit 9bea1cb into r-lib:master Oct 7, 2020
13 checks passed
13 checks passed
macOS-latest (release) macOS-latest (release)
Details
test-coverage test-coverage
Details
windows-latest (release) windows-latest (release)
Details
windows-latest (3.6) windows-latest (3.6)
Details
ubuntu-16.04 (devel) ubuntu-16.04 (devel)
Details
ubuntu-16.04 (release) ubuntu-16.04 (release)
Details
ubuntu-16.04 (oldrel) ubuntu-16.04 (oldrel)
Details
ubuntu-16.04 (3.5) ubuntu-16.04 (3.5)
Details
ubuntu-16.04 (3.4) ubuntu-16.04 (3.4)
Details
ubuntu-16.04 (3.3) ubuntu-16.04 (3.3)
Details
ubuntu-16.04 (3.2) ubuntu-16.04 (3.2)
Details
codecov/patch 72.72% of diff hit (target 0.00%)
Details
codecov/project 86.20% (target 70.00%)
Details
@lionel-
Copy link
Member

@lionel- lionel- commented Oct 7, 2020

Thanks a lot Kirill!

@lionel-
Copy link
Member

@lionel- lionel- commented Oct 8, 2020

rlang 0.4.8 is on CRAN

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

Successfully merging this pull request may close these issues.

None yet

3 participants
You can’t perform that action at this time.