feisty meow concerns codebase  2.140
callstack_tracker.h
Go to the documentation of this file.
1 #ifndef CALLSTACK_TRACKER_CLASS
2 #define CALLSTACK_TRACKER_CLASS
3 
4 /*****************************************************************************\
5 * *
6 * Name : callstack_tracker *
7 * Author : Chris Koeritz *
8 * *
9 *******************************************************************************
10 * Copyright (c) 2007-$now By Author. This program is free software; you can *
11 * redistribute it and/or modify it under the terms of the GNU General Public *
12 * License as published by the Free Software Foundation; either version 2 of *
13 * the License or (at your option) any later version. This is online at: *
14 * http://www.fsf.org/copyleft/gpl.html *
15 * Please send any updates to: fred@gruntose.com *
16 \*****************************************************************************/
17 
19 #include <basis/contracts.h>
20 #include <basis/definitions.h>
21 #include <basis/mutex.h>
22 
23 namespace application {
24 
25 #ifdef ENABLE_CALLSTACK_TRACKING
26 
27 // forward.
28 class callstack_records;
29 class callstack_tracker;
30 
32 
33 callstack_tracker &thread_wide_stack_trace();
35 
36 //hmmm: maybe borked on basis of the conflict between a global stack tracker and the fact that each thread has its own callstack! argh!
37 
39 
41 
49 {
50 public:
52  virtual ~callstack_tracker();
53 
54 // DEFINE_CLASS_NAME("callstack_tracker");
55 
56  bool push_frame(const char *class_name, const char *func, const char *file,
57  int line);
59 
66  bool pop_frame();
68 
69  bool update_line(int line);
71 
74  char *full_trace() const;
76 
78  int full_trace_size() const;
80 
81  int depth() const { return _depth; }
83 
84  double frames_in() const { return _frames_in; }
86 
87  double frames_out() const { return _frames_out; }
89 
90  double highest() const { return _highest; }
92 
95 
96 private:
97  callstack_records *_bt;
98  int _depth;
99  double _frames_in;
100  double _frames_out;
101  double _highest;
102  bool _unusable;
103 };
104 
106 
113 #define GET_AND_TEST_STACK_TRACE(header, failure_return) { \
114  int trace_size = thread_wide_stack_trace().full_trace_size(); \
115  char *stack_trace = thread_wide_stack_trace().full_trace(); \
116  ASSERT_TRUE(trace_size >= strlen(stack_trace) + 1, "insufficient estimated stack trace size"); \
117  if (trace_size < strlen(stack_trace) + 1) { \
118  /* error condition here; we are supposed to get the actual size we would need to allocate! */ \
119  LOG(a_sprintf("failure in stack trace return: estimated size (%d) was less than actual (%d)", \
120  trace_size, strlen(stack_trace))); \
121  /* mandatory free step for newly allocated string. */ \
122  free(stack_trace); \
123  return failure_return; \
124  } \
125  ASSERT_TRUE(strlen(stack_trace) > 1, "empty stack trace"); \
126  if (strlen(stack_trace) < 2) { \
127  LOG("failure in stack trace return: the trace output string was empty!"); \
128  return failure_return; \
129  } \
130  LOG(astring("\n\n################\n\n") + header + "\n" + stack_trace); \
131  /* mandatory free step for newly allocated string. */ \
132  free(stack_trace); \
133 }
134 
136 
138 
146 {
147 public:
148  // these are not encapsulated, but be careful with the contents.
150  char *_class, *_func, *_file;
151  int _line;
152 
153  frame_tracking_instance(const char *class_name = "", const char *func = "",
154  const char *file = "", int line = 0, bool add_frame = false);
156 
162 
165 
167 
168  void assign(const char *class_name, const char *func, const char *file,
169  int line);
171 
172  void clean();
174 };
175 
178 
179 #else // ENABLE_CALLSTACK_TRACKING
180  /*
181  bogus replacements for the most commonly used callstack tracking support.
182  these are necessary because we don't want this enabled in all scenarios,
183  and when we want the callstack tracking disabled, it must have near zero
184  runtime cost.
185  */
186  inline void no_op() { /* do nothing. */ }
187  #define frame_tracking_instance
188  #define GET_AND_TEST_STACK_TRACE(header, failure_return) no_op();
189  #define __trail_of_function(p1, p2, p3, p4, p5) no_op();
190  inline void update_current_stack_frame_line_number(int line) { /* more nothing. */ }
191 #endif // ENABLE_CALLSTACK_TRACKING
192 
193 } //namespace.
194 
195 #endif // outer guard.
196 
Contains definitions that control how libraries and programs are built.
This object can provide a backtrace at runtime of the invoking methods.
double frames_out() const
reports the number of call stack frames that were removed, total.
bool push_frame(const char *class_name, const char *func, const char *file, int line)
adds a new stack from for the "class_name" in "function" at the "line".
double frames_in() const
reports the number of call stack frames that were added, total.
bool pop_frame()
removes the last callstack frame off from our tracking.
char * full_trace() const
provides the current stack trace in a newly malloc'd string.
int depth() const
the current number of frames we know of.
double highest() const
reports the maximum stack depth seen during the runtime so far.
bool update_line(int line)
sets the line number within the current stack frame.
static basis::mutex & __callstack_tracker_synchronizer()
protects concurrent access.
int full_trace_size() const
this returns an estimated number of bytes needed for the full_trace().
a small object that represents a stack trace in progress.
frame_tracking_instance(const char *class_name="", const char *func="", const char *file="", int line=0, bool add_frame=false)
as an automatic variable, this can hang onto frame information.
~frame_tracking_instance()
releases the information and this stack frame in the tracker.
void clean()
throws out our accumulated memory and pops frame if applicable.
char * _file
newly allocated copies.
bool _frame_involved
has this object been added to the tracker?
void assign(const char *class_name, const char *func, const char *file, int line)
similar to assignment operator but doesn't require an object.
frame_tracking_instance & operator=(const frame_tracking_instance &to_copy)
Constants and objects used throughout HOOPLE.
Implements an application lock to ensure only one is running at once.
callstack_tracker & thread_wide_stack_trace()
the single instance of callstack_tracker.
void update_current_stack_frame_line_number(int line)
sets the line number for the current frame in the global stack trace.