On Windows XP, the program fn main() { panic!() }
will fail to run with the following:
thread panicked while processing panic. aborting.
I understand that XP isn't necessarily supported by the standard library, and certain sync implementations are stubbed out (probably the root cause of this issue?), but panicking seems like an operation that should really work if at all possible...
Tested with i686-pc-windows-gnu
target and mingw-w64 on:
rustc 1.11.0-nightly (ad7fe6521 2016-06-23)
binary: rustc
commit-hash: ad7fe6521b8a59d84102113ad660edb21de2cba6
commit-date: 2016-06-23
host: x86_64-unknown-linux-gnu
release: 1.11.0-nightly
Indeed this should definitely work! Would you be able to debug a bit and explore why the double panic is happening? (e.g. the panic messages that were printed or the stack traces)
I'm also not sure I've ever heard of pc-windows-gnu working on XP, so MSVC may work better. Even then though we don't regularly test so it may still have regressed.
@alexcrichton
Hm, I can try to see if I can install a debugger and get more info, but I did find https://github.com/passcod/rsnotify/issues/79#issuecomment-226549718 which seems to include a stack trace of the same issue happening with a double panic.
I'm also not sure I've ever heard of pc-windows-gnu working on XP, so MSVC may work better
It seems to work well enough here, besides the aforementioned issue. If I don't trigger a panic most basic functionality seems fine! I don't have a MSVC Rust dev setup, but if anyone wants to compile the minimal test program and attach an exe I can try running it!
Aha, that'd do it. When a thread panics it attempts to run its panic hook, but that panic hook is protected by an RwLock which is in turn not implemented on XP. That means that when panicking you'll panic immediately as you attempt to acquire an rwlock.
We could change this to use a mutex somehow perhaps which I believe is implemented on XP at least.
Alternatively all of Rust's synchronization primitives could be replaced by versions from parking_lot
which works on XP (and is faster). cc @Amanieu
Triage: no changes I'm aware of
I found that this happens to me too. I may go and modify the panic handler to use a Mutex
rather than an RWLock
so I can find out why this program I am writing is panic-ing on Windows XP Embedded.
Would there be too much of a performance hit if RWLock
checks for SRW lock support at runtime like Mutex
? Could always implement it and do a crater run to find out myself.
Mutexes work on XP since it falls back to using CriticalSection*
functions.
Triage: https://github.com/rust-lang/rust/pull/56410 will switch libstd to use parking_lot
, but it's still got a long way to go
I've been using the changes from #56410 in a small program running on Windows XP Embedded machines for a few months now with working panic messages.
(I love that most of the interest in XP and the reason this issue was filed seems to stem from one certain company's use of XP Embedded in their arcade cabinets)
Would there be too much of a performance hit if RWLock checks for SRW lock support at runtime like Mutex? Could always implement it and do a crater run to find out myself.
An alternative would be to make RwLock
fall back to EnterCriticalSection
similar to what Mutex
already does. Yes that would mean it's not an actual reader-writer lock (there'd be no concurrent readers, though many readers from the same thread would still work), but that still seems better than panicking...
An alternative would be to make
RwLock
fall back toEnterCriticalSection
similar to whatMutex
already does. Yes that would mean it's not an actual reader-writer lock (there'd be no concurrent readers, though many readers from the same thread would still work), but that still seems better than panicking...
In a previous issue regarding Windows XP fallback implementations, MrAlert did this a little bit lower-level so it is definitely possible [1].
[1] https://github.com/rust-lang/rust/issues/26654#issuecomment-119450378
Though, after looking at that implementation again, I would not use it because the keyed events APIs are undocumented.
@RalfJung I decided to follow your advise and threw together a PoC using a wrapper around ReentrantMutex
as a fallback when SRW functions are not available using a similar method to what the Windows' Mutex
implementation is doing.
https://github.com/mbilker/rust/tree/srwlock-compat-mutex
https://github.com/mbilker/rust/commit/9d5febc9bd8336e1515347ea892e9339a461e076
@mbilker nice, that is somewhat like what I had in mind. :)
I imagine the underlying "reentrant mutex" can be shared with the Mutex
implementation, to avoid duplicating all that kind
logic? Basically, a Windows Mutex
could just be a wrapper around RwLock
that only exposes write locks. (That is effectively how they are already implemented on Windows Vista+: they use AcquireSRWLockExclusive
.)
@RalfJung It is using the ReentrantMutex
code from Mutex
.
What I meant is that all of this code is now essentially duplicated:
Ah yeah true. I now have Mutex
using RWLock
but will need to run the test suite to ensure this works alright. I also discovered the Windows Condvar
implementation uses SleepConditionVariableSRW
so that will need to be corrected to use SleepConditionVariableCS
when RWLock
is backed by critical sections.
Sorry for the delay. Are there any testing project out there for testing the Rust synchronization APIs?
Well as a start there is the RwLock
test suite. Mutex
also has one.
So testing my changes would be with python x.py test src/libstd/sync
?
EDIT: It was python x.py test src/libstd
. Looks like all the tests pass.
On Linux I'd do ./x.py test --stage 0 --no-doc src/libstd
. The --stage 0
avoids building the entire compiler, twice, just to run some libstd tests.
Considering the nature of this issue, if a panic occurs and the dbghelp.dll
is the stock DLL included with Windows XP, then SymInitializeW
is not available, only SymInitialize
, causing a double panic.
This was after some testing, if I copied a slightly newer dbghelp.dll
over into the DLL search path (in my case, the same directory as the executable), then no issues whatsoever. I do need some way to handle recursive locking or follow the old behavior and use a writer count of some sort since that's how EnterCriticalSection
works.
There's also some other functions that are not available so I am in the middle of putting in the necessary changes into backtrace-rs so it doesn't attempt to unwrap
on missing symbols.
Hi all,
I would like to build a binary for librsvg that can run on Windows 2008 (Vista). I am going to try to build a custom version of rust just to accomplish this.
Currently on Vista/2008 we get the rust dll error that about missing SetThreadErrorMode in the system api. Would a patch like this solve the issue? https://github.com/jeroen/rust/pull/1
@jeroen This bug here is about Windows XP specifically, because it lacks SRW (slim reader writer) locks. Vista+ have SRW locks so your problem is likely unrelated. Please open a new issue.
Most helpful comment
Alternatively all of Rust's synchronization primitives could be replaced by versions from
parking_lot
which works on XP (and is faster). cc @Amanieu