프로세스는 언제 SIGABRT (신호 6)를 얻습니까?


202

프로세스가 C ++에서 SIGABRT를 얻는 시나리오는 무엇입니까? 이 신호는 항상 프로세스 내에서 오거나이 신호를 한 프로세스에서 다른 프로세스로 보낼 수 있습니까?

이 신호를 보내는 프로세스를 식별하는 방법이 있습니까?


3
몇 가지 방법이 있습니다. 프로그램을 작성한 경우 가장 쉬운 방법은 SIGABRT에 대한 신호 핸들러를 등록하여 해당 정보를 인쇄하고 리턴하기 전에 해당 스트림을 플러시하는 것입니다. 두 번째로 쉬운 방법은 strace 내에서 프로그램을 실행하는 것입니다. 세 번째로 쉬운 방법은 프로그램이 충돌 할 때 코어 파일을 생성하고 코어 덤프를 통해 알아내는 것입니다.
Parthian Shot

답변:


195

abort()호출 프로세스에 SIGABRT신호를 보내면 abort()기본적으로 작동합니다.

abort()일반적으로 내부 오류 또는 심각하게 손상된 제약 조건을 감지하는 라이브러리 함수에 의해 호출됩니다. 예를 들어 내부 구조가 힙 오버플로로 인해 손상된 경우 malloc()호출 abort()합니다.


27
대부분의 경우 SIGABRT는 초기화되지 않았거나 손상된 포인터 libc를 호출 free()하여 전송되었습니다
grandrew

코드 어딘가에 생성자 내에서 순수한 가상 함수 호출을 묻 으면 SIGABRT 신호로 끝날 수 있습니까? 순수한 가상 호출이 있다는 오류 메시지가 표시되면 다음 줄에 SIGABRT 메시지가 표시되고 응용 프로그램이 충돌하거나 운영 체제에 의해 닫힙니다. 감사.
Hrvoje

2
MacOS에서는 약 1000 개의 파일 핸들을 닫지 않고 열 수있는 SIGABRT가있었습니다. 우리의 테스트는 모의 대신에 더 일반적인 독자 유형으로 파일을 추상화하여 Close()방법 이없는 것을 잊어 버렸습니다. 그래도 큰 범위를 가졌습니다. : rolleyes :
Zyl

51

SIGABRTlibc 및 기타 라이브러리에서 일반적으로 심각한 오류가 발생할 경우 프로그램을 중단하는 데 사용됩니다. 예를 들어, glibc는 SIGABRT이중 프리 또는 기타 힙 손상이 감지 된 경우를 보냅니다 .

또한 대부분의 assert구현에서는 SIGABRT어설 션이 실패한 경우를 사용합니다.

또한 SIGABRT다른 신호와 같은 다른 프로세스에서 전송할 수 있습니다. 물론 전송 프로세스는 동일한 사용자 또는 루트로 실행해야합니다.


49

kill(2)인터페이스를 사용하여 모든 프로세스에 신호를 보낼 수 있습니다 .

kill -SIGABRT 30823

30823은 dash내가 시작한 프로세스이므로 내가 죽이고 싶었던 프로세스를 쉽게 찾을 수있었습니다.

$ /bin/dash
$ Aborted

Aborted출력하는 방법을 분명히입니다 dashSIGABRT를보고합니다.

그것은 사용하는 프로세스에 직접적으로 전송 될 수있다 kill(2), 또는 프로세스를 통해 자신에게 신호를 보낼 수있는 assert(3), abort(3)또는 raise(3).


17

일반적으로 메모리 할당에 문제가있을 때 발생합니다.

내 프로그램이 음의 크기로 배열을 할당하려고 할 때 나에게 일어났다.


14

C ++의 경우 또 다른 간단한 원인이 있습니다.

