// stacktrace.c
   
#include <stdio.h>
#include <dlfcn.h>
   
void
printframeinfo(unsigned int level, void *fp, void *ra)
{
    int     ret;
    Dl_info info;
   
    // Find the image containing the given address
    ret = dladdr(ra, &info);
    printf("#%u %s%s in %s, fp = %p, pc = %p\n",
           level,
           (ret) ? info.dli_sname : "?",          // symbol name
           (ret) ? "()" : "",                     // show as a function
           (ret) ? info.dli_fname : "?", fp, ra); // shared object name
}
   
void
stacktrace()
{
    unsigned int level = 0;
    void    *saved_ra  = __builtin_return_address(0);
    void   **fp        = (void **)__builtin_frame_address(0);
    void    *saved_fp  = __builtin_frame_address(1);
   
    printframeinfo(level, saved_fp, saved_ra);
    level++;
    fp = saved_fp;
    while (fp) {
        saved_fp = *fp;
        fp = saved_fp;
        if (*fp == NULL)
            break;
        saved_ra = *(fp + 2);
        printframeinfo(level, saved_fp, saved_ra);
        level++;
    }
}
   
void f4() { stacktrace(); }
void f3() { f4(); }
void f2() { f3(); }
void f1() { f2(); }
   
int
main()
{
    f1();
    return 0;
}

haidragondeMacBook-Air:3-25 haidragon$ ls
stacktrace.c
haidragondeMacBook-Air:3-25 haidragon$ gcc -Wall -o stacktrace stacktrace.c 
haidragondeMacBook-Air:3-25 haidragon$ ls
stacktrace	stacktrace.c
haidragondeMacBook-Air:3-25 haidragon$ ./stacktrace
#0 f4() in /Users/haidragon/Downloads/singh-src/src/3-25/./stacktrace, fp = 0x7ffee087d710, pc = 0x10f382f09
#1 ? in ?, fp = 0x7ffee087d720, pc = 0x7ffee087d740
#2 ? in ?, fp = 0x7ffee087d730, pc = 0x7ffee087d760
#3 ? in ?, fp = 0x7ffee087d740, pc = 0x7ffee087d778
#4 start() in /usr/lib/system/libdyld.dylib, fp = 0x7ffee087d760, pc = 0x7fff6eb02ed9
haidragondeMacBook-Air:3-25 haidragon$ ls
stacktrace	stacktrace.c
haidragondeMacBook-Air:3-25 haidragon$ ll
-bash: ll: command not found
haidragondeMacBook-Air:3-25 haidragon$