www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - Synchronized statement causes IPF or hangs

reply Stewart Gordon <smjg_1998 yahoo.com> writes:
Using DMD 0.102, Windows 98SE.

If a statement block is synchronized but not against any object, and the 
statement is executed more than once in the course of the program, then 
an invalid page fault occurs when the program exits.

I created a few testcases, and these two both show the problem:

----------
import std.stdio;

void main() {
	for (int i = 0; i < 2; i++) {
		synchronized writefln("Running, time %d", i);
	}
}
----------
import std.stdio;

void main() {
	for (int i = 0; i < 2; i++) {
		Qwert yuiop = new Qwert;

		yuiop.print(i);
	}
}

class Qwert {
	void print(int i) {
		synchronized writefln("Running, time %d", i);
	}
}
----------
SYNC1 caused an invalid page fault in
module KERNEL32.DLL at 0167:bff8ac13.
Registers:
EAX=00000000 CS=0167 EIP=bff8ac13 EFLGS=00000246
EBX=00540000 SS=016f ESP=0064fde4 EBP=0064fdf0
ECX=00414a30 DS=016f ESI=00414a34 FS=46df
EDX=00414a30 ES=016f EDI=004149f8 GS=527e
Bytes at CS:EIP:
a1 10 9d fc bf 50 e8 96 95 fe ff ff 76 04 e8 35
Stack dump:
86a721d0 0040225a 00414a34 0064fe38 00408f28 00000000 0040986f 00540000 
851c057c 004076b6 851c057c 00000000 86a721d0 00540000 00407604 0064fe10
----------

I also tried the same within a static method, but it hung the whole 
MS-DOS window it was running in and then confused Windows, without 
generating any output.  I haven't tried running it again as yet, but 
here it is:

----------
import std.stdio;

void main() {
     for (int i = 0; i < 2; i++) {
         Qwert.print(i);
     }
}

class Qwert {
     static void print(int i) {
         synchronized writefln("Running, time %d", i);
     }
}
----------

The following, OTOH, all ran and exited without error:

----------
import std.stdio;

void main() {
     for (int i = 0; i < 2; i++) {
         Qwert.print(i);
     }
}

class Qwert {
     static synchronized void print(int i) {
         writefln("Running, time %d", i);
     }
}
----------
import std.stdio;

void main() {
     for (int i = 0; i < 2; i++) {
         Qwert yuiop = new Qwert;

         yuiop.print(i);
     }
}

class Qwert {
     void print(int i) {
         synchronized (this) writefln("Running, time %d", i);
     }
}
----------
import std.stdio;

void main() {
     for (int i = 0; i < 2; i++) {
         Qwert yuiop = new Qwert;

         yuiop.print(i);
     }
}

class Qwert {
     synchronized void print(int i) {
         writefln("Running, time %d", i);
     }
}
----------

I don't know why the 'static synchronized' method works, but I suppose 
it's a useful workaround.

I haven't yet tried it with nested functions or anything fancy like that.

Stewart.
Oct 04 2004
parent reply h3r3tic <foo bar.baz> writes:
Stewart Gordon wrote:
 Using DMD 0.102, Windows 98SE.
 
 If a statement block is synchronized but not against any object, and the 
 statement is executed more than once in the course of the program, then 
 an invalid page fault occurs when the program exits.
 
I've reported the exact same behaviour a long time ago. I was told to synchronize only against an object. If that's the case, then why do the other cases work at all ? /me confused
Oct 04 2004
parent Stewart Gordon <smjg_1998 yahoo.com> writes:
h3r3tic wrote:

 Stewart Gordon wrote:
 
 Using DMD 0.102, Windows 98SE.

 If a statement block is synchronized but not against any object, and 
 the statement is executed more than once in the course of the program, 
 then an invalid page fault occurs when the program exits.
I've reported the exact same behaviour a long time ago. I was told to synchronize only against an object.
If it were only meant to work against an object, then the form synchronized Statement wouldn't be valid syntax. As it happens, this is supposed to synchronize against Statement itself. But as Carlos has pointed out, we already seem to have another CFG shortcoming here.
 If that's the case, then why do the 
 other cases work at all ?
 /me confused
I guess that within a class, synchronized void qwert() { ... } is syntactic sugar for void qwert() { synchronized (this) { ... } } but that doesn't explain why static synchronized works, or at least seems to work. Stewart.
Oct 04 2004