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
23namespace application {
24
25#ifdef ENABLE_CALLSTACK_TRACKING
26
27// forward.
28class callstack_records;
29class callstack_tracker;
30
32
33callstack_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{
50public:
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
96private:
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{
147public:
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()
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 provider of thread-wide (single instance per thread) callstack_trackers.
void update_current_stack_frame_line_number(int line)
sets the line number for the current frame in the global stack trace.