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 9280381
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 18, 20262026-06-18T17:51:28+00:00 2026-06-18T17:51:28+00:00

The attached code works correctly if I compile it with no -O parameter. If

  • 0

The attached code works correctly if I compile it with no -O parameter. If however, I compile it with -O2, it fails to print out the intermediate functions in the traceback. Originally, I thought that everything was optimized out, so I put a call to printf into each of the routines to rule that out. It still had the same output.

Expected results: gcc -rdynamic -g test.c -o test -L/usr/local/lib -lexecinfo

./test
DEPTH=11
./test: f0 (0x40d952)
./test: f1 (0x40da0e)
./test: f2 (0x40da1e)
./test: f3 (0x40da2e)
./test: f4 (0x40da3e)
./test: f5 (0x40da4e)
./test: f6 (0x40da5e)
./test: f7 (0x40da6e)
./test: main (0x40da89)
./test: _start (0x40080e)

Unexpected results: gcc -O2 -rdynamic -g test.c -o test -L/usr/local/lib -lexecinfo

./test
DEPTH=2
./test: f0 (0x40794b)

#include <stdio.h>
#include <dlfcn.h>

#define CALLSTACK_MAXLEN 64

//
// We use this macro instead of a for loop in backtrace() because the 
// documentation says that you have to use a constant, not a variable.
//
#define BT(X) {                                                         \
        case X:                                                         \
                if (!__builtin_frame_address(X)) {                      \
                        return X;                                       \
                }                                                       \
                                                                        \
                trace[X].address = __builtin_return_address(X);         \
                break;                                                  \
}

struct call {
        const void *address;
        const char *function;
        const char *object;
};

struct call trace[CALLSTACK_MAXLEN];

int
backtrace(int depth) {
        int         i;
        Dl_info     dlinfo;

        for (i = 0; i < depth; i++) {
                switch (i) {
                        BT(  0);  
                        BT(  1);
                        BT(  2);
                        BT(  3);
                        BT(  4);
                        BT(  5);
                        BT(  6);
                        BT(  7);
                        BT(  8);
                        BT(  9);
                        BT( 10);
                        BT( 11);
                        BT( 12);
                        BT( 13);
                        BT( 14);
                        BT( 15);
                        BT( 16);
                        BT( 17);
                        BT( 18);
                        BT( 19);
                        default:  return i;
                }

                if (dladdr(trace[i].address, &dlinfo) != 0) {
                        trace[i].function = dlinfo.dli_sname;
                        trace[i].object = dlinfo.dli_fname;
                }
        }

        return i;
}

void
f0() {
        int i;
        int depth;

        depth = backtrace(CALLSTACK_MAXLEN);
        printf("DEPTH=%d\n", depth);

        for (i = 0 ; trace[i].object != NULL; i++) {
                printf("%s: %s (%p)\n", trace[i].object, trace[i].function, trace[i].address);
        }
}

void f1() { f0(); }
void f2() { f1(); }
void f3() { f2(); }
void f4() { f3(); }
void f5() { f4(); }
void f6() { f5(); }
void f7() { f6(); }

int main(int argc, char **argv) {
        f7();
        return 0;
}
  • 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-06-18T17:51:29+00:00Added an answer on June 18, 2026 at 5:51 pm

    Reason is tail-recursive optimization. Even if inlining is switched off, tail recursion changes call to jump, like

    f6:
    .LFB29:
      .cfi_startproc
      xorl  %eax, %eax
      jmp f5
    

    So you must:

    1. Exclude inlining

      void __attribute__ ((noinline)) f1() { f0(); }
      void __attribute__ ((noinline)) f2() { f1(); }
      void __attribute__ ((noinline)) f3() { f2(); }
      void __attribute__ ((noinline)) f4() { f3(); }
      void __attribute__ ((noinline)) f5() { f4(); }
      void __attribute__ ((noinline)) f6() { f5(); }
      void __attribute__ ((noinline)) f7() { f6(); }
      
    2. Compile with -fno-optimize-sibling-calls and preserve frame pointer

      gcc -O2 -rdynamic -g -o bfa bfa.c -ldl -fno-optimize-sibling-calls -fno-omit-frame-pointer

    Output is:

    $ ./bfa 
    DEPTH=10
    ./bfa: f0 (0x400f23)
    ./bfa: f1 (0x400f8b)
    ./bfa: f2 (0x400f9b)
    ./bfa: f3 (0x400fab)
    ./bfa: f4 (0x400fbb)
    ./bfa: f5 (0x400fcb)
    ./bfa: f6 (0x400fdb)
    ./bfa: f7 (0x400feb)
    ./bfa: main (0x400ffb)
    /lib/libc.so.6: __libc_start_main (0x7fdfbae51c4d)
    

    As desired.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I will keep this quick. The attached code for the most part works i
For the attached code, I get the following compile time error : exception during
Is there any way to view what functions / code are attached to any
I'm using the following code attached to a button, to attempt to open a
i am writing my bachelor thesis and there is some C++ code attached to
I'm using a tutorial plugin - http://particlebits.com/code/jquery-tutorial/ which has this code attached to the
How can I code an in-app screenshot that can then be attached to a
I have some debugging code that if executed while running with GBD attached should
I'm trying to send email with some images attached in django. Code used is
I'm having problem with datagrid view. I have attached an image with the code

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.