Bug 18504 – Assert in synchronized crashes with SIGILL on exit

Status
RESOLVED
Resolution
FIXED
Severity
major
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
x86_64
OS
Linux
Creation time
2018-02-23T12:53:02Z
Last change time
2018-04-02T11:27:23Z
Assigned to
No Owner
Creator
FeepingCreature

Comments

Comment #0 by default_357-line — 2018-02-23T12:53:02Z
Testcase: void main() { synchronized assert(0); } Expected: Error printed, program exits with error code. Actual: Error printed, program exits with Illegal Instruction. What happens: In 9327d158d457093f5fc064a844f3400515558112 (emit better code for try-finally when function does not throw) for v2.078.0, Walter added an optimization that finally blocks can be handled more efficiently if the function does not throw exceptions. AssertError is not an exception. As a result, the mutex of the synchronized{} block is never unlocked. On program exit, the runtime tries to clean up mutexes at program end. (_d_critical_term -> destroyMutex -> pthread_mutex_destroy) pthread_mutex_destroy errors if the mutex is still locked. This triggers the assert(0), which shows (in release mode) as a ud2: illegal instruction.
Comment #1 by default_357-line — 2018-02-23T12:55:36Z
Note that this issue appears in a similar form with crashes on GC cleanup of objects if an assert failed in a synchronized(this) invariant block.
Comment #2 by bugzilla — 2018-03-20T00:21:38Z
Comment #3 by github-bugzilla — 2018-04-02T11:27:22Z
Commits pushed to master at https://github.com/dlang/dmd https://github.com/dlang/dmd/commit/c0592d257413abee0d20ff8b1ce660c5774244cb Fix issue 18504 - Generate unwind tables for halting functions https://github.com/dlang/dmd/commit/0038ec300710db7939f45f538d03c6528f83ba7a Merge pull request #8027 from LemonBoy/b18504 Fix issue 18504 - Generate unwind tables for halting functions merged-on-behalf-of: Razvan Nitu <[email protected]>