File indexing completed on 2026-04-09 07:49:30
0001 #pragma once
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043 #include "SYSRAP_API_EXPORT.hh"
0044 #include <ostream>
0045
0046 struct SYSRAP_API SBacktrace
0047 {
0048 static void Dump();
0049 static void DumpCaller();
0050 static void DumpSummary();
0051
0052 static void Dump(std::ostream& out) ;
0053 static void DumpCaller(std::ostream& out) ;
0054 static void DumpSummary(std::ostream& out) ;
0055
0056 static bool SummaryMatch(const char* x_summary);
0057 static char* Summary();
0058
0059 static const char* CallSite(const char* call="::flat()" , bool addr=true );
0060 };
0061
0062
0063
0064
0065 #include <cstdio>
0066 #include <cstdlib>
0067 #include <string.h>
0068 #include <ostream>
0069 #include <iostream>
0070 #include <sstream>
0071
0072 #include "SStackFrame.h"
0073
0074 #include <execinfo.h>
0075 #include <errno.h>
0076
0077 inline void SBacktrace::Dump()
0078 {
0079 std::ostream& out = std::cout ;
0080 Dump(out);
0081 }
0082 inline void SBacktrace::DumpCaller()
0083 {
0084 std::ostream& out = std::cout ;
0085 DumpCaller(out);
0086 }
0087 inline void SBacktrace::DumpSummary()
0088 {
0089 std::ostream& out = std::cout ;
0090 DumpSummary(out);
0091 }
0092
0093
0094
0095
0096
0097
0098 inline void SBacktrace::Dump(std::ostream& out)
0099 {
0100 enum { max_frames = 63 };
0101 void* addrlist[max_frames+1];
0102 unsigned addrlen = backtrace( addrlist, sizeof(addrlist)/sizeof(void*));
0103
0104 out << "SBacktrace::Dump"
0105 << " addrlen " << addrlen
0106 << std::endl
0107 ;
0108
0109 if(addrlen == 0) return;
0110
0111 char** symbollist = backtrace_symbols( addrlist, addrlen );
0112
0113 bool raw = false ;
0114 if(raw) for ( unsigned i = 0 ; i < addrlen; i++ )
0115 out << symbollist[i]
0116 << " : "
0117 << addrlist[i]
0118 << std::endl
0119 ;
0120
0121 out << "SStackFrames..\n" ;
0122
0123 for ( unsigned i = 0 ; i < addrlen; i++ )
0124 {
0125 SStackFrame f(symbollist[i]) ;
0126 f.dump(out);
0127 }
0128
0129 free(symbollist);
0130 }
0131
0132
0133
0134
0135
0136
0137
0138
0139
0140
0141
0142
0143
0144
0145
0146
0147
0148 inline bool SBacktrace::SummaryMatch(const char* q_summary)
0149 {
0150 char* summary = Summary();
0151 return strstr( summary, q_summary ) != nullptr ;
0152 }
0153
0154
0155
0156
0157
0158
0159
0160
0161
0162
0163 inline char* SBacktrace::Summary()
0164 {
0165 enum { max_frames = 63 };
0166 void* addrlist[max_frames+1];
0167 unsigned addrlen = backtrace( addrlist, sizeof(addrlist)/sizeof(void*));
0168 if(addrlen == 0) return nullptr ;
0169
0170 std::stringstream ss ;
0171 char** symbollist = backtrace_symbols( addrlist, addrlen );
0172 for ( unsigned i = 0 ; i < addrlen; i++ )
0173 {
0174 SStackFrame f(symbollist[i]) ;
0175 if(f.smry) ss << f.smry << std::endl ;
0176 }
0177 free(symbollist);
0178 std::string s = ss.str();
0179 return strdup(s.c_str());
0180 }
0181
0182 inline void SBacktrace::DumpSummary(std::ostream& out)
0183 {
0184 char* summary = Summary();
0185 out << summary << std::endl ;
0186 }
0187
0188 inline void SBacktrace::DumpCaller(std::ostream& out)
0189 {
0190 const char* caller = CallSite("::flat") ;
0191 out << "SBacktrace::DumpCaller " << caller << std::endl ;
0192 }
0193
0194
0195
0196
0197
0198
0199
0200
0201
0202
0203
0204
0205
0206
0207
0208
0209
0210
0211
0212
0213
0214 inline const char* SBacktrace::CallSite(const char* call, bool addr )
0215 {
0216 const char* site = NULL ;
0217 enum { max_frames = 63 };
0218 void* addrlist[max_frames+1];
0219 unsigned addrlen = backtrace( addrlist, sizeof(addrlist)/sizeof(void*));
0220 if(addrlen == 0) return site ;
0221
0222 char** symbollist = backtrace_symbols( addrlist, addrlen );
0223 int state = -1 ;
0224 for ( unsigned i = 0 ; i < addrlen; i++ )
0225 {
0226 SStackFrame f(symbollist[i]) ;
0227
0228
0229 char* p = f.func ? strstr( f.func, call ) : NULL ;
0230 if(p) state++ ;
0231
0232 if(!p && state > -1 )
0233 {
0234 char out[256];
0235 if(addr)
0236 {
0237 snprintf( out, 256, "%16p %10s %s", addrlist[i], f.offset, f.func ) ;
0238
0239
0240
0241 }
0242 else
0243 {
0244 snprintf( out, 256, " %10s %s", f.offset, f.func ) ;
0245 }
0246 site = strdup(out) ;
0247 break ;
0248 }
0249 }
0250
0251 free(symbollist);
0252 return site ;
0253 }
0254
0255
0256