61{
62 QScopedPointer<unwindstack::Regs> regs;
63 if (ucontext) {
64 regs.reset(unwindstack::Regs::CreateFromUcontext(unwindstack::Regs::CurrentArch(), ucontext));
65 } else {
66 regs.reset(unwindstack::Regs::CreateFromLocal());
67 }
68
69 unwindstack::UnwinderFromPid unwinder(256, getpid(), unwindstack::Regs::CurrentArch());
70 if (!unwinder.Init()) {
71 CRASH_LOGGER(
"Couldn't initialize the unwinder: %s\n", unwinder.LastErrorCodeString());
72 return;
73 }
74
75 unwinder.SetRegs(regs.data());
76 unwinder.Unwind();
77
78 std::vector<unwindstack::FrameData> frames = unwinder.frames();
79 if (frames.size() == 0) {
80 CRASH_LOGGER(
"Couldn't unwind: %s\t code = %d\n", unwinder.LastErrorCodeString(), unwinder.LastErrorCode());
81 return;
82 }
83
84 const int fd =
open(crashlog_path, O_CREAT | O_APPEND | O_WRONLY, S_IRUSR | S_IWUSR);
85
86 std::stringstream header;
87 header << "********************** Dumping backtrace **********************\n"
88 <<
"Signal: " << info->si_signo <<
" (" <<
get_signal_name(info->si_signo) <<
")"
89 << " (Code: " << info->si_code << ")"
90 << " Time: " << QDateTime::currentDateTimeUtc().toString().toStdString().c_str()
92 write(fd, header.str().c_str(), header.str().size());
93
94 for (size_t i = 0; i < frames.size(); ++i) {
95 std::string frame = unwinder.FormatFrame(frames[i]) + "\n";
96 write(fd, frame.c_str(), frame.size());
97 }
98 write(fd, "\n", 1);
100}
#define CRASH_LOGGER(...)
QAction * close(const QObject *recvr, const char *slot, QObject *parent)
QAction * open(const QObject *recvr, const char *slot, QObject *parent)
const char * get_signal_name(const int signo)
KRITAVERSION_EXPORT QString versionString(bool checkGit=false)