std::thread::~thread{
    if((joinable ())
        std::terminate ();
}

즉 스레드의 범위가 종료되었지만 호출하는 것을 잊어 버렸습니다.

thread::join();

또는

thread::detach();

7

GNU libc는 /dev/tty호출하기 전에 몇 가지 치명적인 조건 에 관한 정보를 출력 하지만 abort()(이는 트리거 됨 SIGABRT) 프로그램을 서비스로 실행 중이거나 실제 터미널 창에서 실행하지 않으면 이러한 메시지가 없어 질 수 있습니다. tty는 메시지를 표시합니다.

/ dev / tty 대신 stderr에 쓰도록 libc를 재지 정하는 내 게시물을 참조하십시오.

/ dev / tty에서 리디렉션하는 libc 오류 메시지 잡기


4

프로세스가 SIGABRT를 가져 오는 경우 : Hrvoje는 중단을 생성하는 ctor에서 호출 된 묻힌 순수 가상에 대해 언급했으며 이에 대한 예를 다시 작성했습니다. 여기서 d가 생성 될 때, 먼저 기본 클래스 A ctor를 호출하고 내부 포인터를 자신에게 전달합니다. c는 d가 아직 구성되지 않았기 때문에 테이블이 유효한 포인터로 채워지기 전에 순수 가상 메소드를 호출합니다.

#include<iostream>
using namespace std;
class A {
public:
 A(A *pa){pa->f();}
 virtual void f()=0;
};
class D : public A {
public:
 D():A(this){}
 virtual void f() {cout<<"D::f\n";}
};
int main(){
 D d;
 A *pa = &d;
 pa->f();
 return 0;
}

컴파일 : g ++ -o aa aa.cpp

ulimit -c 무제한

실행 : ./aa

pure virtual method called
terminate called without an active exception
Aborted (core dumped)

이제 핵심 파일을 빠르게보고 SIGABRT가 실제로 호출되었는지 확인하십시오.

gdb aa core

등록 참조 :

i r
rdx            0x6      6
rsi            0x69a    1690
rdi            0x69a    1690
rip            0x7feae3170c37

체크 코드 :

장애 0x7feae3170c37

mov    $0xea,%eax  = 234  <- this is the kill syscall, sends signal to process
syscall   <-----

http://blog.rchapman.org/posts/Linux_System_Call_Table_for_x86_64/

234 sys_tgkill pid_t tgid pid_t pid int sig = 6 = SIGABRT

:)


2

필자의 경우 배열 길이와 동일한 인덱스의 배열 입력 때문이었습니다.

string x[5];

for(int i=1; i<=5; i++){

    cin>>x[i];

}

존재하지 않는 x [5]에 액세스하고 있습니다.


1

적절하게 지적한 "@sarnold"와 같이 어떤 프로세스는 다른 프로세스로 신호를 보낼 수 있으므로 한 프로세스는 SIGABORT를 다른 프로세스로 보낼 수 있으며,이 경우 수신 프로세스는 자체 조정으로 인해 발생하는지 여부를 구별 할 수 없습니다. 메모리 등, 또는 다른 사람이 "유니 캐스트 (unicastly)"상태 인 경우이를 보내십시오.

내가 일한 시스템 중 하나에는 프로세스가 심장 박동을 주어 일부 작업에서 나오는지 실제로 감지하는 교착 상태 감지기가 있습니다. 그렇지 않은 경우 프로세스가 교착 상태에 있음을 선언하고 SIGABORT를 보냅니다.

방금 질문 한 내용과 관련하여이 전망을 공유하고 싶었습니다.


0

경쟁력있는 프로그래밍 (cp) 관점 에서 대답을 드리겠습니다 .하지만 다른 도메인에도 적용됩니다.

cp를 수행하는 동안 여러 번 제약 조건이 상당히 큽니다.

예를 들면 : 나는 변수를 질문했다 N, M, Q그러한가 1 ≤ N, M, Q < 10^5.

내가 만들고 있었다 실수는 내가 크기의 배열 정수 차원을 선언 10000 x 10000에서 C++와 고투 SIGABRT거의 2 일간 Codechef에서 오류가 발생했습니다.

이제 우리가 계산하면 :

정수의 일반적인 크기 : 4 바이트

우리 배열의 세포 수 : 10000 x 10000

총 크기 (바이트) : 400000000 바이트 = 4 * 10 ^ 8 ≈ 400MB

이러한 질문에 대한 솔루션은이 크기를 감당할 수 있으므로 PC에서 항상 작동하는 것은 아닙니다.

그러나 코딩 사이트 (온라인 심사 위원)의 리소스는 몇 KB로 제한됩니다.

따라서 SIGABRT오류 및 기타 오류입니다.

결론:

이러한 질문에서, 우리는이 크기의 배열이나 벡터 또는 다른 DS를 선언해서는 안되지만, 우리의 임무는 알고리즘을 효율적으로 만들어서 (DS)없이 또는 적은 메모리로 작동하도록하는 것입니다.

추신 :이 오류에는 다른 이유가있을 수 있습니다. 위의 그들 중 하나였습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.