프로세스가 C ++에서 SIGABRT를 얻는 시나리오는 무엇입니까? 이 신호는 항상 프로세스 내에서 오거나이 신호를 한 프로세스에서 다른 프로세스로 보낼 수 있습니까?
이 신호를 보내는 프로세스를 식별하는 방법이 있습니까?
답변
abort()호출 프로세스에 SIGABRT신호를 보내면 abort()기본적으로 작동합니다.
abort()일반적으로 내부 오류 또는 심각하게 손상된 제약 조건을 감지하는 라이브러리 함수에 의해 호출됩니다. 예를 들어 내부 구조가 힙 오버플로로 인해 손상된 경우 malloc()호출 abort()합니다.
답변
SIGABRTlibc 및 기타 라이브러리에서 일반적으로 심각한 오류가 발생할 경우 프로그램을 중단하는 데 사용됩니다. 예를 들어, glibc는 SIGABRT이중 프리 또는 기타 힙 손상이 감지 된 경우를 보냅니다 .
또한 대부분의 assert구현에서는 SIGABRT어설 션이 실패한 경우를 사용합니다.
또한 SIGABRT다른 신호와 같은 다른 프로세스에서 전송할 수 있습니다. 물론 전송 프로세스는 동일한 사용자 또는 루트로 실행해야합니다.
답변
kill(2)인터페이스를 사용하여 모든 프로세스에 신호를 보낼 수 있습니다 .
kill -SIGABRT 30823
30823은 dash내가 시작한 프로세스이므로 내가 죽이고 싶었던 프로세스를 쉽게 찾을 수있었습니다.
$ /bin/dash
$ Aborted
Aborted출력하는 방법을 분명히입니다 dashSIGABRT를보고합니다.
그것은 사용하는 프로세스에 직접적으로 전송 될 수있다 kill(2), 또는 프로세스를 통해 자신에게 신호를 보낼 수있는 assert(3), abort(3)또는 raise(3).
답변
일반적으로 메모리 할당에 문제가있을 때 발생합니다.
내 프로그램이 음의 크기로 배열을 할당하려고 할 때 나에게 일어났다.
답변
C ++의 경우 또 다른 간단한 원인이 있습니다.
std::thread::~thread{
if((joinable ())
std::terminate ();
}
즉 스레드의 범위가 종료되었지만 호출하는 것을 잊어 버렸습니다.
thread::join();
또는
thread::detach();
답변
GNU libc는 /dev/tty호출하기 전에 몇 가지 치명적인 조건 에 관한 정보를 출력 하지만 abort()(이는 트리거 됨 SIGABRT) 프로그램을 서비스로 실행 중이거나 실제 터미널 창에서 실행하지 않으면 이러한 메시지가 없어 질 수 있습니다. tty는 메시지를 표시합니다.
/ dev / tty 대신 stderr에 쓰도록 libc를 재지 정하는 내 게시물을 참조하십시오.
답변
프로세스가 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
🙂