Thread overview | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
January 12, 2018 union/toString: crash/segfault: What's happening here? | ||||
---|---|---|---|---|
| ||||
crash.d ``` import std.stdio; union U { float f; int i; string toString () { string s; return s; } } void main () { U u; writeln (u); } ``` $ dmd crash.d $ ./crash std.exception.ErrnoException@/.../dmd2/linux/bin64/../../src/phobos/std/stdio.d(2776): (Bad address) ---------------- ??:? @safe int std.exception.errnoEnforce!(int, "/.../dmd2/linux/bin64/../../src/phobos/std/stdio.d", 2776uL).errnoEnforce(int, lazy immutable(char)[]) [0x43f20a] ??:? @safe void std.stdio.File.LockingTextWriter.put!(immutable(char)[]).put(immutable(char)[]) [0x4422a7] ??:? @safe void std.range.primitives.doPut!(std.stdio.File.LockingTextWriter, immutable(char)[]).doPut(ref std.stdio.File.LockingTextWriter, ref immutable(char)[]) [0x44224b] ??:? @safe void std.range.primitives.put!(std.stdio.File.LockingTextWriter, immutable(char)[]).put(ref std.stdio.File.LockingTextWriter, immutable(char)[]) [0x44222b] ??:? void std.format.formatObject!(std.stdio.File.LockingTextWriter, crash.U, char).formatObject(ref std.stdio.File.LockingTextWriter, ref crash.U, ref const(std.format.FormatSpec!(char).FormatSpec)) [0x44220a] ??:? void std.format.formatValue!(std.stdio.File.LockingTextWriter, crash.U, char).formatValue(ref std.stdio.File.LockingTextWriter, ref crash.U, ref const(std.format.FormatSpec!(char).FormatSpec)) [0x44219d] ??:? uint std.format.formattedWrite!(std.stdio.File.LockingTextWriter, char, crash.U).formattedWrite(ref std.stdio.File.LockingTextWriter, const(char[]), crash.U) [0x43e703] ??:? void std.stdio.File.write!(crash.U, char).write(crash.U, char) [0x43e3f5] ??:? void std.stdio.writeln!(crash.U).writeln(crash.U) [0x43e389] ??:? _Dmain [0x43e344] |
January 12, 2018 Re: union/toString: crash/segfault: What's happening here? | ||||
---|---|---|---|---|
| ||||
Posted in reply to kdevel | On Friday, 12 January 2018 at 00:54:03 UTC, kdevel wrote: > crash.d > ``` > import std.stdio; > > union U { > float f; > int i; > string toString () > { > string s; > return s; > } > } > > void main () > { > U u; > writeln (u); > } > ``` > > $ dmd crash.d > $ ./crash > because you don't initialise `s` in > string toString () > { > string s; > return s; > } so it defaults to `string s = null;` thus giving a segfault. try `string s = "";` instead. |
January 12, 2018 Re: union/toString: crash/segfault: What's happening here? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nicholas Wilson | On Friday, 12 January 2018 at 01:45:37 UTC, Nicholas Wilson wrote:
> so it defaults to `string s = null;` thus giving a segfault.
null and "" are basically the same for strings. that's not the problem.
|
January 12, 2018 Re: union/toString: crash/segfault: What's happening here? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nicholas Wilson | On 01/12/2018 02:45 AM, Nicholas Wilson wrote:
> because you don't initialise `s` in
>
>> string toString ()
>> {
>> string s;
>> return s;
>> }
>
> so it defaults to `string s = null;` thus giving a segfault.
>
> try `string s = "";` instead.
A null string is a perfectly fine empty string. Printing it does not lead to a segfault. And the thrown error is not a segfault.
Actually, the problem seems to be that s is not default initialized. It's garbage. And garbage usually isn't a proper string, so writeln fails. Looks like a compiler bug.
|
January 12, 2018 Re: union/toString: crash/segfault: What's happening here? | ||||
---|---|---|---|---|
| ||||
Posted in reply to kdevel | On Friday, 12 January 2018 at 00:54:03 UTC, kdevel wrote:
> $ dmd crash.d
> $ ./crash
Nicholas Wilson is right that you can use = "" to work around it, but with strings, null is supposed to behave the same way.
And this gives different (each wrong) behavior on -m32 vs -m64, which leads me to believe you actually found a compiler bug.
Calling u.toString directly also leads to random spam, which means it isn't even the library.
I'd file this as a compiler codegen bug.
|
January 12, 2018 Re: union/toString: crash/segfault: What's happening here? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Adam D. Ruppe | Thanks for the quick answer! On Friday, 12 January 2018 at 02:16:39 UTC, Adam D. Ruppe wrote: > On Friday, 12 January 2018 at 00:54:03 UTC, kdevel wrote: >> $ dmd crash.d >> $ ./crash > > Nicholas Wilson is right that you can use = "" to work around it, but with strings, null is supposed to behave the same way. > > And this gives different (each wrong) behavior on -m32 vs -m64, which leads me to believe you actually found a compiler bug. dmd -O crash even produces a binary which segfaults on my machine. > Calling u.toString directly also leads to random spam, which means it isn't even the library. > > I'd file this as a compiler codegen bug. https://issues.dlang.org/show_bug.cgi?id=18232 |
January 12, 2018 Re: union/toString: crash/segfault: What's happening here? | ||||
---|---|---|---|---|
| ||||
Posted in reply to kdevel | On Fri, Jan 12, 2018 at 11:09:47AM +0000, kdevel via Digitalmars-d-learn wrote: [...] > On Friday, 12 January 2018 at 02:16:39 UTC, Adam D. Ruppe wrote: [...] > > I'd file this as a compiler codegen bug. > > https://issues.dlang.org/show_bug.cgi?id=18232 Yep, definitely a codegen bug. Apparently, local variables in union member functions aren't initialized to .init as they should be. Digging into the compiler code right now to see if I can find where the problem is... T -- Only boring people get bored. -- JM |
January 12, 2018 Re: union/toString: crash/segfault: What's happening here? | ||||
---|---|---|---|---|
| ||||
On Fri, Jan 12, 2018 at 10:49:45AM -0800, H. S. Teoh via Digitalmars-d-learn wrote: > On Fri, Jan 12, 2018 at 11:09:47AM +0000, kdevel via Digitalmars-d-learn wrote: [...] [...] > > https://issues.dlang.org/show_bug.cgi?id=18232 > > Yep, definitely a codegen bug. Apparently, local variables in union member functions aren't initialized to .init as they should be. [...] Fix: https://github.com/dlang/dmd/pull/7687 Temporary workaround: explicitly initialize your local variables in union member functions. T -- Life begins when you can spend your spare time programming instead of watching television. -- Cal Keegan |
Copyright © 1999-2021 by the D Language Foundation