Creating a debug log with a stacktrace on Linux
-
wrote on 25 Jun 2014, 13:30 last edited by
I am trying to capture some debug information to eventually add to a log with my application but my stacktrace doesn't contain any useful information (at least that I can decipher). Can someone give me some tips?
main.cpp
@#include "FiveWayDriver.h"
const char* get_process_name_by_pid(const int pid)
{
char* name = (char*)calloc(1024,sizeof(char));
if(name){
sprintf(name, "/proc/%d/cmdline",pid);
FILE* f = fopen(name,"r");
if(f){
size_t size;
size = fread(name, sizeof(char), 1024, f);
if(size>0){
if('\n'==name[size-1])
name[size-1]='\0';
}
fclose(f);
}
}
return name;
}/** Print a demangled stack backtrace of the caller function to FILE* out. */
static inline void print_stacktrace()
{
unsigned int max_frames = 63;qDebug() << "stack trace:"; // storage array for stack trace address data void* addrlist[max_frames+1]; // retrieve current stack addresses int addrlen = backtrace(addrlist, sizeof(addrlist) / sizeof(void*)); if (addrlen == 0) { qDebug() << " <empty, possibly corrupt>"; return; } // resolve addresses into strings containing "filename(function+address)", this array must be free()-ed char** symbollist = backtrace_symbols(addrlist, addrlen); // allocate string which will be filled with the demangled function name size_t funcnamesize = 256; char* funcname = (char*)malloc(funcnamesize); // iterate over the returned symbol lines. skip the first, it is the address of this function. for (int i = 1; i < addrlen; i++) { char *begin_name = 0, *begin_offset = 0, *end_offset = 0; for (char *p = symbollist[i]; *p; ++p) { if (*p == '(') begin_name = p; else if (*p == '+') begin_offset = p; else if (*p == ')' && begin_offset) { end_offset = p; break; } } if (begin_name && begin_offset && end_offset && begin_name < begin_offset) { *begin_name++ = '\0'; *begin_offset++ = '\0'; *end_offset = '\0'; int status; char* ret = abi::__cxa_demangle(begin_name, funcname, &funcnamesize, &status); if (status == 0) { funcname = ret; // use possibly realloc()-ed string qDebug() << " " << symbollist[i] << " : " << funcname << "+" << begin_offset; } else { // demangling failed. Output function name as a C function with // no arguments. qDebug() << " " << symbollist[i] << " : " << begin_name << "+" << begin_offset; } } else { // couldn't parse the line? print the whole line. qDebug() << " " << symbollist[i]; } } free(funcname); free(symbollist);
}
void sighandler(int signum)
{
qDebug() << "Process" << get_process_name_by_pid(getpid()) << " got signal " << signum;
print_stacktrace();
signal(signum, SIG_DFL);
kill(getpid(), signum);
}int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv);// Create the five-way driver FiveWayDriver fiveWayDriver; // install our handler signal(SIGSEGV, sighandler); signal(SIGTERM, sighandler); return app.exec();
}
@FiveWayDriver.cpp
@#include "FiveWayDriver.h"
FiveWayDriver::FiveWayDriver()
{
// Setup the timer
m_Timer = new QTimer(this);
connect(m_Timer, SIGNAL(timeout()), this, SLOT(processFiveWayButton()));
m_Timer->start(1000);
}void FiveWayDriver::upButtonClicked()
{
int foo = (int)-1; // make a bad pointer
printf("%d\n", *foo); // causes segfault
}void FiveWayDriver::processFiveWayButton()
{
upButtonClicked();
}void FiveWayDriver::toggleTimer()
{
if (m_Timer->isActive())
{
m_Timer->stop();
}
else
{
m_Timer->start();
}
}@FiveWayDriver.h
@#ifndef FIVEWAYDRIVER_H
#define FIVEWAYDRIVER_H#include <QCoreApplication>
#include <execinfo.h>
#include <errno.h>
#include <cxxabi.h>#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>class FiveWayDriver : public QObject
{
Q_OBJECTpublic:
FiveWayDriver();public slots:
void processFiveWayButton();private slots:
void upButtonClicked();
void toggleTimer();private:
QTimer *m_Timer;
};#endif // FIVEWAYDRIVER_H@
To be continued...
-
wrote on 25 Jun 2014, 13:31 last edited by
[ontinued from above]
What I am expecting to see it the QTimer calling processFiveWayButton() and that function calling upButtonClicked() but this is what actually comes out of the backtrace print...
@
Process /home/nrogers/dev/projects/DbusBreadboardDesktopBuild/Debug/FiveWayDriver/FiveWayDriver got signal 11
stack trace:
/home/nrogers/dev/projects/DbusBreadboardDesktopBuild/Debug/FiveWayDriver/FiveWayDriver() [0x40303e]
/lib/x86_64-linux-gnu/libc.so.6 : + 0x364a0
/home/nrogers/dev/projects/DbusBreadboardDesktopBuild/Debug/FiveWayDriver/FiveWayDriver() [0x403933]
/home/nrogers/dev/projects/DbusBreadboardDesktopBuild/Debug/FiveWayDriver/FiveWayDriver() [0x403a18]
/home/nrogers/dev/projects/DbusBreadboardDesktopBuild/Debug/FiveWayDriver/FiveWayDriver() [0x404e19]
/home/nrogers/Qt5.2.0/5.2.0/gcc_64/lib/libQt5Core.so.5 : QMetaObject::activate(QObject*, int, int, void**) + 0x2d1
/home/nrogers/Qt5.2.0/5.2.0/gcc_64/lib/libQt5Core.so.5 : QTimer::timerEvent(QTimerEvent*) + 0x32
/home/nrogers/Qt5.2.0/5.2.0/gcc_64/lib/libQt5Core.so.5 : QObject::event(QEvent*) + 0x69
/home/nrogers/Qt5.2.0/5.2.0/gcc_64/lib/libQt5Core.so.5 : QCoreApplication::notify(QObject*, QEvent*) + 0x3d
/home/nrogers/Qt5.2.0/5.2.0/gcc_64/lib/libQt5Core.so.5 : QCoreApplication::notifyInternal(QObject*, QEvent*) + 0x84
/home/nrogers/Qt5.2.0/5.2.0/gcc_64/lib/libQt5Core.so.5 : QTimerInfoList::activateTimers() + 0x50c
/home/nrogers/Qt5.2.0/5.2.0/gcc_64/lib/libQt5Core.so.5 : + 0x2d47ed
/lib/x86_64-linux-gnu/libglib-2.0.so.0 : g_main_context_dispatch + 0x133
/lib/x86_64-linux-gnu/libglib-2.0.so.0 : + 0x48060
/lib/x86_64-linux-gnu/libglib-2.0.so.0 : g_main_context_iteration + 0x34
/home/nrogers/Qt5.2.0/5.2.0/gcc_64/lib/libQt5Core.so.5 : QEventDispatcherGlib::processEvents(QFlagsQEventLoop::ProcessEventsFlag) + 0xc3
/home/nrogers/Qt5.2.0/5.2.0/gcc_64/lib/libQt5Core.so.5 : QEventLoop::exec(QFlagsQEventLoop::ProcessEventsFlag) + 0xcb
/home/nrogers/Qt5.2.0/5.2.0/gcc_64/lib/libQt5Core.so.5 : QCoreApplication::exec() + 0x7e
/home/nrogers/dev/projects/DbusBreadboardDesktopBuild/Debug/FiveWayDriver/FiveWayDriver() [0x4030db]
/lib/x86_64-linux-gnu/libc.so.6 : __libc_start_main + 0xed
/home/nrogers/dev/projects/DbusBreadboardDesktopBuild/Debug/FiveWayDriver/FiveWayDriver() [0x4028f9]
@Is there a way to get what I want (ie. QTimer calling processFiveWayButton() and that function calling upButtonClicked())? Thanks!
Nate
1/2