Bạn cần bắt đầu bằng cách bẫy SIGSEGV để thực thi mã khi bạn nhận được segv. Đây là mã posix, vì vậy một cái gì đó tương tự nên hoạt động trên android:
void abortHandler(int signum, siginfo_t* si, void* unused)
{
const char* name = NULL;
switch(signum)
{
case SIGABRT: name = "SIGABRT"; break;
case SIGSEGV: name = "SIGSEGV"; break;
case SIGBUS: name = "SIGBUS"; break;
case SIGILL: name = "SIGILL"; break;
case SIGFPE: name = "SIGFPE"; break;
case SIGPIPE: name = "SIGPIPE"; break;
}
if (name)
printf(stderr, "Caught signal %d (%s)\n", signum, name);
else
printf(stderr, "Caught signal %d\n", signum);
printStackTrace(stderr);
exit(signum);
}
void handleCrashes()
{
struct sigaction sa;
sa.sa_flags = SA_SIGINFO;
sa.sa_sigaction = abortHandler;
sigemptyset(&sa.sa_mask);
sigaction(SIGABRT, &sa, NULL);
sigaction(SIGSEGV, &sa, NULL);
sigaction(SIGBUS, &sa, NULL);
sigaction(SIGILL, &sa, NULL);
sigaction(SIGFPE, &sa, NULL);
sigaction(SIGPIPE, &sa, NULL);
}
Điều tiếp theo là gọi hàm đó để đăng ký trình xử lý tín hiệu. Bạn có thể làm điều đó như là điều đầu tiên trong chính, nhưng sau đó bạn sẽ không nhận được dấu vết ngăn xếp cho đến khi chính. Nếu bạn muốn chúng trước, bạn có thể gọi hàm này từ hàm tạo của một đối tượng chung. Nhưng không có gì đảm bảo rằng nó sẽ được gọi là constructor đầu tiên. Có nhiều cách để đảm bảo nó được gọi sớm. Ví dụ, toán tử quá tải mới - trong quá trình xây dựng gỡ lỗi - để khởi tạo lần đầu tiên các dấu vết ngăn xếp trên phân bổ đầu tiên, và sau đó gọi vào toán tử thực mới. Điều này sẽ cung cấp cho bạn các dấu vết ngăn xếp bắt đầu từ phân bổ đầu tiên.
Để in một stack trace:
void printStackTrace(unsigned int max_frames = 63)
{
void* addrlist[max_frames+1];
// retrieve current stack addresses
u32 addrlen = backtrace(addrlist, sizeof(addrlist)/sizeof(void*));
if (addrlen == 0)
{
printf(stderr, " <empty, possibly corrupt>\n");
return;
}
char** symbollist = backtrace_symbols(addrlist, addrlen);
for (u32 i = 3; i < addrlen; i++)
printf(stderr, "%s\n", symbollist[i]):
}
Bạn sẽ cần phải làm việc nhiều hơn để demangle những biểu tượng để làm cho họ có thể đọc được. thử abi :: __ cxa_demangle. Tất nhiên xây dựng với -g và liên kết với -rdynamic.
kiểm tra câu trả lời này. điều này dành riêng cho android http://stackoverflow.com/a/28858941/365229 –