OpenMPI  0.1.1
MoreBacktrace.h
1 /*
2  File: MoreBacktrace.h
3 
4  Contains: Code for generating backtraces.
5 
6  Written by: DTS
7 
8  Copyright: Copyright (c) 2006 by Apple Computer, Inc., All Rights Reserved.
9 
10  Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
11  ("Apple") in consideration of your agreement to the following terms, and your
12  use, installation, modification or redistribution of this Apple software
13  constitutes acceptance of these terms. If you do not agree with these terms,
14  please do not use, install, modify or redistribute this Apple software.
15 
16  In consideration of your agreement to abide by the following terms, and subject
17  to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs
18  copyrights in this original Apple software (the "Apple Software"), to use,
19  reproduce, modify and redistribute the Apple Software, with or without
20  modifications, in source and/or binary forms; provided that if you redistribute
21  the Apple Software in its entirety and without modifications, you must retain
22  this notice and the following text and disclaimers in all such redistributions of
23  the Apple Software. Neither the name, trademarks, service marks or logos of
24  Apple Computer, Inc. may be used to endorse or promote products derived from the
25  Apple Software without specific prior written permission from Apple. Except as
26  expressly stated in this notice, no other rights or licenses, express or implied,
27  are granted by Apple herein, including but not limited to any patent rights that
28  may be infringed by your derivative works or by other works in which the Apple
29  Software may be incorporated.
30 
31  The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
32  WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
33  WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
34  PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
35  COMBINATION WITH YOUR PRODUCTS.
36 
37  IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
38  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
39  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
40  ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
41  OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
42  (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
43  ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
44 
45  Change History (most recent first):
46 
47 $Log: MoreBacktrace.h,v $
48 Revision 1.4 2006/01/22 22:46:48 eskimo1
49 Complete rewrite to account for architecture independence.
50 
51 Revision 1.3 2003/04/09 22:48:15 eskimo1
52 Added comments.
53 
54 Revision 1.2 2003/04/09 21:58:18 eskimo1
55 Removed the "uncertain PC" flag. I may need to bring it back later, but for now I never use it so there's no point declaring it.
56 
57 Revision 1.1 2003/04/04 15:03:08 eskimo1
58 First checked in. This code still has bugs, but I've written enough code that checking in is a good idea.
59 
60 
61 */
62 
63 #pragma once
64 
65 /////////////////////////////////////////////////////////////////
66 
67 // MoreIsBetter Setup
68 
69 #include "MoreSetup.h"
70 
71 // Mac OS Interfaces
72 
73 // Put <mach/mach.h> inside extern "C" guards for the C++ build
74 // because the Mach header files don't always have them.
75 
76 #if defined(__cplusplus)
77  extern "C" {
78 #endif
79 
80 #include <mach/mach.h>
81 
82 #if defined(__cplusplus)
83  }
84 #endif
85 
86 #include <stdint.h>
87 
88 /////////////////////////////////////////////////////////////////
89 
90 #ifdef __cplusplus
91 extern "C" {
92 #endif
93 
94 /////////////////////////////////////////////////////////////////
95 
96 #if TARGET_RT_MAC_CFM
97  #error MoreBacktrace no longer supports CFM builds.
98 #endif
99 
100 /////////////////////////////////////////////////////////////////
101 
102 /* Overview
103  --------
104  This module implements a number of backtrace routines. All
105  of the routines are implemented in terms of a common core.
106  The code is structured in a very generic way. For example, if
107  you were running on a version of Mach that support inter-machine
108  messaging, it would be feasible to do a backtrace of a PowerPC
109  program from program executing a completely different instruction
110  set architecture (ISA).
111 
112  IMPORTANT:
113  The current code does not support cross-architecture backtraces
114  because of technical limitations (specifically, I haven't had
115  time to implement cross-architecture symbol translation, which
116  is required for cross-architecture backtraces to work properly;
117  see the comments for InitSigTrampAddress in the implementation
118  file for the details).
119 
120  Backtraces are inherently processor-specific. Internal to this
121  module is a ISA later than adapts the backtrace for various ISA.
122  Currently it supports PowerPC (32-bit), PowerPC (64-bit), and
123  Intel (32-bit).
124 
125  If you're curious about how stack frames work for each ISA, check
126  out the comments in the implementation file. The comments in the
127  header focus on how you use these routines.
128 */
129 
130 /* Changes Since Previous Version
131  ------------------------------
132  If you used the previous version of this code, please note the
133  following changes:
134 
135  o Everything has changed (-:
136 
137  I completely rewrote this code to support multiple architectures.
138  By including support for PowerPC (64-bit), I was forced to
139  eliminate my dependencies on CoreServices (which isn't available
140  to PowerPC (64-bit) on Mac OS X 10.4.x), which means now I depend
141  solely on the System framework. Also, because I had to support
142  Intel, which requires Mach-O, I decided to drop support for CFM.
143  My theory is that anyone who wants to adopt the new version of this
144  module is doing so because they're porting to Intel, and those folks
145  have to leave their CFM build behind.
146 
147  The good news is that the new implementation is very similar
148  in spirit to the old, and it should be very easy for you to
149  adopt the new code.
150 */
151 
152 // Within this module, I treat all addresses as 64-bit. That way
153 // the code doesn't change for 64-bit and 32-bit architectures.
154 //
155 // Note:
156 // I could have made this type scale with the current pointer size,
157 // but my eventual goal is to support cross-architecture backtraces,
158 // which means I wanted a size that's at least as big as the 'largest'
159 // architecture I support.
160 
161 typedef uint64_t MoreBTAddr;
162 
163 // The following flags provide information about a specific frame in
164 // a backtrace.
165 //
166 // IMPORTANT:
167 // kMoreBTFrameBadMask is set for the last frame in the backtrace
168 // (where we've run off the end of the stack), but it can also be set
169 // for intermediate frames (where we've detected a frameless leaf
170 // routine, either at the top of the stack or as part of crossing
171 // a signal frame).
172 
173 typedef int MoreBTFlags;
174 enum {
175  kMoreBTFrameBadMask = 0x0001, // this frame pointer is bad
176  kMoreBTPCBadMask = 0x0002, // this PC is bad
177  kMoreBTSignalHandlerMask = 0x0004 // this frame is a signal handler
178 };
179 
180 // The end result of a backtrace is an array of MoreBTFrame
181 // structures describing a particular frame in the backtrace.
182 //
183 // Note:
184 // The PC points to the code that's using the frame. It is not
185 // the return address for that code. On architectures where the
186 // frame holds the return address (Intel, but not PowerPC), I do
187 // the appropriate corrections.
188 
189 struct MoreBTFrame {
190  MoreBTAddr pc; // PC for this function invocation
191  MoreBTAddr fp; // frame pointer for this function invocation
192  MoreBTFlags flags; // various flags, see above
193 };
194 typedef struct MoreBTFrame MoreBTFrame;
195 
196 /* Common Parameters
197  -----------------
198  All of the backtrace routines accept certain common parameters.
199 
200  o function result -- This is an errno-style error code.
201 
202  o stackBottom and stackTop -- These define the extent of the stack
203  which you are tracing. If this information isn't handy, supply
204  0 for both. Supplying meaningful values can reduce the number
205  of bogus frames reported if the stack is corrupt.
206 
207  o frameArray and frameArrayCount -- These define an array of stack
208  frames that the routines fill out. You can supply NULL and 0
209  (respectively) if you're not interested in getting the actual
210  frame data (typically you do this to get the count of the number
211  of frames via frameCount). The routines do not fail if this
212  buffer is exhausted. Instead they simply return as many frames
213  as they can and continue tracing, returning an accurate value
214  for frameCount.
215 
216  o frameCountPtr -- You can use this to get back an accurate count of
217  the number of frames in the stack. If you're not interested
218  in this information, you can pass NULL.
219 
220  IMPORTANT:
221  Because of the above, on return, *frameCountPtr can be larger than
222  frameArrayCount.
223 
224  The following assertions apply to these common parameters.
225 
226  o On entry, stackBottom and stackTop must both be zero, or stackBottom
227  must be strictly less than stackTop.
228 
229  o On entry, if frameArrayCount is not zero, frameArray must be not NULL.
230 
231  o On entry, frameCountPtr must not be NULL.
232 
233  o On return, *frameCountPtr will be the number of frames that were
234  found. On success, this is likely to be a meaningful number. On
235  error, this just indicates how far we got.
236 
237  o On return, if frameArrayCount is not NULL, frame data has been placed
238  into the frame array. The number of valid entries is
239  min(frameArray, *frameArrayCount).
240 */
241 
242 extern int MoreBacktraceMachSelf(
243  MoreBTAddr stackBottom,
244  MoreBTAddr stackTop,
245  MoreBTFrame * frameArray,
246  size_t frameArrayCount,
247  size_t * frameCountPtr
248 );
249  // Does a backtrace of the current thread. All of the parameters
250  // are described by the "Common Parameters" section above.
251 
252 extern int MoreBacktraceMachThread(
253  task_t task,
254  thread_t thread,
255  MoreBTAddr stackBottom,
256  MoreBTAddr stackTop,
257  MoreBTFrame * frameArray,
258  size_t frameArrayCount,
259  size_t * frameCountPtr
260 );
261  // Does a backtrace of a particular thread within a particular tasks.
262  // The common parameters (stackBottom and later) are described by the
263  // "Common Parameters" section above. The task parameter must a
264  // task control port; for a thread in the current task, use
265  // mach_task_self to get this value. The thread parameter is the thread
266  // to sample. It's generally inappropriate to use mach_thread_self
267  // (call MoreBacktraceMachSelf instead), but it does work.
268  //
269  // On entry, task must not be MACH_PORT_NULL.
270  // On entry, thread must not be MACH_PORT_NULL.
271 
272 #ifdef __cplusplus
273 }
274 #endif
Definition: MoreBacktrace.h:189