LCOV - code coverage report
Current view: top level - debug - stacktrace.cpp (source / functions) Hit Total Coverage
Test: CoherentDB code coverage Lines: 0 26 0.0 %
Date: 2011-02-13 Functions: 0 3 0.0 %

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2007-2008 Aleksey Cheusov <vle@gmx.net>
       3             :  *
       4             :  * Permission is hereby granted, free of charge, to any person obtaining
       5             :  * a copy of this software and associated documentation files (the
       6             :  * "Software"), to deal in the Software without restriction, including
       7             :  * without limitation the rights to use, copy, modify, merge, publish,
       8             :  * distribute, sublicense, and/or sell copies of the Software, and to
       9             :  * permit persons to whom the Software is furnished to do so, subject to
      10             :  * the following conditions:
      11             :  *
      12             :  * The above copyright notice and this permission notice shall be
      13             :  * included in all copies or substantial portions of the Software.
      14             :  *
      15             :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
      16             :  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
      17             :  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
      18             :  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
      19             :  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
      20             :  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
      21             :  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
      22             :  */
      23             : 
      24             : /*
      25             :  * Modifications by Marek Dopiera
      26             :  */
      27             : 
      28             : #include <sstream>
      29             : #include <vector>
      30             : 
      31             : #include <dlfcn.h>
      32             : #include <pthread.h>
      33             : 
      34             : #include <config/cmake_config.h>
      35             : #include <debug/stacktrace.h>
      36             : 
      37             : namespace coherent {
      38             : namespace debug {
      39             : 
      40             : static pthread_mutex_t stacktrace_mutex = PTHREAD_MUTEX_INITIALIZER;
      41             : 
      42             : #if defined(HAVE_EXECINFO_H) && defined(HAVE_BACKTRACE)
      43             : #include <execinfo.h>
      44             : 
      45             : /* GNU libc ? */
      46           0 : static int stacktrace_internal (void **buffer, int size)
      47             : {
      48           0 :         return backtrace(buffer, size);
      49             : }
      50             : 
      51             : #else
      52             : /* !HAVE_HEADER_EXECINFO_H (probably NetBSD/FreeBSD/Solaris etc.) */
      53             : 
      54             : #include <string.h>
      55             : #include <signal.h>
      56             : #include <setjmp.h>
      57             : 
      58             : static struct sigaction sigsegv_orig_handler;
      59             : static struct sigaction  sigbus_orig_handler;
      60             : 
      61             : static jmp_buf jmpbuf;
      62             : 
      63             : static void handler_sigfatal (int dummy)
      64             : {
      65             :         longjmp (jmpbuf,1);
      66             : }
      67             : 
      68             : static void set_sigfatal_handlers (void)
      69             : {
      70             :         struct sigaction sa;
      71             : 
      72             :         sa.sa_handler = handler_sigfatal;
      73             :         sigemptyset (&sa.sa_mask);
      74             :         sa.sa_flags = 0;
      75             : 
      76             :         sigaction (SIGSEGV, &sa, &sigsegv_orig_handler);
      77             :         sigaction (SIGBUS,  &sa,  &sigbus_orig_handler);
      78             : }
      79             : 
      80             : static void restore_sigfatal_handlers (void)
      81             : {
      82             :         sigaction (SIGSEGV, &sigsegv_orig_handler, NULL);
      83             :         sigaction (SIGBUS,  &sigbus_orig_handler, NULL);
      84             : }
      85             : 
      86             : #define one_return_address(x)                  \
      87             :                 if (x >= size) break;                  \
      88             :                 tb [x] = __builtin_return_address (x); \
      89             :                 frame  = __builtin_frame_address (x); \
      90             :                 if (!tb [x] || !frame){\
      91             :                         tb [x] = 0; \
      92             :                         break;\
      93             :                 }
      94             : 
      95             : int stacktrace_internal (void **tb, int size)
      96             : {
      97             :         int i  = 0;
      98             :         void* frame = NULL;
      99             : 
     100             :         for (i=0; i < size; ++i){
     101             :                 tb [i] = 0;
     102             :         }
     103             : 
     104             :         set_sigfatal_handlers ();
     105             : 
     106             :         if (!setjmp (jmpbuf)){
     107             :                 while (1){
     108             :                         one_return_address(0);
     109             :                         one_return_address(1);
     110             :                         one_return_address(2);
     111             :                         one_return_address(3);
     112             :                         one_return_address(4);
     113             :                         one_return_address(5);
     114             :                         one_return_address(6);
     115             :                         one_return_address(7);
     116             :                         one_return_address(8);
     117             :                         one_return_address(9);
     118             :                         one_return_address(10);
     119             :                         one_return_address(11);
     120             :                         one_return_address(12);
     121             :                         one_return_address(13);
     122             :                         one_return_address(14);
     123             :                         one_return_address(15);
     124             :                         one_return_address(16);
     125             :                         one_return_address(17);
     126             :                         one_return_address(18);
     127             :                         one_return_address(19);
     128             :                         one_return_address(20);
     129             :                         one_return_address(21);
     130             :                         one_return_address(22);
     131             :                         one_return_address(23);
     132             :                         one_return_address(24);
     133             :                         one_return_address(25);
     134             :                         one_return_address(26);
     135             :                         one_return_address(27);
     136             :                         one_return_address(28);
     137             :                         one_return_address(29);
     138             :                         one_return_address(30);
     139             :                         one_return_address(31);
     140             :                         one_return_address(32);
     141             :                         one_return_address(33);
     142             :                         one_return_address(34);
     143             :                         one_return_address(35);
     144             :                         one_return_address(36);
     145             :                         one_return_address(37);
     146             :                         one_return_address(38);
     147             :                         one_return_address(39);
     148             :                 }
     149             : 
     150             :                 longjmp (jmpbuf, 2);
     151             :         }
     152             : 
     153             :         restore_sigfatal_handlers ();
     154             : 
     155             :         for (i=0; i < size; ++i){
     156             :                 if (!tb [i])
     157             :                         return i;
     158             :         }
     159             :         return size;
     160             : }
     161             : 
     162             : #endif /* HAVE_HEADER_EXECINFO_H */
     163             : 
     164             : using namespace std;
     165             : 
     166           0 : vector<string> stacktrace()
     167             : {
     168           0 :         vector<string> res;
     169             :         void *syms[40];
     170           0 :         pthread_mutex_lock(&stacktrace_mutex);
     171           0 :         int const num_syms = stacktrace_internal(syms, 40);
     172           0 :         pthread_mutex_unlock(&stacktrace_mutex);
     173           0 :         for (int i = 0; i < num_syms; ++i) {
     174             :                 Dl_info dlinfo;
     175           0 :                 int ret = dladdr(syms[i], &dlinfo);
     176           0 :                 if (ret) {
     177           0 :                         stringstream ss;
     178           0 :                         ss << dlinfo.dli_sname << " (" << syms[i] << ")";
     179           0 :                         res.push_back(ss.str());
     180             :                 } else {
     181           0 :                         stringstream ss;
     182           0 :                         ss << syms[i];
     183           0 :                         res.push_back(ss.str());
     184             :                 }
     185             :         }
     186           0 :         if (res.empty())
     187           0 :                 res.push_back("(backtrace not available)");
     188             :         return res;
     189             : }
     190             : 
     191           0 : string stacktrace_as_string()
     192             : {
     193           0 :         vector<string> const & elems = stacktrace();
     194           0 :         stringstream res;
     195           0 :         for (vector<string>::const_iterator it = elems.begin(); it != elems.end(); ++it) {
     196           0 :                 if (it != elems.begin())
     197           0 :                         res << endl;
     198           0 :                 res << *it;
     199             :         }
     200           0 :         return res.str();
     201             : }
     202             : 
     203             : } // namespace debug
     204             : } // namespace coherent

Generated by: LCOV version 1.9