Jump to page: 1 2
Thread overview
BetterC + Windows + setjmp longjmp
Sep 17, 2018
SrMordred
Sep 18, 2018
Diederik de Groot
Sep 18, 2018
SrMordred
Sep 18, 2018
Diederik de Groot
Sep 18, 2018
Mike Parker
Sep 18, 2018
SrMordred
Sep 18, 2018
SrMordred
Sep 18, 2018
SrMordred
Sep 19, 2018
Diederik de Groot
Sep 19, 2018
Diederik de Groot
Sep 19, 2018
SrMordred
Sep 20, 2018
SrMordred
Sep 20, 2018
Diederik de Groot
May 22, 2019
Lobachevsky
May 22, 2019
kinke
September 17, 2018
Its possible to use setjmp/longjmp on windows?
Or, to be straight to my problem: its possible to continue execution after a SIGSEGV(or any other failure/signal) with betterC and windows?
September 18, 2018
On Monday, 17 September 2018 at 23:44:41 UTC, SrMordred wrote:
> Its possible to use setjmp/longjmp on windows?
> Or, to be straight to my problem: its possible to continue execution after a SIGSEGV(or any other failure/signal) with betterC and windows?

You can use core.stdc.signal
nothrow @nogc @system sigfn_t signal(SIGSEGV, sigfn_t func)
To catch the signal
With a handler signature of:
enum void function(int) nothrow @nogc @system SIG_ERR;

However continuing execution after catching a SIGSEGV is normally considered undefined (at least to POSIX).

Quote:
According to POSIX, the behavior of a process is undefined after it ignores a SIGFPE, SIGILL, or SIGSEGV signal that was not generated by kill(2) or raise(3). Integer division by zero has undefined result. On some architectures it will generate a SIGFPE signal. (Also dividing the most negative integer by -1 may generate SIGFPE.) Ignoring this signal might lead to an endless loop.
From: https://stackoverflow.com/questions/14233464/can-a-c-program-continue-execution-after-a-signal-is-handled#14233912

I am not sure if this is any different on Windows. They handle SIGSEGV differently (ie: as an exception). You would have to read the windows manual, try and test (heavily).

September 18, 2018
On Tuesday, 18 September 2018 at 00:12:35 UTC, Diederik de Groot wrote:
> On Monday, 17 September 2018 at 23:44:41 UTC, SrMordred wrote:
>> [...]
>
> You can use core.stdc.signal
> nothrow @nogc @system sigfn_t signal(SIGSEGV, sigfn_t func)
> To catch the signal
> With a handler signature of:
> enum void function(int) nothrow @nogc @system SIG_ERR;
>
> [...]

Yes, i'm using signal(SIGSEGV, sigfn_t func), it catches correctly, but end the execution after.

I find the alternatives of setjmp/longjmp and sigaction, but none are avaliable on windows afaik.
September 18, 2018
On Tuesday, 18 September 2018 at 00:24:23 UTC, SrMordred wrote:
> On Tuesday, 18 September 2018 at 00:12:35 UTC, Diederik de Groot wrote:
>> On Monday, 17 September 2018 at 23:44:41 UTC, SrMordred wrote:
>>> [...]
>>
>> You can use core.stdc.signal
>> nothrow @nogc @system sigfn_t signal(SIGSEGV, sigfn_t func)
>> To catch the signal
>> With a handler signature of:
>> enum void function(int) nothrow @nogc @system SIG_ERR;
>>
>> [...]
>
> Yes, i'm using signal(SIGSEGV, sigfn_t func), it catches correctly, but end the execution after.
>
> I find the alternatives of setjmp/longjmp and sigaction, but none are avaliable on windows afaik.

Aah ok. I think signal() and sigaction() are equivalent. Don't know about setjmp/longjmp not being available on D-windows. They are defined in core.sys.posix, so not directly available on windows per definition. They might be available under mingw.

