Bug 20532 – [betterC] methods utilizing stdout cause a segfault

Status
RESOLVED
Resolution
DUPLICATE
Severity
normal
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
x86_64
OS
Windows
Creation time
2020-01-25T17:25:48Z
Last change time
2021-01-11T13:59:42Z
Assigned to
No Owner
Creator
DragonDePlatino

Comments

Comment #0 by DragonDePlatino — 2020-01-25T17:25:48Z
DMD 2.090.0 on Windows 8.1 x64. Compiling this betterC program with "dub run" or "dub run -ax86_64" causes program to exit with a garbage error code: module main; import core.stdc.stdio; extern(C) void main() { fprintf(stdout, "foo"); putchar(' '); } Calling either of these functions causes a crash. Program runs successfully when using "dub run -ax86".
Comment #1 by dkorpel — 2020-08-06T22:11:23Z
The problem is that stdout in the Microsoft C runtime is a macro for __acrt_iob_func(1), which in D is translated as a shared pointer that gets initialized along with the D runtime: The function `rt.dmain2: rt_init` calls `init_msvc` in rt/msvc.c where the pointers for stdin, stdout and stderr are set. If you have an extern(C) main() (with or without -betterC), the runtime won't be initialized so you will be calling fprintf with a FILE* that is just null. putchar is simply a function calling `putc(c,stdout)`, hence the same issue. The annoying part is that people probably use the FILE pointers from core.stdc.stdio precisely because their code is translated from C, where one expects to require no runtime initialization. So the workaround "just initialize them manually" doesn't help translated C programs from failing with an unhelpful error code. I guess the fix would be to make stdout, stderr and stdin functions instead of globals in version (CRuntime_Microsoft), though that might break existing code that takes the address of the global variables. I doubt many programs do that however.
Comment #2 by dkorpel — 2021-01-11T13:59:42Z
*** This issue has been marked as a duplicate of issue 19933 ***