duktape icon indicating copy to clipboard operation
duktape copied to clipboard

Better default for MinGW setjmp/longjmp

Open svaarala opened this issue 7 years ago • 12 comments

Proposal from IRC: https://github.com/mamod/JavaScript-Duktape/pull/23/commits/91f0ef29096f19991186a27a268d92521ff7d983.

Changes:

  • [x] For Windows target, when compiling with MinGW, use _builtin{setjmp,longjmp}() to avoid a potential crash issue
  • [x] Identify Cygwin target as "cygwin", not "windows", for clarity
  • [x] Releases entry

svaarala avatar Mar 27 '17 16:03 svaarala

I guess that will work, but note that MinGW is not Cygwin. The MinGW compiler is used without and outside of the Cygwin framework and, for example, uses native filenames instead of /cygdrive/whatever.

I don't know what your configuration framework requires and how it makes the distinction between MinGW and Cygwin.

Corion avatar Mar 27 '17 16:03 Corion

It needs a way of detecting the compiler/platform from preprocessor defines (without #including files) and then whatever goes.

svaarala avatar Mar 27 '17 17:03 svaarala

@Corion Would setjmp() be a better default than __builtin_setjmp()? Is your environment missing both _setjmp() and setjmp() (that would seem odd)?

svaarala avatar Mar 27 '17 18:03 svaarala

Ok, so based on the link there's a potential crash issue in longjmp() while __builtin_longjmp() would work.

svaarala avatar Mar 27 '17 18:03 svaarala

According to Stackoverflow and a Sourceforge project collecting #defines , the following should work to identify MinGW:

#ifdef MINGW32

On 64bit, the following also is enabled:

#ifdef MINGW64

Unfortunately, I don't know much about the differences between longjmp, _longjmp, __longjmp and __builtin_longjmp - I just took a solution I found and applied it here ;)

Corion avatar Mar 29 '17 18:03 Corion

C and C++ (lang/compillers) exceptions handlers differs, i.e., https://msdn.microsoft.com/pt-br/library/yz2ez4as(v=vs.110).aspx

Lua uses a tiny approach to handle it.

NOTE: i know, duktape are written in ANSI C, but, can be compilled using c++ [same lua]

denisdemaisbr avatar Mar 30 '17 11:03 denisdemaisbr

@denisdemaisbr The easiest approach would be to rely on ANSI setjmp()/longjmp() and any platform missing it would need to supply it separately. That was pretty much the original approach but there are various reasons (performance, signal handling) to use different variants on each platform. So ultimately I can only rely on the input from people working on each platform as to what the appropriate default (that is, suitable for the majority of users on that platform) would be.

Duktape does support C++ exceptions which allows proper C++ unwinding, -DDUK_USE_CPP_EXCEPTIONS. It's not the default because C++ environments don't always have exception support enabled.

svaarala avatar Mar 30 '17 11:03 svaarala

Ok, I've updated the pull so that MinGW with POSIX (Cygwin) and Windows targets should now use __builtin_setjmp/longjmp(). I don't actively use Windows so I'm not sure if the checks are correct so if anyone can test, that would be nice. But in principle:

  • When compiling for Cygwin POSIX target, __CYGWIN__ should be set and _WIN32 etc not. Due to the ordering in platforms.yaml, this should be handled by config/platforms/platform_cygwin.h.in which has the custom setjmp/longjmp now (it's #ifdef'd for MinGW which should be pretty pointless but also doesn't harm).
  • When compiling for Windows target, __CYGWIN__ should not be set, and _WIN32 should be set. This should be handled by config/platforms/platform_windows.h.in, which now has a MinGW specific setjmp/longjmp check.

If anyone can confirm whether this is correct, that'd be nice.

svaarala avatar Dec 17 '17 22:12 svaarala

Also one thing to consider: should config/platforms/platform_cygwin.h.in define the OS string as "cygwin" rather than "windows"? If so, a POSIX/Cygwin build would identify as "mingw cygwin".

svaarala avatar Dec 17 '17 22:12 svaarala

I happened to have an unused Windows 10 VM around so I quickly checked that Cygwin GCC doesn't identify as MinGW (= doesn't trigger DUK_F_MINGW) so if the setjmp() crash is confined to MinGW only, then it should only be necessary to add the MinGW check for config/platforms/platform_windows.h.in.

I've updated the diff to reflect this; config/platforms/platform_cygwin.h.in uses _setjmp()/_longjmp() as before, and now sets the OS string to "cygwin" and not "windows".

svaarala avatar Dec 18 '17 03:12 svaarala

So, as things stand now this pull should only affect Win32 + MinGW w.r.t. setjmp/longjmp. It'd be great if @Corion or @mamod could confirm that the pull works in practice for that combination - I'll merge once there is some confirmation of this.

svaarala avatar Dec 18 '17 03:12 svaarala

@svaarala I've been checking this yesterday and I came to a conclusion that this may happened because of a bad design from my side, or maybe perl itself :P

I've been compiling Duktape along side with perl headers, perl redefines setjmp # define setjmp PerlProc_setjmp and PerlProc_setjmp is perl's own Sigsetjmp implementation.

This is already confusing to me so I think this exact case is a major header pollution, separate the build process and linking duktape fixed the problem, at least for me, I'll check with @Corion and I'll try to test duktape compiling under MingW, I'll be commenting here if I find anything.

mamod avatar Dec 19 '17 13:12 mamod