Wiki Roadmap Timeline Tickets New Ticket Source Search Help / Guide About Trac Login

Ticket #112 (closed defect: fixed)

Opened 2 months ago

Last modified 2 months ago

Segfault on template alias parameter with mangled name >= 126 chars

Reported by: fvbommel Assigned to:
Priority: major Milestone:
Component: Version:
Keywords: Cc:

Description

The following program segfaults my LDC (hg r757):

module blaat;

struct MatchResult {
    private size_t data;
}

MatchResult ABCD(alias Alias)(char[]) {
    return MatchResult(1);
}
MatchResult A(alias Alias)(char[]) {
    return MatchResult(1);
}
MatchResult ABCDE(dchar[] chars)(char[]) {
    return MatchResult(1);
}

// The mangled name of A's template parameter needs to be >= 126 chars
// for it to segfault.
// (125 may segfault also, 124 doesn't)
alias A!(ABCD!(ABCDE!("012345678")))
    MangleMatcher;
$ dmd -c blaat.d
$ gdc -c blaat.d
$ ldc -c blaat.d
Segmentation fault

I'm running x86-64 Ubuntu 8.04. As you can see, DMD (v1.036) and GDC ((prerelease gdc 0.25, using dmd 1.021) (Ubuntu 0.25-4.1.2-16ubuntu1), x86-64) compile it without error but LDC segfaults.

GDB backtrace (slighly cleaned up for readability):

#0  0x00007ffaed157060 in strlen () from /lib/libc.so.6
#1  0x00007ffaed123e1a in vfprintf () from /lib/libc.so.6
#2  0x00007ffaed1479ea in vsnprintf () from /lib/libc.so.6
#3  0x000000000057f446 in OutBuffer::vprintf () at ldc/dmd/root.c:1627
#4  0x000000000057f556 in OutBuffer::printf () at ldc/dmd/root.c:1677
#5  0x00000000005b11fd in TemplateInstance::genIdent () at ldc/dmd/template.c:3644
#6  0x00000000005b4f35 in TemplateInstance::semantic () at ldc/dmd/template.c:2964
#7  0x0000000000571dea in TypeInstance::resolve () at ldc/dmd/mtype.c:3667
#8  0x0000000000549d9d in AliasDeclaration::semantic () at ldc/dmd/declaration.c:460
#9  0x0000000000555d18 in Module::semantic () at ldc/dmd/module.c:654
#10 0x000000000056c45e in main () at ldc/dmd/mars.c:1136

Investigating further, it seems strlen is passed an invalid pointer: its value is 0x686374614d313174, which translates to "t11Match" (that substring appears around the middle of the mangled name TemplateInstance::genIdent is trying to print).

Something is very wrong here, probably something to do with the mess that is C(++) varargs... (Unless that format string it uses is incorrect?)

Attachments

varargs.patch (0.9 kB) - added by fvbommel on 11/11/08 16:24:54.
Patch to fix this.

Change History

11/11/08 14:21:36 changed by lindquist

Works for me on x86-32 + Linux :/ Not sure what to do here..

11/11/08 14:56:41 changed by fvbommel

Like I said in IRC: Somebody with an x86-64 (Linux) machine probably needs to take a look at this then...

11/11/08 16:24:54 changed by fvbommel

  • attachment varargs.patch added.

Patch to fix this.

11/11/08 16:25:17 changed by fvbommel

Well, looks like I was right: it's the unholy mess that is C(++) varargs (on X86_64). va_list == __va_list_tag[1] (or some such nonsense) on that particular platform, which means it's passed by reference. Since OutBuffer::vprintf keeps iterating on vsnprintf() until it used a big enough buffer, it needs to va_copy its va_list parameter beforehand, and va_copy it back before retrying. It didn't, which meant that the second iteration tried to read the third and fourth varargs instead of the first and second.

Patch attached.

11/11/08 16:32:59 changed by lindquist

  • status changed from new to closed.
  • resolution set to fixed.

applied in rev [761]

Copyright © 2008, LDC Development Team.