~thopiekar/zypper/libzypp-manual-import

« back to all changes in this revision

Viewing changes to zypp/base/Backtrace.cc

  • Committer: Thomas-Karl Pietrowski
  • Date: 2014-01-29 22:44:28 UTC
  • Revision ID: thopiekar@googlemail.com-20140129224428-gpcqnsdakby362n8
firstĀ import

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*---------------------------------------------------------------------\
 
2
|                          ____ _   __ __ ___                          |
 
3
|                         |__  / \ / / . \ . \                         |
 
4
|                           / / \ V /|  _/  _/                         |
 
5
|                          / /__ | | | | | |                           |
 
6
|                         /_____||_| |_| |_|                           |
 
7
|                                                                      |
 
8
\---------------------------------------------------------------------*/
 
9
/** \file       zypp/base/Backtrace.cc
 
10
 */
 
11
#include <execinfo.h>
 
12
#include <cxxabi.h>
 
13
 
 
14
#include <iostream>
 
15
#include "zypp/base/LogTools.h"
 
16
#include "zypp/base/String.h"
 
17
#include "zypp/base/Backtrace.h"
 
18
 
 
19
using std::endl;
 
20
 
 
21
///////////////////////////////////////////////////////////////////
 
22
namespace zypp
 
23
{
 
24
  std::ostream & dumpBacktrace( std::ostream & stream_r )
 
25
  {
 
26
    // get void*'s for all entries on the stack
 
27
    static const size_t arraySize = 50;
 
28
    void *array[arraySize];
 
29
    size_t size = ::backtrace( array, arraySize );
 
30
 
 
31
    // print out all the frames to stderr
 
32
    char ** messages = ::backtrace_symbols( array, size );
 
33
    if ( messages )
 
34
    {
 
35
      static const size_t first = 1;
 
36
      for ( size_t i = first; i < size; ++i )
 
37
      {
 
38
        char * mangled_name = 0;
 
39
        char * offset_begin = 0;
 
40
        char * offset_end = 0;
 
41
 
 
42
        // find parantheses and +address offset surrounding mangled name
 
43
        for ( char * p = messages[i]; *p; ++p )
 
44
        {
 
45
          if ( *p == '(' )
 
46
          {
 
47
            mangled_name = p;
 
48
          }
 
49
          else if ( *p == '+' )
 
50
          {
 
51
            offset_begin = p;
 
52
          }
 
53
          else if ( *p == ')' )
 
54
          {
 
55
            offset_end = p;
 
56
            break;
 
57
          }
 
58
        }
 
59
 
 
60
        if ( i > first )
 
61
          stream_r << endl;
 
62
 
 
63
        // if the line could be processed, attempt to demangle the symbol
 
64
        if ( mangled_name && offset_begin && offset_end && mangled_name < offset_begin )
 
65
        {
 
66
          *mangled_name++ = '\0';
 
67
          *offset_begin++ = '\0';
 
68
          *offset_end++ = '\0';
 
69
 
 
70
          int status;
 
71
          char * real_name = ::abi::__cxa_demangle( mangled_name, 0, 0, &status );
 
72
 
 
73
          // if demangling is successful, output the demangled function name
 
74
          if ( status == 0 )
 
75
          {
 
76
            stream_r << "[bt]: (" << i << ") " << messages[i] << " : "
 
77
            << real_name << "+" << offset_begin << offset_end;
 
78
 
 
79
          }
 
80
          // otherwise, output the mangled function name
 
81
          else
 
82
          {
 
83
            stream_r << "[bt]: (" << i << ") " << messages[i] << " : "
 
84
            << mangled_name << "+" << offset_begin << offset_end;
 
85
          }
 
86
          ::free( real_name );
 
87
        }
 
88
        else
 
89
        {
 
90
          // otherwise, print the whole line
 
91
          stream_r << "[bt]: (" << i << ") " << messages[i];
 
92
        }
 
93
      }
 
94
      ::free( messages );
 
95
    }
 
96
    return stream_r;
 
97
  }
 
98
 
 
99
} // namespace zypp
 
100
///////////////////////////////////////////////////////////////////