NCBI C++ ToolKit
ncbi_stack.cpp
Go to the documentation of this file.

Go to the SVN repository for this file.

1 /* $Id: ncbi_stack.cpp 100651 2023-08-23 15:14:23Z ucko $
2  * ===========================================================================
3  *
4  * PUBLIC DOMAIN NOTICE
5  * National Center for Biotechnology Information
6  *
7  * This software/database is a "United States Government Work" under the
8  * terms of the United States Copyright Act. It was written as part of
9  * the author's official duties as a United States Government employee and
10  * thus cannot be copyrighted. This software/database is freely available
11  * to the public for use. The National Library of Medicine and the U.S.
12  * Government have not placed any restriction on its use or reproduction.
13  *
14  * Although all reasonable efforts have been taken to ensure the accuracy
15  * and reliability of the software and data, the NLM and the U.S.
16  * Government do not and cannot warrant the performance or results that
17  * may be obtained by using this software or data. The NLM and the U.S.
18  * Government disclaim all warranties, express or implied, including
19  * warranties of performance, merchantability or fitness for any particular
20  * purpose.
21  *
22  * Please cite the author in any work or product based on this material.
23  *
24  * ===========================================================================
25  *
26  * Authors: Mike DiCuccio
27  *
28  * File Description:
29  *
30  */
31 
32 #include <ncbi_pch.hpp>
33 #include <corelib/ncbi_stack.hpp>
34 #include <corelib/ncbistd.hpp>
35 #include <corelib/ncbi_param.hpp>
36 
37 #ifdef NCBI_OS_SOLARIS
38 # include <sys/ucontext.h> // for additional test below
39 #endif
40 
41 #if defined(HAVE_BACKWARD_HPP) \
42  && (defined(HAVE_LIBDW) || defined(NCBI_OS_DARWIN))
44 #elif defined HAVE_LIBUNWIND
45 # include "ncbi_stack_libunwind.cpp"
46 #elif defined NCBI_OS_MSWIN
47 # if NCBI_PLATFORM_BITS == 64
48 # include "ncbi_stack_win64.cpp"
49 # else
50 # include "ncbi_stack_win32.cpp"
51 # endif
52 #elif defined NCBI_OS_SOLARIS && defined(GETUSTACK)
53 # include "ncbi_stack_solaris.cpp"
54 #elif defined NCBI_OS_LINUX
55 # include "ncbi_stack_linux.cpp"
56 #else
57 # include "ncbi_stack_default.cpp"
58 #endif
59 
60 
62 
63 
65 {
66  return module + " " + file + ":" + NStr::NumericToString(line) + " " + func +
67  " offset=0x" + NStr::NumericToString(offs, 0, 16) +
68 // On Windows PtrToString does not add 0x prefix, while on Linux it does.
69 #if defined NCBI_OS_MSWIN
70  " addr=0x" +
71 #else
72  " addr=" +
73 #endif
75 }
76 
77 
78 CStackTrace::CStackTrace(const string& prefix)
79  : m_Impl(new CStackTraceImpl),
80  m_Prefix(prefix)
81 {
82 }
83 
84 
86 {
87 }
88 
89 
91 {
92  *this = stack_trace;
93 }
94 
95 
97 {
98  if (&stack_trace != this) {
99  if ( stack_trace.m_Impl ) {
100  m_Impl.reset(new CStackTraceImpl(*stack_trace.m_Impl));
101  }
102  else {
103  const TStack& stack = stack_trace.GetStack();
104  m_Stack.clear();
105  m_Stack.insert(m_Stack.end(), stack.begin(), stack.end());
106  }
107  m_Prefix = stack_trace.m_Prefix;
108  }
109  return *this;
110 }
111 
112 
114 {
115  if ( m_Impl.get() ) {
116  m_Impl->Expand(m_Stack);
117  m_Impl.reset();
118  }
119 }
120 
121 
122 static const vector<string> s_StackFilters {
123  "ncbi::CStackTrace::", "ncbi::CStackTraceImpl::", "ncbi::CException::",
124  "backward::"
125 };
126 
128 {
130 
131  if ( Empty() ) {
132  os << m_Prefix << "NOT AVAILABLE" << endl;
133  return;
134  }
135 
136  ITERATE(TStack, it, m_Stack) {
137  string s = it->AsString();
138  bool skip = false;
139  for (auto filter : s_StackFilters) {
140  if (s.find(filter) != NPOS) {
141  skip = true;
142  break;
143  }
144  }
145  if (skip) continue;
146  os << m_Prefix << s << endl;
147  }
148 }
149 
150 
151 // Stack trace depth limit
152 const unsigned int kDefaultStackTraceMaxDepth = 200;
153 NCBI_PARAM_DECL(int, Debug, Stack_Trace_Max_Depth);
154 NCBI_PARAM_DEF_EX(int, Debug, Stack_Trace_Max_Depth, kDefaultStackTraceMaxDepth,
155  eParam_NoThread, DEBUG_STACK_TRACE_MAX_DEPTH);
156 typedef NCBI_PARAM_TYPE(Debug, Stack_Trace_Max_Depth) TStackTraceMaxDepth;
157 
159 {
160  static volatile bool s_InGetMaxDepth = false;
161  static CAtomicCounter s_MaxDepth;
162 
163  // Check if we are already getting the max depth. If yes, something
164  // probably went wrong. Just return the default value.
165  unsigned int val = kDefaultStackTraceMaxDepth;
166  if ( !s_InGetMaxDepth ) {
167  s_InGetMaxDepth = true;
168  try {
169  val = (unsigned int)s_MaxDepth.Get();
170  if (val > 0) {
171  return val;
172  }
173  val = TStackTraceMaxDepth::GetDefault();
174  if (val == 0) {
176  }
177  s_MaxDepth.Set(val);
178  }
179  catch (...) {
180  s_InGetMaxDepth = false;
181  throw;
182  }
183  s_InGetMaxDepth = false;
184  }
185  return val;
186 }
187 
188 
190 {
191 #ifdef CAN_HONOR_SIGNAL_HANDLING_CONFIGURATION
193 #endif
194 }
195 
196 
CAtomicCounter –.
Definition: ncbicntr.hpp:71
static void s_HonorSignalHandlingConfiguration(void)
bool Empty(void) const
Check if stack trace information is available.
Definition: ncbi_stack.hpp:90
unique_ptr< CStackTraceImpl > m_Impl
Definition: ncbi_stack.hpp:117
list< SStackFrameInfo > TStack
Definition: ncbi_stack.hpp:78
void Write(CNcbiOstream &os) const
Write stack trace to the stream, prepend each line with the prefix.
Definition: ncbi_stack.cpp:127
string m_Prefix
Definition: ncbi_stack.hpp:119
static unsigned int s_GetStackTraceMaxDepth(void)
Definition: ncbi_stack.cpp:158
const TStack & GetStack(void) const
Get the stack trace data.
Definition: ncbi_stack.hpp:97
static void s_HonorSignalHandlingConfiguration(void)
Definition: ncbi_stack.cpp:189
CStackTrace & operator=(const CStackTrace &stack_trace)
Definition: ncbi_stack.cpp:96
CStackTrace(const string &prefix="")
Get and store current stack trace.
Definition: ncbi_stack.cpp:78
void x_ExpandStackTrace(void) const
Definition: ncbi_stack.cpp:113
~CStackTrace(void)
Definition: ncbi_stack.cpp:85
TStack m_Stack
Definition: ncbi_stack.hpp:118
Include a standard set of the NCBI C++ Toolkit most basic headers.
#define ITERATE(Type, Var, Cont)
ITERATE macro to sequence through container elements.
Definition: ncbimisc.hpp:815
void Set(TValue new_value) THROWS_NONE
Set atomic counter value.
Definition: ncbicntr.hpp:185
TValue Get(void) const THROWS_NONE
Get atomic counter value.
Definition: ncbicntr.hpp:168
@ eParam_NoThread
Do not use per-thread values.
Definition: ncbi_param.hpp:418
#define END_NCBI_SCOPE
End previously defined NCBI scope.
Definition: ncbistl.hpp:103
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
Definition: ncbistl.hpp:100
IO_PREFIX::ostream CNcbiOstream
Portable alias for ostream.
Definition: ncbistre.hpp:149
#define NPOS
Definition: ncbistr.hpp:133
static void PtrToString(string &out_str, const void *ptr)
Convert pointer to string.
Definition: ncbistr.cpp:2762
static enable_if< is_arithmetic< TNumeric >::value||is_convertible< TNumeric, Int8 >::value, string >::type NumericToString(TNumeric value, TNumToStringFlags flags=0, int base=10)
Convert numeric value to string.
Definition: ncbistr.hpp:673
unsigned int
A callback function used to compare two keys in a database.
Definition: types.hpp:1210
const unsigned int kDefaultStackTraceMaxDepth
Definition: ncbi_stack.cpp:152
static const vector< string > s_StackFilters
Definition: ncbi_stack.cpp:122
NCBI_PARAM_DECL(int, Debug, Stack_Trace_Max_Depth)
NCBI_PARAM_DEF_EX(int, Debug, Stack_Trace_Max_Depth, kDefaultStackTraceMaxDepth, eParam_NoThread, DEBUG_STACK_TRACE_MAX_DEPTH)
typedef NCBI_PARAM_TYPE(Debug, Stack_Trace_Max_Depth) TStackTraceMaxDepth
string AsString(void) const
Definition: ncbi_stack.cpp:64
Modified on Fri Sep 20 14:57:43 2024 by modify_doxy.py rev. 669887