2013-05-30 18 views
9

我正在windows下移植Linux/gcc程序,併爲兩者實現了常見的異常處理。我想知道MinGW/gcc的信號相當於SIGINT相當於用於在Windows下捕獲「CTRL + C」的「SIGINT」(posix)信號/ MinGW

這是我如何處理它在Linux下:

static void handler(int sig) 
{ 
    // Catch exceptions 
    switch(sig) 
    { 
    case SIGABRT: 
     fputs("Caught SIGABRT: usually caused by an abort() or assert()\n", stderr); 
     break; 
    case SIGFPE: 
     fputs("Caught SIGFPE: arithmetic exception, such as divide by zero\n", 
       stderr); 
     break; 
    case SIGILL: 
     fputs("Caught SIGILL: illegal instruction\n", stderr); 
     break; 
    case SIGINT: 
     fputs("Caught SIGINT: interactive attention signal, probably a ctrl+c\n", 
       stderr); 
     break; 
    case SIGSEGV: 
     fputs("Caught SIGSEGV: segfault\n", stderr); 
     break; 
    case SIGTERM: 
    default: 
     fputs("Caught SIGTERM: a termination request was sent to the program\n", 
       stderr); 
     break; 
    } 

    // Ctrl+C interrupt => No backtrace 
    if (sig != (int)SIGINT) 
    { 
     fprintf(stderr, "Error: signal %d:\n", sig); 
     posix_print_stack_trace(); 
    } 
    exit(sig); 

} 

signal(SIGABRT, handler); 
signal(SIGFPE, handler); 
signal(SIGILL, handler); 
signal(SIGINT, handler); 
signal(SIGSEGV, handler); 
signal(SIGTERM, handler); 

在Windows下,這看起來像:

static LONG WINAPI windows_exception_handler(EXCEPTION_POINTERS * ExceptionInfo) 
{ 
    switch(ExceptionInfo->ExceptionRecord->ExceptionCode) 
    { 
    case EXCEPTION_ACCESS_VIOLATION: 
     fputs("Error: EXCEPTION_ACCESS_VIOLATION\n", stderr); 
     break; 
    case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: 
     fputs("Error: EXCEPTION_ARRAY_BOUNDS_EXCEEDED\n", stderr); 
     break; 
    case EXCEPTION_BREAKPOINT: 
     fputs("Error: EXCEPTION_BREAKPOINT\n", stderr); 
     break; 

    ... 
    } 
} 

if (EXCEPTION_STACK_OVERFLOW != ExceptionInfo->ExceptionRecord->ExceptionCode) 
{ 
    windows_print_stacktrace(ExceptionInfo->ContextRecord); 
} 

我的問題是,我沒有看到任何SIGINT相當於在EXCEPTION_*適用於Windows。如何在Windows(MinGW/gcc)下捕獲「CTRL + C」中斷?

非常感謝。

+1

無論如何它仍然是SIGINT。 SIGBREAK用於Ctrl + Break按鍵。不,這不會通過爲SetUnhandledException()安裝的回調。它不是未處理的:) SetConsoleCtrlHandler()以便及早查看它。 –

回答

9

如果你想趕ctrl + c SetConsoleCtrlHandler可能是你在找什麼。

#define WIN32_LEAN_AND_MEAN 
#include <windows.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <signal.h> 

BOOL WINAPI ConsoleHandler(DWORD); 

int main(int argc, char *argv[]) 
{ 
    if (!SetConsoleCtrlHandler((PHANDLER_ROUTINE)ConsoleHandler,TRUE)) { 
     fprintf(stderr, "Unable to install handler!\n"); 
     return EXIT_FAILURE; 
    } 

    for (;;) 
     ; /* Null body. */ 

    return EXIT_SUCCESS; 
} 

BOOL WINAPI ConsoleHandler(DWORD dwType) 
{ 
    switch(dwType) { 
    case CTRL_C_EVENT: 
     printf("ctrl-c\n"); 
     break; 
    case CTRL_BREAK_EVENT: 
     printf("break\n"); 
     break; 
    default: 
     printf("Some other event\n"); 
    } 
    return TRUE; 
} 
+0

聽起來不錯。我試試看。謝謝。 –

+2

這就像一個魅力。乾杯。只是'CCHandler'應該是'ConsoleHandler' ... –

+0

請注意,Windows從另一個線程調用它,而不是在同一個線程上運行的信號處理程序。 – OCTAGRAM