Bug 3753 – ICE(eh.c): Related to exception handling and alloca.
Status
RESOLVED
Resolution
FIXED
Severity
major
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
Other
OS
Linux
Creation time
2010-01-29T15:04:00Z
Last change time
2015-10-04T18:19:40Z
Keywords
ice
Assigned to
nobody
Creator
dsimcha
Comments
Comment #0 by dsimcha — 2010-01-29T15:04:57Z
I can't seem to reduce this one to a small test case, but I think this comment from where the assert fires at least gives a hint that it involves some combination of exceptions and alloca:
// BUG: alloca() changes the stack size, which is not reflected
// in the fixed eh tables.
assert(!usedalloca);
Also, in the (too large to post to Bugzilla) program that this issue occurred in, removing the alloca() calls and replacing them with GC.malloc() fixed the problem.
This assert is in a #if TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_SOLARIS statement, so I guess it only happens on those OS's. The code that triggers it definitely works on Windows.
Comment #1 by clugdbug — 2010-01-30T00:53:46Z
(In reply to comment #0)
> I can't seem to reduce this one to a small test case, but I think this comment
> from where the assert fires at least gives a hint that it involves some
> combination of exceptions and alloca:
>
> // BUG: alloca() changes the stack size, which is not reflected
> // in the fixed eh tables.
> assert(!usedalloca);
>
> Also, in the (too large to post to Bugzilla) program that this issue occurred
> in, removing the alloca() calls and replacing them with GC.malloc() fixed the
> problem.
Are you sure you can't cut it down? Without a test case, the chance of it ever getting fixed is pretty remote (basically, you have to wait until someone else hits the same bug and files a test case). Even a huge test case would help.
Comment #2 by dsimcha — 2010-01-30T06:48:29Z
import core.stdc.stdlib;
void main(string[] args) {
try { doNothing(); } catch {}
void* foo = alloca(args.length);
}
void doNothing() {}
I've had some more time to fiddle with this and more insight into what causes it, so I've managed to get a reduced test case working. It seems like you need to do both of the following in the same function:
1. Use exception handling either explicitly or implicitly. This can include try-catch, try-finally, scope(exit), and struct destructors.
2. Use alloca, but **the number of bytes must not be a compile-time constant**. This is what was messing me up before. If you replace:
void* foo = alloca(args.length);
with:
void* foo = alloca(8);
then this bug will not be triggered.
Comment #3 by clugdbug — 2010-05-18T00:18:01Z
I'm including this test case from bug 4054, so that I can close it, as it is clearly another instance of the same bug.
-------
import core.stdc.stdlib : alloca;
class A { }
void b()
{
scope a = new A;
int l;
alloca(l);
goto L1;
L1:
;
}
Comment #4 by clugdbug — 2010-05-18T00:18:41Z
*** Issue 4054 has been marked as a duplicate of this issue. ***
Comment #5 by braddr — 2012-07-22T20:00:51Z
*** Issue 4054 has been marked as a duplicate of this issue. ***
Comment #6 by clugdbug — 2013-08-28T00:19:50Z
Another test case from bug 10575 is also very simple:
---
import core.stdc.stdlib : alloca;
struct TheStruct
{
~this()
{
}
}
void bar()
{
}
void main()
{
auto s = TheStruct();
bar();
auto a = alloca(16);
}
Comment #7 by clugdbug — 2013-08-28T00:20:03Z
*** Issue 10575 has been marked as a duplicate of this issue. ***