If you think this is an oversight (as they are part of libc in general) and see a definite need, it should not be too hard to add them, i would think. You would have to ask someone with knowledge and access to windows to help you out though (A druntime PR would be welcome).
September 18, 2018
On Tuesday, 18 September 2018 at 00:24:23 UTC, SrMordred wrote:

> Yes, i'm using signal(SIGSEGV, sigfn_t func), it catches correctly, but end the execution after.
>
> I find the alternatives of setjmp/longjmp and sigaction, but none are avaliable on windows afaik.

setjmp/longjmp are available on windows (image loaders using libpng, lua, quake3, and lots of old C code make use of them):

https://msdn.microsoft.com/en-us/library/xe7acxfb.aspx?f=255&MSPPError=-2147217396
https://msdn.microsoft.com/en-us/library/3ye15wsy.aspx

You can declare the functions in your own code and they should link just fine. It would be helpful if you also submit a PR to add them to DRuntime for Windows.

As for sigaction, a quick search suggests it isn't available (and it doesn't show up in MSDN):

https://stackoverflow.com/questions/32389905/sigaction-and-porting-linux-code-to-windows
September 18, 2018
On Tuesday, 18 September 2018 at 03:09:18 UTC, Mike Parker wrote:
> On Tuesday, 18 September 2018 at 00:24:23 UTC, SrMordred wrote:
>
>> Yes, i'm using signal(SIGSEGV, sigfn_t func), it catches correctly, but end the execution after.
>>
>> I find the alternatives of setjmp/longjmp and sigaction, but none are avaliable on windows afaik.
>
> setjmp/longjmp are available on windows (image loaders using libpng, lua, quake3, and lots of old C code make use of them):
>
> https://msdn.microsoft.com/en-us/library/xe7acxfb.aspx?f=255&MSPPError=-2147217396
> https://msdn.microsoft.com/en-us/library/3ye15wsy.aspx
>
> You can declare the functions in your own code and they should link just fine. It would be helpful if you also submit a PR to add them to DRuntime for Windows.
>
> As for sigaction, a quick search suggests it isn't available (and it doesn't show up in MSDN):
>
> https://stackoverflow.com/questions/32389905/sigaction-and-porting-linux-code-to-windows

I think this may be going beyond my knowledge ;/

(Trying to follow setjmp.h, don´t have experience doing this)

enum _SIGSET_NWORDS = (1024 / (8 * (ulong.sizeof)));
struct __sigset_t
{
    ulong[_SIGSET_NWORDS] __val;
}

struct __jmp_buf_tag
{
    long[8] __jmpbuf;
    int __mask_was_saved;
    __sigset_t __saved_mask;
};

alias __jmp_buf_tag[1] jmp_buf;

extern (C) @nogc nothrow  int setjmp(ref jmp_buf) ;
extern (C) @nogc nothrow void longjmp(ref jmp_buf, int);

OK, things linked fine.
I´m trying to escape a sigfault with signal + set/longjmp:

jmp_buf buf;
extern(C) nothrow @nogc void h1(int code)  { longjmp(buf, 1); }

//main
signal(SIGSEGV, &h1);
auto x = setjmp(buf);
if(x == 1) ... (go elsewhere)
else
//forcing some sigfault

There are no compilation errors. But my program still just crashes after sigfault.

So maybe setjmp/longjmp are not working properly.
Or is not possible to escape a crash.
Or i completely misunderstood everything :P

September 18, 2018
longjmp is crashing so may be related to the struct declaration.
September 18, 2018
On Tuesday, 18 September 2018 at 20:01:48 UTC, SrMordred wrote:
> longjmp is crashing so may be related to the struct declaration.

Well just found a thread of the same problem, just that in my case with 64x crashes too.

