Throw stack trace from program kill

Hipreme msnmancini at hotmail.com
Wed Jan 19 10:54:17 UTC 2022


On Sunday, 16 January 2022 at 18:03:53 UTC, Paul Backus wrote:
> On Sunday, 16 January 2022 at 15:15:07 UTC, Hipreme wrote:
>> Is there some way to throw a stack trace when killing the 
>> program from the CTRL+C from the terminal?
>>
>> It would help a lot into debugging occasional infinity loops
>
> On POSIX, you can use the `sigaction` function to install a 
> signal handler for `SIGINT`, the signal generated by CTRL+C. To 
> terminate the program with a stack trace, simply have the 
> signal handler `throw` an `Error`.
>
> Here's an example program that demonstrates the technique:
>
> ```d
> import core.sys.posix.signal;
>
> extern(C) void handleCtrlC(int)
> {
> 	throw new Error("Killed by CTRL+C");
> }
>
> void main()
> {
> 	sigaction_t act = { sa_handler: &handleCtrlC };
> 	int errcode = sigaction(SIGINT, &act, null);
>
> 	f(); // call some functions
> }
>
> void f() { g(); }
>
> void g() { h(); }
>
> void h()
> {
> 	while (1) {} // wait for ctrl+c
> }
>
> ```
>
> Make sure to compile with the `-g` option if you want your 
> stack trace to have filenames and line numbers.

```d
import std.stdio;

version(Posix)
{
     import core.sys.posix.signal;
     extern(C) void handleCtrlC(int)
     {
         throw new Error("Killed by CTRL+C");
     }

     bool setupSignal()
     {
         sigaction_t act = {sa_handler: &handleCtrlC};
         int errCode = sigaction(SIGINT, &act, null);
         return errCode == 0;
     }
}
else version(Windows)
{
     import core.sys.windows.windef;
     import core.sys.windows.wincon;
     extern(Windows) BOOL handleCtrlC(DWORD dwType)
     {
         switch(dwType)
         {
             case CTRL_C_EVENT:
                 throw new Error("Killed by CTRL+C");
                 break;
             case CTRL_BREAK_EVENT:
                 throw new Error("Killed by break");
                 break;
             default:
                 throw new Error("Killed by unknown event");
                 break;
         }
         return TRUE;
     }
     bool setupSignal()
     {
         return 
SetConsoleCtrlHandler(cast(PHANDLER_ROUTINE)&handleCtrlC, TRUE) 
== TRUE;
     }
}
else{bool setupSignal(){return false;}}

void a(){b();}
void b(){c();}
void c(){for(;;){}}

void main(string[] args)
{
     if(!setupSignal)
         writeln("Could not setup signal, exiting.");
     else
         a();
}
```


This is my current solution. The problem is that on Windows, it 
actually has the stack trace:

```
0x76909A63 in CtrlRoutine                                         
                                                       0x76BD6359 
in BaseThreadInitThunk                                            
                                            0x76FF7B74 in 
RtlGetAppContainerNamedObjectPath                                 
                                         0x76FF7B44 in 
RtlGetAppContainerNamedObjectPath
```

If I throw that error on the Ctrl, it actually shows a message 
box:

`The exception unknown software exception (0xe04400001) occurred 
in the application at location: ...`

Maybe there is some specific formatting for throwing exceptions 
to Windows recognize it?


More information about the Digitalmars-d-learn mailing list