문제

는 경우 어떤 기적은 세그멘테이션에서 발생하는 우리 산의 샘을 찾아가 직접 시음하길 권유를 잡으려면 SIGSEGV 고 사용자가(가능한 GUI 를 클라이언트)으로 단일 코드를 반환하는 심각한 문제가 발생했습니다.동시에 나는 정보를 표시하는 명령줄에 표시되는 신호가 잡혔다.

오늘 우리의 신호 처리기는 다음과 같습니다:

void catchSignal (int reason) {
  std :: cerr << "Caught a signal: " << reason << std::endl;
  exit (1);
}

를 들을 수 있었던 공포와,위로 읽었에서 이 스레드 그것이 악화 비 함수 재진입에서 신호 처리기입니다.

이 있 휴대용하는 방법을 처리합 신호 및 정보를 제공하는 사용자가?

편집: 또는 적어도 내에서 휴대용 POSIX framework?

도움이 되었습니까?

해결책

테이블 목록 모두 함수는 POSIX 보장하는 비동기-신호-안전하고 너무라고 할 수 있습에서 신호 처리기입니다.

를 사용하여 쓰기'명령에서 이 테이블은 다음과 같은 상대적으로"못생긴"솔루션 희망이 될 것이:

#include <csignal>

#ifdef _WINDOWS_
#define _exit _Exit
#else
#include <unistd.h>
#endif

#define PRINT_SIGNAL(X) case X: \
          write (STDERR_FILENO, #X ")\n" , sizeof(#X ")\n")-1); \
          break;

void catchSignal (int reason) {
  char s[] = "Caught signal: (";
  write (STDERR_FILENO, s, sizeof(s) - 1);
  switch (reason)
  {
    // These are the handlers that we catch
    PRINT_SIGNAL(SIGUSR1);
    PRINT_SIGNAL(SIGHUP);
    PRINT_SIGNAL(SIGINT);
    PRINT_SIGNAL(SIGQUIT);
    PRINT_SIGNAL(SIGABRT);
    PRINT_SIGNAL(SIGILL);
    PRINT_SIGNAL(SIGFPE);
    PRINT_SIGNAL(SIGBUS);
    PRINT_SIGNAL(SIGSEGV);
    PRINT_SIGNAL(SIGTERM);
  }

  _Exit (1);  // 'exit' is not async-signal-safe
}

편집: 건물이드 응용 프로그램을 시작합니다.

후 구축을 위해 노력이다,윈도우가 나타나는'STDERR_FILENO'가 정의되지 않았습니다.에서 문서를 그러나 그 값이 나타납'2'.

#include <io.h>
#define STDIO_FILENO 2

편집: 'exit'하지 않아야에서 호출되는 신호 처리기는 하나!

으로 지적하여 fizzer, 부르고,exit;정 위에서는 쇠망치에 접근을 위해 신호를 같은 HUP 및 용어입니다.이상적으로,이러한 신호는 잡은 플래그"휘발성 sig_atomic_t"형식을 사용할 수 있는 통지하는 메인 프로그램을 이해야 합니다.

다음과 같은 내용에서 나를 검색합니다.

  1. 소개 Unix 신호를 프로그래밍
  2. 확장 전통 신호

다른 팁

FWIW,2 이 표준오류에 윈도우에도,그러나 당신이 필요 해요 일부는 조건 컴파일하기 때문에 그들의 작성()를 호출 _write 에().당신은 또한 원

#ifdef SIGUSR1 /* or whatever */

등 주위에 모두 참조하는 신호를 보장되지는 않에 의해 정의 될 C 표준입니다.

또한 위에서 언급한 바와 같이,당신을 원하지 않을 처리하 SIGUSR1,SIGHUP,SIGINT,SIGQUIT 및 SIGTERM 은 이렇습니다.

리처드,여전히 충분하지 않은 업 의견,그래서 새로운 해답을 것입니다.이들은 비동기식 신호;당신은 아이디어가 있지 않을 때 그들이 배달되는,그래서 아마도 당신은 라이브러리 코드를 완료하는 데 필요한시 일치한다.이러한 신호를 위한 신호 처리기를 그러므로 반환해야한다.를 호출하는 경우 exit(),라이브러리는 것입니다 몇 가지 작업을 수행 post-main()호출하는 등 기록과 함께 atexit()하고 청소하는 표준 스트림이 있습니다.이 처리에 실패할 수 있는 경우,말,당신의 신에 도착하는 표준 라이브러리 I/O 기능입니다.따라서 C90 을 허용하지 않는 전화 종료를().나는 지금 보는 C99 이완 요구 사항을 제공하여 새로운 기능 exit;정()에 stdlib.h.Exit;정()하여도 안전에서 호출 처리기 위한 비동기식 신호입니다.Exit;정()호출하지 않습니다 atexit()함수와 생략할 수 있습 청소 스트림 표준에 구현 판단하여 결정할 수 있습니다.

을 bk1e(주석이 표시까지) 는 사실 SIGSEGV 는 동기입니다 왜 당신이 사용할 수 없는 함수할 수 있도록 설계되어 있지 않습의 재진입.어떤 경우는 기능에 추락이었을 들고 잠금,그리고 함수 호출에 신호 처리기하려고 동일하게 취득합니다.

이것은 가능성이 있지만,그것은'는 사실 SIGSEGV 동기'는 문제입니다.전화 비 함수 재진입에서 핸들러는 훨씬 더 비동기식 신호를위한 두 가지 이유:

  • 비동기식 신호 처리기 (일반적으로)기대하고 돌아와 이력서 정상적인 프로그램 실행이 가능합니다.A 핸들러를 위한 동기식 신호 (일반적으로)가을 종료 어쨌든,그래서 당신은 잃지 않는 경우에 많 당신이 충돌이 발생합니다.
  • 에서는 비뚤어진 감각은,당신은 절대로 제어할 때 동기식 신호 전달됩니다-그것을 발생으로 실행한 결함이 있는 코드,및 다른 시간에.을 제어할 수 있는 권한이 없습에서 모든 경우 비동기 신호 전달됩니다.지 않는 한 OP 자체의 I/O 코드는 ifself 의 원인 결함-예를 들어,출력하는 나쁜 char*-의 오류 메시지는 합리적인 기회를 성공하고 있습니다.

쓰 런처 프로그램을 실행하는 프로그램과 보고서를 비정상적인 종료 코드를 사용합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top