Nếu bạn muốn biết nguyên nhân bạn có thể đăng ký sig handler NAL, một cái gì đó như:
void handler(int signum, siginfo_t *info, void *context)
{
struct sigaction action = {
.sa_handler = SIG_DFL,
.sa_sigaction = NULL,
.sa_mask = 0,
.sa_flags = 0,
.sa_restorer = NULL
};
fprintf(stderr, "Fault address: %p\n", info->si_addr);
switch (info->si_code) {
case SEGV_MAPERR:
fprintf(stderr, "Address not mapped.\n");
break;
case SEGV_ACCERR:
fprintf(stderr, "Access to this address is not allowed.\n");
break;
default:
fprintf(stderr, "Unknown reason.\n");
break;
}
/* unregister and let the default action occur */
sigaction(SIGSEGV, &action, NULL);
}
Và rồi đâu đó bạn cần phải đăng ký nó:
struct sigaction action = {
.sa_handler = NULL,
.sa_sigaction = handler,
.sa_mask = 0,
.sa_flags = SA_SIGINFO,
.sa_restorer = NULL
};
if (sigaction(SIGSEGV, &action, NULL) < 0) {
perror("sigaction");
}
Về cơ bản bạn đăng ký một dấu hiệu cho thấy vụ cháy khi SIGSEGV được phân phối, và bạn nhận được một số thông tin bổ sung, để báo giá xem man page:
The following values can be placed in si_code for a SIGSEGV signal:
SEGV_MAPERR address not mapped to object
SEGV_ACCERR invalid permissions for mapped object
những bản đồ với hai lý do cơ bản f hoặc bị lỗi seg - trang bạn truy cập không được ánh xạ hoặc bạn không được phép thực hiện bất kỳ thao tác nào bạn đã cố gắng truy cập trang đó.
Ở đây sau khi trình xử lý tín hiệu kích hoạt, nó tự hủy đăng ký và thay thế hành động mặc định. Điều này khiến cho thao tác không thực hiện lại được vì vậy nó có thể bị bắt bởi tuyến đường bình thường. Đây là hành vi bình thường của lỗi trang (tiền thân để nhận lỗi seg) để những thứ như yêu cầu phân trang hoạt động.
Bạn có thể sử dụng chức năng ['backtrace'] (http://linux.die.net/man/3/backtrace). Nhưng tôi thực sự khuyên bạn nên chạy chương trình của bạn trong một trình gỡ lỗi thay thế, nó sẽ cho phép bạn không chỉ nhìn thấy các backtrace, nhưng đi bộ lên ngăn xếp cuộc gọi và kiểm tra các biến. –
"đọc về tệp kết xuất lõi" - Tôi thực sự khuyên bạn nên sử dụng chúng. Họ đổ tất cả mọi thứ trong bộ nhớ và sau đó bạn có thể mở chúng với 'gdb' và thực thi đúng. Điều này sẽ cung cấp cho bạn cơ hội để xem chính xác những gì đã xảy ra (trừ khi bộ nhớ không bị rối loạn, nhưng đó là trường hợp khá hiếm) - xem bất kỳ biến 'giá trị, backtrace, chủ đề, vv (tất nhiên, nó sẽ được tốt đẹp để có gỡ lỗi tối đa mức độ và không tối ưu hóa cho loại hình điều tra này) –
hmm .. loại '* ptr' là' char', nhưng '" hello "' là kiểu 'char *'. bạn có lẽ nên gán một ký tự ('* ptr = 'h';') hoặc sử dụng một 'memmove()' hoặc tương tự cho ví dụ là đúng.vì nó là, nó lấy địa chỉ của hằng số chuỗi, chuyển nó thành số nguyên, chuyển nó xuống 1 byte, và sau đó segfaults gán nó cho '* ptr' – SingleNegationElimination