https://forum.dlang.org/post/mmxwhdypncaeikknlpyq@forum.dlang.org
September 19, 2018
On Tuesday, 18 September 2018 at 19:45:18 UTC, SrMordred wrote:
> On Tuesday, 18 September 2018 at 03:09:18 UTC, Mike Parker wrote:
>> On Tuesday, 18 September 2018 at 00:24:23 UTC, SrMordred wrote:
>>
>>> Yes, i'm using signal(SIGSEGV, sigfn_t func), it catches correctly, but end the execution after.
>>>
>>> I find the alternatives of setjmp/longjmp and sigaction, but none are avaliable on windows afaik.
>>
>> setjmp/longjmp are available on windows (image loaders using libpng, lua, quake3, and lots of old C code make use of them):
>>
>> https://msdn.microsoft.com/en-us/library/xe7acxfb.aspx?f=255&MSPPError=-2147217396
>> https://msdn.microsoft.com/en-us/library/3ye15wsy.aspx
>>
>> You can declare the functions in your own code and they should link just fine. It would be helpful if you also submit a PR to add them to DRuntime for Windows.
>>
>> As for sigaction, a quick search suggests it isn't available (and it doesn't show up in MSDN):
>>
>> https://stackoverflow.com/questions/32389905/sigaction-and-porting-linux-code-to-windows
>
> I think this may be going beyond my knowledge ;/
>
> (Trying to follow setjmp.h, don´t have experience doing this)
>
> enum _SIGSET_NWORDS = (1024 / (8 * (ulong.sizeof)));
> struct __sigset_t
> {
>     ulong[_SIGSET_NWORDS] __val;
> }
>
> struct __jmp_buf_tag
> {
>     long[8] __jmpbuf;
>     int __mask_was_saved;
>     __sigset_t __saved_mask;
> };
>
> alias __jmp_buf_tag[1] jmp_buf;
>
> extern (C) @nogc nothrow  int setjmp(ref jmp_buf) ;
> extern (C) @nogc nothrow void longjmp(ref jmp_buf, int);

I think your definition should look more like this:
Notes:
- modulename using druntime path.
- Not 100% sure about all the sizes (lifted from winsdk10).
   - long/c_long
   - JBLEN or JBLEN+1
- Compatible with MARS setjmp.h x86 sizes
------
module core.sys.windows.setjmp;

extern (C):
@system:
nothrow:
@nogc:

private import core.sys.windows.config;
import core.stdc.signal;

version ( Windows ):
version( X86 )
{
    enum _JBLEN 16
    struct _jmp_buf { int[_JBLEN + 1] _ssjb; }
}
else version( X86_64)
{
    enum _JBLEN 16
    struct {
        long[2] part;   // c_long ?
    } float128;
    struct _jmp_buf { float128[_JBLEN] _sjb;
}
else version (AArch64)
{
    enum _JBLEN 28
    struct _jmp_buf { int[_JBLEN] _sjb; }
}
/*
else version (IA64)
{
    enum _JBLEN 33
    struct {
        long _high;
        long _low;
    } float128;
    struct _jmp_buf { float128[_JBLEN] _sjb;
}
*/
else
    static assert(0, "Not implemented for platforms other than X86, yet");

alias _jmp_buf[_JBLEN] jmp_buf;

int  setjmp(ref jmp_buf);
void longjmp(ref jmp_buf, int);
--------
Only the exact size of the jmp_buf is important (not the details about the content). We only call a function with it, we never look inside.

September 19, 2018
On Wednesday, 19 September 2018 at 11:06:23 UTC, Diederik de Groot wrote:
> On Tuesday, 18 September 2018 at 19:45:18 UTC, SrMordred wrote:

> Only the exact size of the jmp_buf is important (not the details about the content). We only call a function with it, we never look inside.

I don't own any windows machines so had to use these references (and could not test anything):
- WinSDK10: goo.gl/m9DjZt
- MARS: goo.gl/Qoc6g2
Code above does not yet cover the Mars case, but the i386 sizes should be the same.
Please Note: setjmp/longjmp should only be used in "@system + @nogc + nothrow / -betterC" code.
« First   ‹ Prev
1 2