-
Notifications
You must be signed in to change notification settings - Fork 13.3k
Add debug-refcell
feature to libcore
#82271
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
Conversation
(rust-highfive has picked a reviewer for you, use r? to override) |
This comment has been minimized.
This comment has been minimized.
bbbde10
to
1c032f6
Compare
This comment has been minimized.
This comment has been minimized.
1c032f6
to
dc2fa13
Compare
This comment has been minimized.
This comment has been minimized.
Implementation seems reasonable - I'm not sure how much we want to do this, but I could easily see it being quite useful in practice. r? @m-ou-se for T-libs |
Ancedotally, I've already used this to fix a bug (ruffle-rs/ruffle#3322) where the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- The captured location is only displayed when
borrow()
or
borrow_mut()
panics. If a crate callstry_borrow().unwrap()
ortry_borrow_mut().unwrap()
, this extra information will be lost.
Why not add the location to the BorrowError
and BorrowMutError
types instead? Then you don't need to modify the borrow()
and borrow_mut()
functions at all, as the .expect()
will include the information in the panic message. And it'll make try_borrow().unwrap()
(etc.) also show the information.
dc2fa13
to
fbdaf3f
Compare
@m-ou-se I've addressed your comments. I've only modified the |
This comment has been minimized.
This comment has been minimized.
The assertion failure is due to the fact that I've enabled this by default to make testing easier. I'll disable the feature by default before this is merged. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks good!
r=me with the feature disabled by default.
fbdaf3f
to
a8ef043
Compare
This comment has been minimized.
This comment has been minimized.
See https://rust-lang.zulipchat.com/#narrow/stream/131828-t-compiler/topic/Attaching.20backtraces.20to.20RefCell/near/226273614 for some background discussion This PR adds a new off-by-default feature `debug-refcell` to libcore. When enabled, this feature stores additional debugging information in `RefCell`. This information is included in the panic message when `borrow()` or `borrow_mut()` panics, to make it easier to track down the source of the issue. Currently, we store the caller location for the earliest active borrow. This has a number of advantages: * There is only a constant amount of overhead per `RefCell` * We don't need any heap memory, so it can easily be implemented in core * Since we are storing the *earliest* active borrow, we don't need any extra logic in the `Drop` implementation for `Ref` and `RefMut` Limitations: * We only store the caller location, not a full `Backtrace`. Until we get support for `Backtrace` in libcore, this is the best tha we can do. * The captured location is only displayed when `borrow()` or `borrow_mut()` panics. If a crate calls `try_borrow().unwrap()` or `try_borrow_mut().unwrap()`, this extra information will be lost. To make testing easier, I've enabled the `debug-refcell` feature by default. I'm not sure how to write a test for this feature - we would need to rebuild core from the test framework, and create a separate sysroot. Since this feature will be off-by-default, users will need to use `xargo` or `cargo -Z build-std` to enable this feature. For users using a prebuilt standard library, this feature will be disabled with zero overhead. I've created a simple test program: ```rust use std::cell::RefCell; fn main() { let _ = std::panic::catch_unwind(|| { let val = RefCell::new(true); let _first = val.borrow(); let _second = val.borrow(); let _third = val.borrow_mut(); }); let _ = std::panic::catch_unwind(|| { let val = RefCell::new(true); let first = val.borrow_mut(); drop(first); let _second = val.borrow_mut(); let _thid = val.borrow(); }); } ``` which produces the following output: ``` thread 'main' panicked at 'already borrowed: BorrowMutError { location: Location { file: "refcell_test.rs", line: 6, col: 26 } }', refcell_test.rs:8:26 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace thread 'main' panicked at 'already mutably borrowed: BorrowError { location: Location { file: "refcell_test.rs", line: 16, col: 27 } }', refcell_test.rs:18:25 ```
a8ef043
to
a23273e
Compare
@bors r=m-ou-se |
📌 Commit a23273e has been approved by |
☀️ Test successful - checks-actions |
See https://rust-lang.zulipchat.com/#narrow/stream/131828-t-compiler/topic/Attaching.20backtraces.20to.20RefCell/near/226273614
for some background discussion
This PR adds a new off-by-default feature
debug-refcell
to libcore.When enabled, this feature stores additional debugging information in
RefCell
. This information is included in the panic message whenborrow()
orborrow_mut()
panics, to make it easier to track down thesource of the issue.
Currently, we store the caller location for the earliest active borrow.
This has a number of advantages:
RefCell
extra logic in the
Drop
implementation forRef
andRefMut
Limitations:
Backtrace
. Untilwe get support for
Backtrace
in libcore, this is the best tha we cando.
borrow()
orborrow_mut()
panics. If a crate callstry_borrow().unwrap()
or
try_borrow_mut().unwrap()
, this extra information will be lost.To make testing easier, I've enabled the
debug-refcell
feature bydefault. I'm not sure how to write a test for this feature - we would
need to rebuild core from the test framework, and create a separate
sysroot.
Since this feature will be off-by-default, users will need to use
xargo
orcargo -Z build-std
to enable this feature. For users usinga prebuilt standard library, this feature will be disabled with zero
overhead.
I've created a simple test program:
which produces the following output: