This blog is under construction

Saturday, 2 February 2013

backtrace_symbols_fd example in C


Header file:
    execinfo.h

Synopsis:
     void backtrace_symbols_fd (void *const *buffer, int size, int fd);

Description:
     backtrace() function gives us set of backtrace symbols(set of addresses).  Those addresses can be translated to set of strings and write those strings to the given file descriptor fd using backtrace_symbols_fd() function.  Argument buffer indicates the set of address(backtrace symbols) from backtrace() and size indicates the number of entries in the array.  And this function does not use malloc.


backtrace_symbols_fd function C example:



  #include<stdio.h>
  #include<execinfo.h>
  #include<stdlib.h>

  FILE *fp;
  void func5() {
        void *array[12];
        int size, i, fd;
        char **str;
        fp = fopen("./backtrace_info.txt", "a");
        fd = fileno(fp);
        fseek(fp, 0, SEEK_END);
        size = backtrace(array, 12);
        printf("Backtrace:\n");
        for (i = 0; i < size; i++) {
                printf("0x%08x\n", (int)array[i]); // printing symbols on output screen
        }

        /* converts address to string and writes the o/p to a file */
        backtrace_symbols_fd(array, size, fd);
        printf("No of level in backtrace:%d\n", size);
  }

  void func4() {
        func5();
  }

  void func3() {
        func4();
  }

  void func2() {
        func3();
  }

  void func1() {
        func2();
  }


  int main() {
        func1();
        return 0;
  }



  Output:

  jp@jp-VirtualBox:$ ls
  backtrace.c  backtrace_symbols.c  backtrace_symbols_fd.c
  jp@jp-VirtualBox:$ gcc -rdynamic backtrace_symbols_fd.c 
  jp@jp-VirtualBox:$ ./a.out
  Backtrace:
  0x080487d5
  0x0804884d
  0x0804885a
  0x08048867
  0x08048874
  0x08048881
  0x0015fce7
  0x080486e1
  No of level in backtrace:8
  jp@jp-VirtualBox:$ ls
  backtrace.c  backtrace_info.txt  backtrace_symbols.c  backtrace_symbols_fd.c 

  jp@jp-VirtualBox:$ cat backtrace_info.txt 
  ./a.out(func5+0x61)[0x80487d5]
  ./a.out(func4+0xb)[0x804884d]
  ./a.out(func3+0xb)[0x804885a]
  ./a.out(func2+0xb)[0x8048867]
  ./a.out(func1+0xb)[0x8048874]
  ./a.out(main+0xb)[0x8048881]
  /lib/libc.so.6(__libc_start_main+0xe7)[0x15fce7]
  ./a.out[0x80486e1]


Note:
why rdynamic option?
Eg: gcc -rdynamic backtrace_symbols.c
rdynamic is the linker option that makes the function names available to the program.  Basically, it instructs the linker to add all the symbols to the dynamic symbol table.

5 comments:

  1. Really nice post.
    What about inducing a segfault in func5(lets say we try to access an array index which is out of bound or we try to access some other restricted memory address).
    1> Can I record the segfault in fd(3rd arg of backtrace_symbols_fd()).
    2> How can I generate a core file in-case of segfault.

    How can we modify your above code to accommodate 1 & 2.

    ReplyDelete
  2. Do you need Finance? Are you looking for Finance? Are you looking for finance to enlarge your business? We help individuals and companies to obtain finance for business expanding and to setup a new business ranging any amount. Get finance at affordable interest rate of 3%, Do you need this finance for business and to clear your bills? Then send us an email now for more information contact us now via (financialserviceoffer876@gmail.com) whats-App +918929509036 Dr James Eric Finance Pvt Ltd Thanks

    ReplyDelete
  3. Very nice blog keep sharing such informative conents.

    best dot net training

    ReplyDelete
  4. Great blog, Keep writing such informative blogs, I am a regular reader of your blogs
    garden decoration items

    ReplyDelete
  5. This comment has been removed by the author.

    ReplyDelete