Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Creating a debug log with a stacktrace on Linux
Forum Update on Tuesday, May 27th 2025

Creating a debug log with a stacktrace on Linux

Scheduled Pinned Locked Moved General and Desktop
2 Posts 1 Posters 3.0k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • N Offline
    N Offline
    Nate R.
    wrote on 25 Jun 2014, 13:30 last edited by
    #1

    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_OBJECT

    public:
    FiveWayDriver();

    public slots:
    void processFiveWayButton();

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

    private:
    QTimer *m_Timer;
    };

    #endif // FIVEWAYDRIVER_H@

    To be continued...

    1 Reply Last reply
    0
    • N Offline
      N Offline
      Nate R.
      wrote on 25 Jun 2014, 13:31 last edited by
      #2

      [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 Reply Last reply
      0

      1/2

      25 Jun 2014, 13:30

      • Login

      • Login or register to search.
      1 out of 2
      • First post
        1/2
        Last post
      0
      • Categories
      • Recent
      • Tags
      • Popular
      • Users
      • Groups
      • Search
      • Get Qt Extensions
      • Unsolved