Line data Source code
1 : /*
2 : * Context.cxx
3 : * ers
4 : *
5 : * Created by Serguei Kolos on 26.11.05.
6 : * Copyright 2004 CERN. All rights reserved.
7 : *
8 : */
9 : #include <string.h>
10 : #include <cxxabi.h>
11 : #include <sys/types.h>
12 : #include <pwd.h>
13 : #include <unistd.h>
14 :
15 : #include <iostream>
16 : #include <sstream>
17 :
18 : #ifndef __rtems__
19 : #include <execinfo.h>
20 : #else
21 : char** backtrace_symbols (void ** , int size) {
22 : return 0;
23 : }
24 : #endif
25 :
26 : #include <ers/Context.hpp>
27 : #include <ers/Configuration.hpp>
28 :
29 : namespace
30 : {
31 : std::string
32 0 : demangle( char * mangled )
33 : {
34 0 : int status;
35 0 : char * function_begin = ::strchr( mangled, '(' );
36 0 : if ( function_begin ) {
37 0 : char * function_end = ::strchr( ++function_begin, '+' );
38 0 : if ( function_end && function_end != function_begin)
39 : {
40 0 : std::string fname(function_begin, function_end - function_begin);
41 0 : char * name = abi::__cxa_demangle( fname.c_str(), 0, 0, &status );
42 :
43 0 : if (!name) {
44 0 : return std::string( mangled );
45 : }
46 :
47 0 : std::ostringstream out;
48 0 : out << std::string(mangled, function_begin - mangled) << name << function_end;
49 0 : free( name );
50 0 : return out.str();
51 0 : }
52 : }
53 0 : return std::string( mangled );
54 : }
55 :
56 : void
57 1022 : print_function( std::ostream & out, const char * function, int verbosity )
58 : {
59 1022 : if ( verbosity )
60 : {
61 0 : out << function;
62 0 : return;
63 : }
64 :
65 1022 : const char * end = strchr( function, '(' );
66 1022 : if ( end )
67 : {
68 : const char * beg = end;
69 57222 : while ( beg > function ) {
70 56926 : if ( *(beg-1) == ' ' ) {
71 : break;
72 : }
73 56200 : --beg;
74 : }
75 1022 : out.write( beg, end - beg );
76 1022 : out << "(...)";
77 : } else {
78 0 : out << function;
79 : }
80 : }
81 : }
82 :
83 : std::vector<std::string>
84 0 : ers::Context::stack( ) const
85 : {
86 0 : std::vector<std::string> stack;
87 0 : stack.reserve( stack_size() );
88 0 : char ** symbols = backtrace_symbols( (void**)stack_symbols(), stack_size() );
89 :
90 0 : if (symbols) {
91 0 : for (int i = 1; i < stack_size(); i++) {
92 0 : stack.push_back( demangle(symbols[i]) );
93 : }
94 0 : free(symbols);
95 : }
96 :
97 0 : return stack;
98 0 : }
99 :
100 : /** Pretty printed code position
101 : * format: package_name/file_name:line_number <function_name>
102 : * \return reference to string containing format
103 : */
104 : std::string
105 1022 : ers::Context::position( int verbosity ) const
106 : {
107 1022 : std::ostringstream out;
108 1022 : print_function( out, function_name(), verbosity );
109 1022 : out << " at ";
110 :
111 1022 : const char * file = file_name();
112 1022 : if ( file[0] == '.'
113 0 : && file[1] == '.'
114 0 : && file[2] == '/' ) // file name starts with "../"
115 : {
116 0 : out << package_name() << (file + 2);
117 : } else {
118 1022 : out << file;
119 : }
120 1022 : out << ":" << line_number();
121 2044 : return out.str();
122 1022 : }
123 :
124 :
|