www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - longjmp crashes on Windows

reply "Piotr =?UTF-8?B?UG9kc2lhZMWCeSI=?= <ppodsiadly mykolab.com> writes:
Hello,

I'm trying to use setjmp and longjmp on Windows with DMD compiler 
(version 2.064). When compiled as 64-bit application, it works, 
but 32-bit version crashes inside longjmp. What should be changed 
to get it to work?

I tried changing value of _JBLEN for x86 to some bigger number 
(like 1024), but it crashes too.

Code:

import std.stdio;

version(Windows)
{
	version(X86)
		enum _JBLEN = 64;
	else version(X86_64)
		enum _JBLEN = 256;
	else version(IA64)
		enum _JBLEN = 528;
	
	alias ubyte[_JBLEN] jmp_buf;

	extern(C)
	{
		int _setjmp(ref jmp_buf _Buf);
		void longjmp(ref jmp_buf _Buf, int _Value);
	}
	
	alias _setjmp setjmp;
}

void main()
{
	jmp_buf env;
	uint i;
	if(setjmp(env) < 3)
	{
		writeln("ping");
		longjmp(env, ++i);
	}
	writeln("done");
}

Call stack:

c:\Users\vbox\Documents\test>test.exe
ping
object.Error: Access Violation
----------------
0x00423F78 in _local_unwind
0x004214D0 in longjmp
0x0040B300 in void rt.dmain2._d_run_main(int, char**, extern (C) 
int function(char[][])*).runAll().void __lambda1()
0x0040B2D3 in void rt.dmain2._d_run_main(int, char**, extern (C) 
int function(char[][])*).runAll()
0x0040B1EB in _d_run_main
0x0040B018 in main
0x0042142D in mainCRTStartup
0x754F3677 in BaseThreadInitThunk
0x77959F42 in RtlInitializeExceptionChain
0x77959F15 in RtlInitializeExceptionChain
----------------
Nov 16 2013
parent reply "Maxim Fomin" <maxim maxim-fomin.ru> writes:
On Saturday, 16 November 2013 at 14:14:24 UTC, Piotr Podsiadły 
wrote:
 Hello,

 I'm trying to use setjmp and longjmp on Windows with DMD 
 compiler (version 2.064). When compiled as 64-bit application, 
 it works, but 32-bit version crashes inside longjmp. What 
 should be changed to get it to work?

 I tried changing value of _JBLEN for x86 to some bigger number 
 (like 1024), but it crashes too.

 Code:

 import std.stdio;

 version(Windows)
 {
 	version(X86)
 		enum _JBLEN = 64;
 	else version(X86_64)
 		enum _JBLEN = 256;
 	else version(IA64)
 		enum _JBLEN = 528;
 	
 	alias ubyte[_JBLEN] jmp_buf;

 	extern(C)
 	{
 		int _setjmp(ref jmp_buf _Buf);
 		void longjmp(ref jmp_buf _Buf, int _Value);
 	}
 	
 	alias _setjmp setjmp;
 }
What kind of problem you try to solve by manual defining system data structures? Why not use platform independent valid declarations? Why did you decide that _JBLEN is 64, 256, 528 according to version? Why did you decide that having _JBLEN bytes filled with zeros is a valid value of jmp_buf object? Why should setjmp/longjmp take buffer by reference?
 void main()
 {
 	jmp_buf env;
 	uint i;
 	if(setjmp(env) < 3)
 	{
 		writeln("ping");
 		longjmp(env, ++i);
 	}
 	writeln("done");
 }

 Call stack:

 c:\Users\vbox\Documents\test>test.exe
 ping
 object.Error: Access Violation
 ----------------
 0x00423F78 in _local_unwind
 0x004214D0 in longjmp
 0x0040B300 in void rt.dmain2._d_run_main(int, char**, extern 
 (C) int function(char[][])*).runAll().void __lambda1()
 0x0040B2D3 in void rt.dmain2._d_run_main(int, char**, extern 
 (C) int function(char[][])*).runAll()
 0x0040B1EB in _d_run_main
 0x0040B018 in main
 0x0042142D in mainCRTStartup
 0x754F3677 in BaseThreadInitThunk
 0x77959F42 in RtlInitializeExceptionChain
 0x77959F15 in RtlInitializeExceptionChain
 ----------------
Try to use proper version of setjmp/jmp_buf from druntime. By the way, why did you decide to use it in D language in a first place?
Nov 16 2013
parent reply "Piotr =?UTF-8?B?UG9kc2lhZMWCeSI=?= <ppodsiadly mykolab.com> writes:
On Saturday, 16 November 2013 at 14:41:46 UTC, Maxim Fomin wrote:
 What kind of problem you try to solve by manual defining system 
 data structures? Why not use platform independent valid 
 declarations? Why did you decide that _JBLEN is 64, 256, 528 
 according to version? Why did you decide that having _JBLEN 
 bytes filled with zeros is a valid value of jmp_buf object? Why 
 should setjmp/longjmp take buffer by reference?
