Một trường hợp khi quá trình lấy SIGABRT từ chính nó: Hrvoje đã đề cập đến một ảo tinh khiết bị chôn vùi được gọi là từ ctor tạo ra một hủy bỏ, tôi tái tạo một ví dụ cho việc này. Ở đây khi d được xây dựng, đầu tiên nó gọi ctor lớp cơ sở của nó là và đi vào bên trong con trỏ đến chính nó. Ctor gọi phương thức ảo thuần túy trước khi bảng được điền bằng con trỏ hợp lệ, vì d chưa được tạo.
#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;
}
biên dịch: g ++ -o aa aa.cpp
ulimit -c không giới hạn
chạy: ./aa
pure virtual method called
terminate called without an active exception
Aborted (core dumped)
bây giờ cho phép nhanh chóng xem các tập tin cốt lõi, và xác nhận SIGABRT thực sự được gọi là:
gdb aa core
thấy regs: Mã
i r
rdx 0x6 6
rsi 0x69a 1690
rdi 0x69a 1690
rip 0x7feae3170c37
kiểm tra:
disas 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
:)
Nguồn
2017-03-29 08:20:11
Có một vài cách. Cách dễ nhất, nếu bạn đã viết chương trình, là đăng ký trình xử lý tín hiệu cho SIGABRT để in ra thông tin đó và xóa luồng của nó trước khi trở về. Cách dễ nhất thứ hai là chạy chương trình trong strace. Cách dễ nhất thứ ba là đảm bảo chương trình tạo ra một tệp lõi khi nó gặp sự cố và tìm hiểu thông qua kết xuất lõi. –