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?