Bug 23310 – Segfault on switch with global enum

Status
NEW
Severity
critical
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
All
OS
Windows
Creation time
2022-08-29T12:21:22Z
Last change time
2024-12-13T19:24:17Z
Assigned to
No Owner
Creator
ryuukk_
Moved to GitHub: dmd#18122 →

Comments

Comment #0 by ryuukk.dev — 2022-08-29T12:21:22Z
The follow code segfaults: ``` enum Test {A, B, C} Test test = Test.A; extern(C) void main() { switch(test) { default: break; } } ``` DMD: 2.100.1 It works fine with LDC
Comment #1 by dkorpel — 2022-08-29T13:56:58Z
Is the segfault the result of compiling the code or running the resulting program? I can't reproduce this with dmd master on Linux, but it could be Windows only.
Comment #2 by ryuukk.dev — 2022-08-29T17:18:22Z
I should have been more precise in the report, i appologies The issue is when compiling with a custom `object.d` --- app.d enum Test {A, B, C} Test test = Test.A; extern(C) void main() { switch(test) { default: break; } } --- object.d module object; The following code compiles fine, but when you run the executable, it segfault dmd app.d object.d app.exe
Comment #3 by ryuukk.dev — 2022-08-29T17:47:23Z
It should provide an error: ``` `switch` runtime hook not found Have you created a custom `object` module and forgot to implement the hook? ```
Comment #4 by dkorpel — 2022-08-29T19:52:14Z
(In reply to ryuukk_ from comment #3) > It should provide an error: > > ``` > `switch` runtime hook not found > Have you created a custom `object` module and forgot to implement the hook? > ``` I still cannot reproduce (on linux), and I don't get why you would expect a runtime hook for a switch statement over an integer. If I adapt your example to use final switch: ``` enum Test {A, B, C} Test test = Test.A; extern(C) void main() { final switch(test) { case Test.A: case Test.B: case Test.C: } } ``` I get: test_.d(7): Error: `object.__switch_error` not found. The current runtime does not support generating assert messages, or the runtime is corrupt. Which looks like what you want. Are you sure the segfault is because of the switch, or could it have to do with thread local storage not being initialized on Windows without druntime?
Comment #5 by ryuukk.dev — 2022-08-29T20:12:23Z
I don't know, i'm not knowledgeable enough on the matter Hence the need of a proper error message
Comment #6 by dkorpel — 2022-08-29T20:22:29Z
(In reply to ryuukk_ from comment #5) > I don't know, i'm not knowledgeable enough on the matter Can you test if it still segfaults when you make it `__gshared Test test = Test.A;`? Otherwise I'll look into it on Windows later. > Hence the need of a proper error message Using a custom druntime is quite an advanced use case. This particular segfault could be fixed, but in general, don't expect the quality of error messages to be very good under these circumstances.
Comment #7 by ryuukk.dev — 2022-08-29T20:44:24Z
``` enum Test {A, B, C} Test test = Test.A; extern(C) void main() { switch(test) { default: break; } } ``` without object.d, compiles fine, runs fine it doesn't initialize the runtime, so the issue must be something else? The moment i add `object.d` in the folder, the same code segfaults
Comment #8 by ryuukk.dev — 2022-08-29T20:45:58Z
And following your suggestion ``` enum Test {A, B, C} __gshared Test test = Test.A; extern(C) void main() { switch(test) { default: break; } } ``` Compiles fine, and run fines even with `object.d` I'll try to figure out how druntime initializes the tls on windows and copy the code
Comment #9 by ryuukk.dev — 2022-08-29T21:34:09Z
I struggle to understand druntime code If anyone can help me get rid of the segfault, that would be nice LDC doesn't complain, so that must be something specific to DMD
Comment #10 by ryuukk.dev — 2022-08-29T21:42:58Z
Progress, compiling with `dmd -g -m64 app.d && ./app.exe` (basically adding -g), now works and get rid of the segfault: ``` import core.stdc.stdio; enum Test {A, B, C} Test test = Test.A; extern(C) void main() { switch(test) { default: break; } printf("the end"); } ``` So there is a problem somewhere with DMD not doing something important..
Comment #11 by dfj1esp02 — 2022-08-30T14:04:58Z
TLS on windows is initialized by the system if the executable has TLS directory, otherwise you get some kind of garbage in place of TLS. LDC might link TLS directory unconditionally.
Comment #12 by dfj1esp02 — 2022-08-30T14:16:28Z
For gnu toolchain (as, ld) TLS directory looks like this: --- tlssup.asm --- .intel_syntax .arch generic64,nojumps .global _tls_used .section .rdata _tls_used: .quad ___tls_start__, ___tls_end__, _tls_index, _tls_callbacks _tls_callbacks: .quad 0 .global _tls_index .bss .balign 4 _tls_index: .int 0 --- Compile: as tlssup.asm -o tlssup.obj
Comment #13 by ryuukk.dev — 2022-08-30T15:11:06Z
How can i make it so dmd links the TLS? I'm not familiar with that stuff
Comment #14 by ryuukk.dev — 2022-08-30T22:12:11Z
Problem is solved, i had to copy bunch of other code from druntime Here is a working object.d: https://gist.github.com/ryuukk/53c133f29da5a8326c359a6bb1063207 Would have been cool if the compiler would emit proper error message in the future...
Comment #15 by razvan.nitu1305 — 2023-02-28T14:52:46Z
Is there anything actionable on this issue? To me it seems that the problem was that a proper custom object.d was not provided. I don't see what the compiler can do in such situations.
Comment #16 by ryuukk.dev — 2023-03-01T15:30:42Z
> To me it seems that the problem was that a proper custom object.d was not provided. The issue is the compiler didn't tell me what was wrong, it segfault > I don't see what the compiler can do in such situations. There is, provide proper error message I don't understand why you guys hate proper error message, leaving users in the blind is the goal?
Comment #17 by robert.schadek — 2024-12-13T19:24:17Z
THIS ISSUE HAS BEEN MOVED TO GITHUB https://github.com/dlang/dmd/issues/18122 DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB