-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
Don't hit thread-local-storage when entering catch_unwind
#34787
Comments
Although not an easy bug to dive into, this shouldn't be too hard to do so. I'd totally be willing to mentor anyone who'd like to tackle this! |
I would like to work on this! I still have a few days before my college starts, so I sure can spend some time working on a not-so-easy bug! 😀 |
@cynicaldevil go for it! If you need any help let me know, and to clarify the TLS access I'm thinking about is this one right here. I believe we only need to hit TLS once we catch an actual panic, not when we enter or if we leave without catching a panic. |
@alexcrichton Since a panic cannot be started when one's already active, the panic counter can only have two values(0 and 1). Therefore, wouldn't it be better to keep track of this using a |
Nah I think we'll need to keep a counter because on a double panic I believe we still invoke the panic hook, and if that panics then the counter will be at 2. The value of 2 is understood as "don't even run the panic hook, just get out of here ASAP" |
@alexcrichton Oh, alright then! |
@alexcrichton Ok, here's what I got after scanning the source code:
Is this correct? |
That’s a well known pattern called rethrowing.
You also should check that |
@cynicaldevil Yes I believe that's correct. I think it should be ok to add this at the end of the function (for both the success and happy paths): debug_assert!(PANIC_COUNT.with(|c| c.get()), 0);
Unfortunately this is actually entirely different in how you'd be supposed to codegen it. Thinking more on this now, I've been informed that if you're in a cleanup pad then it's undefined behavior to raise another exception on MSVC. I believe on Unix it's fine, however. I also believe that rethrowing is implemented by actually catching an exception and then calling library functions to rethrow it. In LLVM a catch pad is quite different from a cleanup pad (which we generate everywhere). |
@alexcrichton If we were to add that statement, then TLS would be accessed anyway, regardless of whether there was a panic or not, which is what we are trying to avoid. I think it must only be added for the path in which a panic occurs. |
Yes, that's correct there's no point in checking that in the panic-less On Jul 15, 2016 13:42, "Nikhil Shagrithaya" notifications@github.com
|
@cynicaldevil ah yeah sure in debug mode it'll hit TLS, but it'll get optimized away in release mode and it's a good sanity check in theory (not required though) |
…richton Refactored code to access TLS only in case of panic (II) Fixes rust-lang#34787 r? @alexcrichton Do it **very** carefully this time!
Refactored code to access TLS only in case of panic (II) Fixes #34787 r? @alexcrichton Do it **very** carefully this time!
Although TLS is fast, it's not that fast on Windows and we shouldn't be hitting it on the fast path for
catch_unwind
. Right now all we do this for is to reset the panic counter back to 0.The purpose of this is to allow code like this to work, but thinking more about that I believe that's actually undefined behavior on MSVC. Basically once a panic is initiated you can't initiate another panic for... "reasons". (I'm not 100% clear myself). This definitely seems like a sketchy pattern as well!
So if we don't want to enable that pattern, I think we can get away with different management of the panic counter:
catch_unwind
returns from catching a panic, decrease the panic counter. (maybe assert it's 0?)This way the normal usage of
catch_unwind
where nothing panics should never hit TLS, and we should still be able to use panics as we do today.The text was updated successfully, but these errors were encountered: