September 19, 2018 Re: BetterC + Windows + setjmp longjmp | ||||
---|---|---|---|---|
| ||||
Posted in reply to Diederik de Groot | On Wednesday, 19 September 2018 at 11:12:41 UTC, Diederik de Groot wrote:
> 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.
g++ and clang give me sizeof = 256. dmc give me 64. I tried all this sizes and other, but still crashes.
|
September 20, 2018 Re: BetterC + Windows + setjmp longjmp | ||||
---|---|---|---|---|
| ||||
Posted in reply to SrMordred | Ok, after a better look at the sources I finally got it: setjmp is a macro. the true function signature is "int _setjmp(jmp_buf, void*)" the void* is the current function address which in mingw sources are capture by "__builtin_frame_address(0)". And I did´t look yet to see if Dlang have an equivalent. but calling _setjmp(jmp_buf, null); the simple examples are working :) |
September 20, 2018 Re: BetterC + Windows + setjmp longjmp | ||||
---|---|---|---|---|
| ||||
Posted in reply to SrMordred | On Thursday, 20 September 2018 at 12:11:55 UTC, SrMordred wrote: > Ok, after a better look at the sources I finally got it: > > setjmp is a macro. > the true function signature is "int _setjmp(jmp_buf, void*)" > > the void* is the current function address which in mingw sources are capture by "__builtin_frame_address(0)". > > And I did´t look yet to see if Dlang have an equivalent. > but calling _setjmp(jmp_buf, null); the simple examples are working :) Nice to see you managed to figure it all out, congrats! So it now looks something like this ?: 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, null); void longjmp(ref jmp_buf, int); } alias _setjmp setjmp; } Hopefully you will be able to merge the two examples and create a nice druntime PR out of it. The https://forum.dlang.org/post/mmxwhdypncaeikknlpyq@forum.dlang.org version does look a lot cleaner (but also a little more cryptic). Might be wise to follow the core.sys.posix.setjmp.d implementation. If available, maybe also add the sigsetjmp / siglonggmp and sigaction versions (if available on windows). Good luck ! |
May 22, 2019 Re: BetterC + Windows + setjmp longjmp | ||||
---|---|---|---|---|
| ||||
Posted in reply to Diederik de Groot | I have been experimenting with setjmp / longjmp under Windows as a way to break out of an endless loop. With my experiments, longjmp appears to silently exit the process, no stack trace, nothing. Black emptiness. I stared with the C program described in https://docs.microsoft.com/en-us/windows/console/setconsolectrlhandler and added the setjmp and longjmp code fragments. When I try this, the CtrlHandler is successfully loaded and it even beeps accordingly when cntl-C and cntl-break are pressed. Of course, the Microsoft documentation warns against using setjmp / longjump from callbacks: https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/longjmp?view=vs-2019 Here is the companion Microsoft setjmp documentation: https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/setjmp?view=vs-2019 I'm using DMD 2.084, VS 2017, not using BetterC Compiler arguments: -boundscheck=on -dw -c -gf -debug -g -m64 -wi Linker: /OUT:"C:\Users\...\Test.exe" /MANIFEST /NXCOMPAT /PDB:"C:\Users\...\Test.pdb" /DEBUG /MACHINE:X64 /INCREMENTAL /PGD:"C:\Users\...\Test.pgd" /SUBSYSTEM:CONSOLE /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /ManifestFile:"x64\Debug\Testexe.intermediate.manifest" /ERRORREPORT:PROMPT /VERBOSE:Lib /TLBID:1 Suggestions welcome. ---------------------------------------------------------------------------- // CtrlHandler.d : This file contains the 'main' function. Program execution begins and ends there. // See https://docs.microsoft.com/en-us/windows/console/setconsolectrlhandler module CtrlHandler; import core.sys.posix.setjmp; import std.conv; import core.sys.windows.windows; import std.stdio; // #include <windows.h> // #include <stdio.h> alias ubyte[1024] jmp_buf; extern(C) { int _setjmp(ref jmp_buf) nothrow; void longjmp(ref jmp_buf, int) nothrow; } alias _setjmp setjmp; public static jmp_buf buf; extern (Windows) private static int CtrlHandler(uint fdwCtrlType) nothrow { switch (fdwCtrlType) { // Handle the CTRL-C signal. case CTRL_C_EVENT: // writeln("Ctrl-C event\n\n"); Beep(750, 300); longjmp(buf, 42); break; // CTRL-CLOSE: confirm that the user wants to exit. case CTRL_CLOSE_EVENT: Beep(600, 200); // writeln("Ctrl-Close event\n\n"); longjmp(buf, 39); break; // Pass other signals to the next handler. case CTRL_BREAK_EVENT: Beep(900, 200); // writeln("Ctrl-Break event\n\n"); longjmp(buf, 13); break; case CTRL_LOGOFF_EVENT: Beep(1000, 200); // writeln("Ctrl-Logoff event\n\n"); return 0; case CTRL_SHUTDOWN_EVENT: Beep(750, 500); // writeln("Ctrl-Shutdown event\n\n"); return 0; default: return 0; } return 0; } int main(string[] args) { int sj; sj = setjmp(buf); writeln("sj = " ~ to!string(sj)); readln(); if (sj != 0) goto breakout; if (SetConsoleCtrlHandler(&CtrlHandler, 1)) { writeln("\nThe Control Handler is installed.\n"); writeln("\n -- Now try pressing Ctrl+C or Ctrl+Break, or"); writeln("\n try logging off or closing the console...\n"); writeln("\n(...waiting in a loop for events...)\n\n"); while (1) {} } else { writeln("\nERROR: Could not set control handler"); return 1; } breakout: writeln("\nSuccessfully broke out of endless loop - sj = " ~ to!string(sj)); return 0; } |
May 22, 2019 Re: BetterC + Windows + setjmp longjmp | ||||
---|---|---|---|---|
| ||||
Posted in reply to Lobachevsky | On Wednesday, 22 May 2019 at 16:37:36 UTC, Lobachevsky wrote: > I have been experimenting with setjmp / longjmp under Windows as a way to break out of an endless loop. With my experiments, longjmp appears to silently exit the process, no stack trace, nothing. Black emptiness. I don't think breaking out of a loop this way can work. The CtrlHandler is called by another thread. Quoting from https://docs.microsoft.com/en-us/windows/console/handlerroutine: > An application-defined function used with the SetConsoleCtrlHandler function. A console process uses this function to handle control signals received by the process. When the signal is received, the system creates a new thread in the process to execute the function. |
Copyright © 1999-2021 by the D Language Foundation