2013-05-30 27 views
9

Tôi đang chuyển một chương trình Linux/gcc trong các cửa sổ và thực hiện xử lý ngoại lệ chung cho cả hai. Tôi đã tự hỏi điều gì sẽ tương đương với tín hiệu SIGINT cho MinGW/gcc.Tương đương với tín hiệu "SIGINT" (posix) để bắt "CTRL + C" trong Windows/MinGW

Dưới đây là cách tôi xử lý nó dưới 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); 

Dưới Windows, điều này có vẻ như:

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); 
} 

Vấn đề của tôi là tôi không thấy bất kỳ tương đương với SIGINT trong EXCEPTION_* có sẵn cho Windows.

Làm cách nào để bắt gặp sự gián đoạn "CTRL + C" trong Windows (MinGW/gcc)?

Cảm ơn rất nhiều.

+1

Vẫn còn SIGINT, trong Microsoft CRT. SIGBREAK cho tổ hợp phím Ctrl + Break. Và không, điều này không đi qua gọi lại được cài đặt cho SetUnhandledException(). Nó không phải là unhandled :) SetConsoleCtrlHandler() để có được một cái nhìn sớm vào nó. –

Trả lời

9

Nếu bạn muốn bắt ctrl + c SetConsoleCtrlHandler có thể là những gì bạn đang tìm kiếm.

#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

Âm thanh tốt. Tôi thử xem. Cảm ơn. –

+2

Điều đó làm việc như một sự quyến rũ. Chúc mừng. Chỉ cần 'CCHandler' có thể là' ConsoleHandler' ... –

+0

Lưu ý rằng Windows gọi nó từ một luồng khác trái ngược với các trình xử lý tín hiệu đang chạy trên cùng một luồng. – OCTAGRAM

Các vấn đề liên quan