길을 끄는 segfaults C
-
23-08-2019 - |
문제
내가 있는 프로그램 segfaults 에서 포인터 연산 가끔.내가 이것을 알고 발생 수는 없지만 쉽게 확인하는 시간의 여부를 볼 segfaults 지-어느 나는"사전 검색"입력된 데이터 보면 그것이 원인이됩니다 세그멘테이션(수를 결정하는 것은 불가능),또는 나 수리지 않도록 사용하여 포인터 연산하는 것이 필요한 상당히 많은 양의 작품,또는 나를 잡으려고 세그멘테이션.그래서 제 질문:
1)방법에서,C,할 수 있습니 잡을 세그멘테이션?알 가 에서는 OS 인 세그멘테이션이지만,무엇을 할 수 있는 C 프로그램에 이벤트는 segfaults 죽을 조금 더 많은 정상적으로 보 Segmentation fault
?
2)휴대용은 이?
내가 상상 이것은 매우 unportable 행동,그래서 당신은 모든 코드를 잡는 세그멘테이션,을 말해주십시오 그것은 작품이다.나 Mac OS X 에서 그러나 나는 같은 프로그램에서 작업으로 많은 플랫폼 수 있으므로 나는 무엇을 보고 내 옵션은 다음과 같습니다.
걱정하지 마십시오-기본적으로 내가 하고 싶은 인쇄 사용자에게 더 친절한 오류 메시지 및 무료로부 malloc()
ed 메모리고 다 죽습니다.나는 계획에 그냥 무시하고 모든 segfaults 나와 갈 앞서 있습니다.
해결책
이 있을 정의 신호 처리기입니다.이것은 유닉스 시스템에서 사용하는 기능 sigaction
.나는 이와 같은 코드에 페도라 64-비트 및 32 비트,그리고에 Sun Solaris.
다른 팁
론,SIGSEGV 은 트래핑,이는 POSIX,그래서 그것은 휴대용니다.
Bu 내가 관심을 보이고 싶을 처리하 세그멘테이션보다 문제를 해결하는 원인이 세그멘테이션.는 경우가 있었는지 여부를 선택하였다 OS 에서 결함 또는 내 자신의 코드,내가 알고 있는 것은 선택합니다.나는 당신이를 사냥하는 버그 수정하고,다음 작성 테스트 사례를 확인 그것은 결코 바이트다.
당신이 기능을 사용할 수 있습니다 신호 을 설치하는 새로운 신호 처리기 신호:
#include <signal.h>
void (*signal(int signum, void (*sighandler)(int)))(int);
다음과 같은 코드:
signal(SIGINT , clean_exit_on_sig);
signal(SIGABRT , clean_exit_on_sig);
signal(SIGILL , clean_exit_on_sig);
signal(SIGFPE , clean_exit_on_sig);
signal(SIGSEGV, clean_exit_on_sig); // <-- this one is for segmentation fault
signal(SIGTERM , clean_exit_on_sig);
void
clean_exit_on_sig(int sig_num)
{
printf ("\n Signal %d received",sig_num);
}
안전 조치에 신호 처리기 아 제한됩니다.안전하지 않을 부르는 라이브러리 함수에 알려지지 않은 다시 참가자는 제외됩니다,예를 들어, free()
고 printf()
.최고의 방법은 변수를 설정 및 반환,그러나 이 도움이되지 않습니다.그것은 또한 안전한 사용하는 시스템 호출을 등 write()
.
참고에서 두 가지 프로그램 예제는 주어진 여기서, backtrace_symbols_fd()
기능 안전할 것이기 때문에 그것을 사용하여 원 fd 직접지만,전화 fprintf()
이 잘못되었으로 교체해야의 사용 write()
.
나는 생각하고 있는 문제를 해결하기 위해 존재하지 않습니다.이상에서 작업하고 있다.당신은 할 수 없 잡기 세그먼트 오류로서,이러/예외가 발생드(그 생 에 의해 귀하의 프로그램을 운영 체제 어획량 it).
당신이 당신의 전략에 관한 입력:왜 불가능을 삭제요?가장 중요한 것은 크기 검사,이에 대한 C stdlib 는 적절한 기능입니다.물론 다음에 따라 달라질 수 있을 확인에 대한 올바른 입력에 관한 콘텐츠입니다.예,이것은 아마도 그 결과에서 많은 일이지만,그것은 유일한 방법으로 작성한 강력한 프로그램입니다.
편집: 나의 C 전문가,지 않았다는 것을 알고도 세그먼트 오류를 처리할 수 있으로 신호 처리기입니다.여전히,나는 그것이 바로 이동하는 방법에 대해 이유로 위에서 언급된다.
를 제공해야 합니 SIGSEGV 처리기 이 보는 꽤 괜찮은 있습니다.
신호 처리(상대적으로)휴대용 전 unix machines(이 포함되어 있 mac,linux).큰 차이점은 제외 세부사항,전달되는 인수로 신호 처리 루틴입니다.Sorrty 입니다,하지만 당신은 아마 무#ifdefs 는,인쇄하고 싶은 경우는 더 합리적인 오류 메시지(등으로 인해 어떤 주소로 잘못이 일어났)...
확인,여기에는 코드 조각을 위해 당신을 시작한다:
#include <signal.h>
/* reached when a segv occurrs */
void
SEGVFunction( SIGARGS )
{
...
}
...
main(...) {
signal(SIGSEGV, SEGVFunction); /* tell the OS, where to go in case... */
...
... do your work ...
}
귀하의 작업은:
- 이 무엇인지 확인 SIGARGS 입니다(운영체제에 따라 다르므로,사용 ifdef)
- 보 추출하는 방법을 결함-주소와에서 pc 를 제외한 정보에 sigArgs
- 인쇄 합리적인 메시지
- 구
이론적으로,당신은 심지어는 패 pc 에서 신호 처리기(한 후에 오류가 있는 지),그리고 진행합니다.그러나,전형적인 신호 처리기나 exit()또는 longjmp()으로 저장소에 주입니다.
감사
가의 예를 잡는 방법 SIGSEGV 및 인쇄 스택 추적용 glibc 의 프로그램()여기:
을 생성하는 방법 stacktrace 때 나는 C++응용 프로그램의 충돌
당신이 사용할 수 있습을 잡을하 세그멘테이션 청소,하지만 경고:당신은 수행하지 않아야합니다 너무 많은 물건에서 신호 처리기,특히 물건을 포함하는 전화를 만들기 같은 malloc().의 많은 통화를 하지 않는 신호,안전 및 종료할 수 있습니 촬영에서 자신을 발하는 경우 당신은 말하자면,전화하는 malloc 내에서 malloc.