Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 3759904
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 19, 20262026-05-19T10:23:20+00:00 2026-05-19T10:23:20+00:00

We use stack traces in proprietary assert like macro to catch developer mistakes –

  • 0

We use stack traces in proprietary assert like macro to catch developer mistakes – when error is caught, stack trace is printed.

I find gcc’s pair backtrace()/backtrace_symbols() methods insufficient:

  1. Names are mangled
  2. No line information

1st problem can be resolved by abi::__cxa_demangle.

However 2nd problem s more tough. I found replacement for backtrace_symbols().
This is better than gcc’s backtrace_symbols(), since it can retrieve line numbers (if compiled with -g) and you don’t need to compile with -rdynamic.

Hoverer the code is GNU licenced, so IMHO I can’t use it in commercial code.

Any proposal?

P.S.

gdb is capable to print out arguments passed to functions.
Probably it’s already too much to ask for 🙂

PS 2

Similar question (thanks nobar)

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-19T10:23:21+00:00Added an answer on May 19, 2026 at 10:23 am

    Not too long ago I answered a similar question. You should take a look at the source code available on method #4, which also prints line numbers and filenames.

    • Method #4:

    A small improvement I’ve done on method #3 to print line numbers. This could be copied to work on method #2 also.

    Basically, it uses addr2line to convert addresses into file names and line numbers.

    The source code below prints line numbers for all local functions. If a function from another library is called, you might see a couple of ??:0 instead of file names.

    #include <stdio.h>
    #include <signal.h>
    #include <stdio.h>
    #include <signal.h>
    #include <execinfo.h>
    
    void bt_sighandler(int sig, struct sigcontext ctx) {
    
      void *trace[16];
      char **messages = (char **)NULL;
      int i, trace_size = 0;
    
      if (sig == SIGSEGV)
        printf("Got signal %d, faulty address is %p, "
               "from %p\n", sig, ctx.cr2, ctx.eip);
      else
        printf("Got signal %d\n", sig);
    
      trace_size = backtrace(trace, 16);
      /* overwrite sigaction with caller's address */
      trace[1] = (void *)ctx.eip;
      messages = backtrace_symbols(trace, trace_size);
      /* skip first stack frame (points here) */
      printf("[bt] Execution path:\n");
      for (i=1; i<trace_size; ++i)
      {
        printf("[bt] #%d %s\n", i, messages[i]);
    
        /* find first occurence of '(' or ' ' in message[i] and assume
         * everything before that is the file name. (Don't go beyond 0 though
         * (string terminator)*/
        size_t p = 0;
        while(messages[i][p] != '(' && messages[i][p] != ' '
                && messages[i][p] != 0)
            ++p;
    
        char syscom[256];
        sprintf(syscom,"addr2line %p -e %.*s", trace[i], p, messages[i]);
            //last parameter is the file name of the symbol
        system(syscom);
      }
    
      exit(0);
    }
    
    
    int func_a(int a, char b) {
    
      char *p = (char *)0xdeadbeef;
    
      a = a + b;
      *p = 10;  /* CRASH here!! */
    
      return 2*a;
    }
    
    
    int func_b() {
    
      int res, a = 5;
    
      res = 5 + func_a(a, 't');
    
      return res;
    }
    
    
    int main() {
    
      /* Install our signal handler */
      struct sigaction sa;
    
      sa.sa_handler = (void *)bt_sighandler;
      sigemptyset(&sa.sa_mask);
      sa.sa_flags = SA_RESTART;
    
      sigaction(SIGSEGV, &sa, NULL);
      sigaction(SIGUSR1, &sa, NULL);
      /* ... add any other signal here */
    
      /* Do something */
      printf("%d\n", func_b());
    }
    

    This code should be compiled as: gcc sighandler.c -o sighandler -rdynamic

    The program outputs:

    Got signal 11, faulty address is 0xdeadbeef, from 0x8048975
    [bt] Execution path:
    [bt] #1 ./sighandler(func_a+0x1d) [0x8048975]
    /home/karl/workspace/stacktrace/sighandler.c:44
    [bt] #2 ./sighandler(func_b+0x20) [0x804899f]
    /home/karl/workspace/stacktrace/sighandler.c:54
    [bt] #3 ./sighandler(main+0x6c) [0x8048a16]
    /home/karl/workspace/stacktrace/sighandler.c:74
    [bt] #4 /lib/tls/i686/cmov/libc.so.6(__libc_start_main+0xe6) [0x3fdbd6]
    ??:0
    [bt] #5 ./sighandler() [0x8048781]
    ??:0
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

Most websites use - (like Stack Overflow) but most PHP frameworks generate + encoded
I'm working in a large Perl application and would like to get stack traces
In C++, when is it best to use the stack? When is it best
We use a CruiseControl.Net/NAnt/Subversion stack for CI. Doing a fresh checkout for every build
In another Stack Overflow question Leon Timmermans asserted: I would advice you not to use
Some systems such as Symbian insist people to use heap instead of stack when
Is there a way to use the new keyword to allocate on the stack
Playing with log4net, I have seen the possibility to use a per-thread stack of
Sometimes we receive stack traces from our customer with wrong line numbers. It happens
We use Log4j (and Commons Logging) to log our error messages. Now we want

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.