I am trying to capture some debug information to eventually add to a log in my 
application but my stacktrace doesn't contain the actual names of the functions 
that are being call (at least that I can see).  How can I get a stack trace 
that is more meaningful or easier to read?

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_OBJECT

public:
    FiveWayDriver();

public slots:
    void processFiveWayButton();

private slots:
    void upButtonClicked();
    void toggleTimer();

private:
    QTimer *m_Timer;
};

#endif // FIVEWAYDRIVER_H
-------------------------------------------------------------------------------------------------------


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(QFlags<QEventLoop::ProcessEventsFlag>) + 
0xc3
  /home/nrogers/Qt5.2.0/5.2.0/gcc_64/lib/libQt5Core.so.5  :  
QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>&#41; + 0xcb
  /home/nrogers/Qt5.2.0/5.2.0/gcc_64/lib/libQt5Core.so.5  :  
QCoreApplication::exec(&#41; + 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


Confidentiality Notice: The preceding e-mail message (including any 
attachments) contains information that may be confidential, protected by 
applicable legal privileges, or constitute non-public information. It is 
intended to be conveyed only to the designated recipient(s). If you are not an 
intended recipient of this message, please notify the sender by replying to 
this message and then delete it from your system. Use, dissemination, 
distribution or reproduction of this message by unintended recipients is not 
authorized and may be unlawful.
_______________________________________________
Interest mailing list
Interest@qt-project.org
http://lists.qt-project.org/mailman/listinfo/interest

Reply via email to