Rust: Panic broken on Windows XP

Created on 29 Jun 2016  路  28Comments  路  Source: rust-lang/rust

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
A-runtime C-bug O-windows T-libs

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

All 28 comments

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 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...

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.)

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.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

modsec picture modsec  路  3Comments

pedrohjordao picture pedrohjordao  路  3Comments

SharplEr picture SharplEr  路  3Comments

wthrowe picture wthrowe  路  3Comments

dnsl48 picture dnsl48  路  3Comments