Bug 315 – Exception handling is broken for delegates on Linux
Status
RESOLVED
Resolution
FIXED
Severity
critical
Priority
P1
Component
dmd
Product
D
Version
D1 (retired)
Platform
x86
OS
Linux
Creation time
2006-08-28T22:14:00Z
Last change time
2014-02-15T13:20:49Z
Keywords
EH, wrong-code
Assigned to
bugzilla
Creator
juanjo
Comments
Comment #0 by juanjo — 2006-08-28T22:14:13Z
There is a code generation bug on Linux that was found by Mikola Lysenko that has been present since DMD 0.150 . The link associated to this bug report has an example that shows this problem and an explanation of the problem. The following paragraph has been copied verbatim from the original report:
As of version 0.150, the offsets of the code within a delegate's function handler are not correctly calculated. All of them seem to be set relative to the address of the first delegate declared within the scope. This results in the following code breaking. The Windows version does not have this problem.
Comment #1 by juanjo — 2006-09-03T10:10:10Z
I'm attaching a copy of the original bug report to make it easy for people checking this bug:
As of version 0.150, the offsets of the code within a delegate's function
handler are not correctly calculated. All of them seem to be set relative to
the address of the first delegate declared within the scope. This results in
the following code breaking. The windows version does not have this problem.
#class Tester
#{
# this(void delegate() dg_) { dg = dg_; }
# void delegate() dg;
# void stuff() { dg(); }
#}
#
#unittest
#{
# writefln("Starting test");
#
# int a = 0;
# int b = 0;
# int c = 0;
# int d = 0;
#
# try
# {
# a++;
# throw new Exception("test1");
# a++;
# }
# catch(Exception e)
# {
# e.print;
# b++;
# }
# finally
# {
# c++;
# }
#
# writefln("initial test.");
#
# assert(a == 1);
# assert(b == 1);
# assert(c == 1);
#
# writefln("pass");
#
# Tester t = new Tester(
# delegate void()
# {
# try
# {
# a++;
# throw new Exception("test2");
# a++;
# }
# catch(Exception e)
# {
# b++;
# throw e;
# b++;
# }
# });
#
# try
# {
# c++;
# t.stuff();
# c++;
# }
# catch(Exception e)
# {
# d++;
# e.print;
# }
#
# assert(a == 2);
# assert(b == 2);
# assert(c == 2);
# assert(d == 1);
#
#
# int q0 = 0;
# int q1 = 0;
# int q2 = 0;
# int q3 = 0;
#
# Tester t2 = new Tester(
# delegate void()
# {
# try
# {
# q0++;
# throw new Exception("test3");
# q0++;
# }
# catch(Exception e)
# {
# writefln("Never called.");
# q1++;
# throw e;
# q1++;
# }
# });
#
# try
# {
# q2++;
# t2.stuff();
# q2++;
# }
# catch(Exception e)
# {
# q3++;
# e.print();
# }
#
# assert(q0 == 1);
# assert(q1 == 1);
# assert(q2 == 1);
# assert(q3 == 1);
#
# writefln("Passed!");
#}
The catch block in the second delegate never gets invoked. On a Linux machine.
My output is as follows:
Starting test
test1
initial test.
pass
test2
test3
Error: AssertError Failure test(117)
While on windows, it passes with:
Starting test
test1
initial test.
pass
test2
Never called.
test3
Passed!
-Mik
Comment #2 by shro8822 — 2006-09-25T11:51:06Z
another case
<code>
import std.stdio;
void main()
{
{
scope(exit) writef("a\n");
}
scope(exit) writef("b\n");
}
<code>
output:
a
b
b
Comment #3 by thomas-dloop — 2006-09-29T03:20:40Z
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
[email protected] schrieb am 2006-09-25:
> http://d.puremagic.com/issues/show_bug.cgi?id=315
> another case
>
><code>
> import std.stdio;
>
> void main()
> {
> {
> scope(exit) writef("a\n");
> }
>
> scope(exit) writef("b\n");
> }
><code>
>
> output:
>
> a
> b
> b
Added to DStress as
http://dstress.kuehne.cn/run/s/scope_15_A.d
Thomas
-----BEGIN PGP SIGNATURE-----
iD8DBQFFHOBWLK5blCcjpWoRAixTAJ9MvZnBso4t7IPuLMlhFM6Ngrs0yACggj3y
myqAYD8Shd12YShVf/PYt/s=
=CUfw
-----END PGP SIGNATURE-----