문제

저는 Visual C++ 응용 프로그램을 GCC(MingW 및 Linux에서 빌드해야 함)로 이식하는 작업을 하고 있습니다.

기존 코드는 __try { ... } __except(1) { ... } 최소한의 로깅을 수행하지 않고 거의 아무것도(메모리 부족 유형 오류가 아닌) 프로그램이 종료되도록 몇 군데 블록을 차단합니다.

GCC와 비슷한 작업을 수행하기 위한 옵션은 무엇입니까?

편집하다:Visual Studio의 /EH 옵션에 대한 포인터 덕분에 지금 필요한 것은 Linux에서 신호를 처리하는 방법에 대한 몇 가지 예입니다.내가 발견했다 이 메시지 2002년부터.

그 외에 또 어떤 신호가 SIGFPE 그리고 SIGSEVG 조심해야 해?(주로 다음에서 제기될 수 있는 것에 관심을 갖습니다. 뭔가 잘못하고 있어)

포상금 정보:나는 내 애플리케이션이 종료되기 전에 가능한 한 많은 오류 조건을 자체 기록할 수 있기를 원합니다.

어떤 신호를 받을 수 있으며 일반적으로 이후에 오류 메시지를 기록하는 것이 불가능한 신호는 무엇입니까?(기억 부족, 또 뭐야?)

코드가 최소한 Linux 및 MingW에서 동일하게 작동한다는 이식 가능한 방식으로 예외 및 (가장 중요한) 신호를 처리하려면 어떻게 해야 합니까?#ifdef는 괜찮습니다.

실패를 기록하는 래퍼 프로세스가 없는 이유는 성능상의 이유로 일부 데이터를 마지막 순간까지 디스크에 쓰는 것을 저장하므로 문제가 발생하면 이전에 데이터를 기록하기 위해 가능한 모든 시도를 하고 싶기 때문입니다. 종료.

도움이 되었습니까?

해결책

try { xxx } catch(...) { xxx } 는 이식성이 더 좋지만 많이 포착하지 못할 수도 있습니다.컴파일러 설정 및 환경에 따라 다릅니다.

기본 VC++ 설정을 사용하면 비동기(SEH) 오류가 C++ EH 인프라에 전달되지 않습니다.이를 잡으려면 대신 SEH 처리기(__try/__Exception)를 사용해야 합니다.VC++를 사용하면 C++ 오류 처리를 통해 SEH 오류를 라우팅할 수 있으며, 이를 통해 catch(...)를 사용하여 SEH 오류를 잡을 수 있습니다.여기에는 널 포인터 역참조와 같은 메모리 오류가 포함됩니다. 세부.

그러나 Linux에서는 Windows가 SEH를 사용하는 많은 오류가 신호를 통해 표시됩니다.이것들은 try/catch에 의해 포착되지 않습니다.이를 처리하려면 신호 처리기가 필요합니다.

다른 팁

MSFT의 독점 확장 대신 C++ 표준 예외를 사용하지 않는 이유는 무엇입니까?C++에는 예외 처리 개념이 있습니다.

struct my_exception_type : public logic_error {
    my_exception_type(char const* msg) : logic_error(msg) { }
};

try {
    throw my_exception_type("An error occurred");
} catch (my_exception_type& ex) {
    cerr << ex.what << endl;
}

C++에는 "catchall" 절도 있으므로 예외를 기록하려면 다음 래퍼를 사용할 수 있습니다.

try {
    // …
}
catch (...) {
}

그러나 이러한 일반 래퍼를 생성하려면 처리 코드를 모든 컴파일러에 의한 후속 스택 프레임(예외가 실제로 발생하지 않는 한 추가 비용 없이 예외 처리가 제공되는 .NET과 같은 관리 시스템과 달리).

이식성을 위해 시도해 볼 수 있는 한 가지는 대부분의 바닐라 예외에 대해 try-catch 블록을 사용한 다음 종료 핸들러(set_terminate_handler)를 설정하여 치명적인 종료 조건에 사용할 수 있는 최소한의 후크를 갖는 것입니다.atexit 또는 on_exit 핸들러와 같은 것을 추가해 볼 수도 있습니다.물론 이러한 함수를 입력할 때 실행 환경이 이상하거나 손상될 수 있으므로 정상적인 환경을 얼마나 가정하는지 주의하세요.

마지막으로, 일반적인 try-catch 쌍을 사용할 때 함수 본문에서 try 블록을 여는 대신 함수 try 블록을 사용하는 것을 고려할 수 있습니다.

int foo(int x) try {
  // body of foo
} catch (...) {
   // be careful what's done here!
}

이는 상대적으로 알려지지 않은 C++ 덩어리이며 경우에 따라 부분(소규모) 스택 손상이 발생한 경우에도 복구 기능을 제공할 수 있습니다.

마지막으로, 그렇습니다. 스스로 지속적으로 처리할 수 있는 신호 또는 중단할 수 있는 신호를 조사하고 싶을 것입니다. 처리 메커니즘을 덜 원할 경우 new 연산자의 던지지 않는 버전을 호출하는 것을 고려할 수 있습니다. , 필요한 경우 부동 소수점 예외를 생성하지 않도록 컴파일합니다(자신을 보호하기 위해 항상 FP 결과에서 isnan(.), isfinite(.)를 확인할 수 있습니다).

마지막 메모에서 주의하세요.부동 소수점 결과 분류 함수는 Linux와 Windows의 서로 다른 헤더에 있을 수 있다는 것을 확인했습니다.따라서 해당 포함을 조건화해야 할 수도 있습니다.

기분이 좋지 않다면 setjmp와 longjmp를 사용하여 모두 작성하십시오(농담입니다...).

C++ 예외 잡기 catch(...) 이미 당신을 황혼 지대에 놓았습니다.

잡히지 않은 오류를 잡으려고 노력 중입니다. catch(...) 정의되지 않은 행동 속에 당신을 정면으로 두었습니다.C++ 코드는 작동이 보장되지 않습니다.최소한의 로깅 코드로 인해 미사일이 대신 발사될 수 있습니다.

내 추천은 시도조차 하지 않는 것입니다. catch(...).의미있고 안전하게 기록할 수 있는 예외만 포착하고 나머지는 OS가 처리하도록 하세요.

근본 원인에 더해 오류 처리 코드 오류가 있는 경우 사후 디버깅이 보기 흉해집니다.

사용하기 쉽고 이식 가능하며 리소스를 거의 사용하지 않는 한 가지 방법은 빈 클래스를 잡는 것입니다.처음에는 이상하게 들릴 수도 있지만 매우 유용할 수 있습니다.

귀하의 질문에도 적용되는 다른 질문에 대해 제가 만든 예는 다음과 같습니다. 링크

또한 1개 이상의 캐치를 가질 수 있습니다.

try
{
   /* code that may throw exceptions */
}
catch (Error1 e1)
{
   /* code if Error1 is thrown */
}
catch (Error2 e2)
{
   /* code if Error2 is thrown */
}
catch (...)
{
   /* any exception that was not expected will be caught here */
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top