I couldn't find these declarations for Windows in druntime (there is only POSIX version). Values of _JBLEN are based on constants from headers from DMC (x86 version) and Visual Studio (x86_64 and ia64). These are declarations copied from setjmp.h from DMC: #define _JBLEN 16 typedef int jmp_buf[_JBLEN]; #define __CLIB __cdecl int __CLIB _setjmp(jmp_buf); void __CLIB longjmp(jmp_buf,int); jmp_buf is initialized by the first call to setjmp, so its initial value doesn't matter. In C, arrays are alawys passed as a pointer - that's why I used ref.
 Try to use proper version of setjmp/jmp_buf from druntime.
 By the way, why did you decide to use it in D language in a 
 first place?
I'm trying to use libpng and libjpeg directly from D, without any wrappers. These libraries use longjmp to handle errors (the only alternative is to call exit() or abort()).
Nov 16 2013
parent reply "Rene Zwanenburg" <renezwanenburg gmail.com> writes:
On Saturday, 16 November 2013 at 16:22:17 UTC, Piotr Podsiadły 
wrote:
 On Saturday, 16 November 2013 at 14:41:46 UTC, Maxim Fomin 
 wrote:
 What kind of problem you try to solve by manual defining 
 system data structures? Why not use platform independent valid 
 declarations? Why did you decide that _JBLEN is 64, 256, 528 
 according to version? Why did you decide that having _JBLEN 
 bytes filled with zeros is a valid value of jmp_buf object? 
 Why should setjmp/longjmp take buffer by reference?
I couldn't find these declarations for Windows in druntime (there is only POSIX version). Values of _JBLEN are based on constants from headers from DMC (x86 version) and Visual Studio (x86_64 and ia64). These are declarations copied from setjmp.h from DMC: #define _JBLEN 16 typedef int jmp_buf[_JBLEN]; #define __CLIB __cdecl int __CLIB _setjmp(jmp_buf); void __CLIB longjmp(jmp_buf,int); jmp_buf is initialized by the first call to setjmp, so its initial value doesn't matter. In C, arrays are alawys passed as a pointer - that's why I used ref.
 Try to use proper version of setjmp/jmp_buf from druntime.
 By the way, why did you decide to use it in D language in a 
 first place?
I'm trying to use libpng and libjpeg directly from D, without any wrappers. These libraries use longjmp to handle errors (the only alternative is to call exit() or abort()).
As an alternative to those libraries, may I suggest using the DevIL binding in Derelict? It's quite easy to use: https://github.com/aldacron/Derelict3
Nov 16 2013
parent Xavier Bigand <flamaros.xavier gmail.com> writes:
Le 16/11/2013 23:26, Rene Zwanenburg a écrit :
 On Saturday, 16 November 2013 at 16:22:17 UTC, Piotr Podsiadły wrote:
 On Saturday, 16 November 2013 at 14:41:46 UTC, Maxim Fomin wrote:
 What kind of problem you try to solve by manual defining system data
 structures? Why not use platform independent valid declarations? Why
 did you decide that _JBLEN is 64, 256, 528 according to version? Why
 did you decide that having _JBLEN bytes filled with zeros is a valid
 value of jmp_buf object? Why should setjmp/longjmp take buffer by
 reference?
I couldn't find these declarations for Windows in druntime (there is only POSIX version). Values of _JBLEN are based on constants from headers from DMC (x86 version) and Visual Studio (x86_64 and ia64). These are declarations copied from setjmp.h from DMC: #define _JBLEN 16 typedef int jmp_buf[_JBLEN]; #define __CLIB __cdecl int __CLIB _setjmp(jmp_buf); void __CLIB longjmp(jmp_buf,int); jmp_buf is initialized by the first call to setjmp, so its initial value doesn't matter. In C, arrays are alawys passed as a pointer - that's why I used ref.
 Try to use proper version of setjmp/jmp_buf from druntime.
 By the way, why did you decide to use it in D language in a first place?
I'm trying to use libpng and libjpeg directly from D, without any wrappers. These libraries use longjmp to handle errors (the only alternative is to call exit() or abort()).
As an alternative to those libraries, may I suggest using the DevIL binding in Derelict? It's quite easy to use: https://github.com/aldacron/Derelict3
Piotr Podsiadły help us to remove SDL_Image from DQuick. Our goal is to avoid big dependencies, to provide a light weight and easy to build/install library. An other point is to simplify port to new platforms such as Smartphones OS, or any other embedded devices, video games consoles,... It's important for "D" to support this kind of feature correctly.
Nov 16 2013