15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2005, Google Inc.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// All rights reserved.
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Redistribution and use in source and binary forms, with or without
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// modification, are permitted provided that the following conditions are
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// met:
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     * Redistributions of source code must retain the above copyright
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// notice, this list of conditions and the following disclaimer.
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     * Redistributions in binary form must reproduce the above
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// copyright notice, this list of conditions and the following disclaimer
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// in the documentation and/or other materials provided with the
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// distribution.
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     * Neither the name of Google Inc. nor the names of its
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// contributors may be used to endorse or promote products derived from
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// this software without specific prior written permission.
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ---
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Author: Sanjay Ghemawat
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Routines to extract the current stack trace.  These functions are
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// thread-safe.
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef GOOGLE_STACKTRACE_H_
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define GOOGLE_STACKTRACE_H_
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Annoying stuff for windows -- makes sure clients can import these functions
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef PERFTOOLS_DLL_DECL
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# ifdef _WIN32
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#   define PERFTOOLS_DLL_DECL  __declspec(dllimport)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# else
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#   define PERFTOOLS_DLL_DECL
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# endif
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Skips the most recent "skip_count" stack frames (also skips the
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// frame generated for the "GetStackFrames" routine itself), and then
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// records the pc values for up to the next "max_depth" frames in
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// "result", and the corresponding stack frame sizes in "sizes".
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns the number of values recorded in "result"/"sizes".
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Example:
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//      main() { foo(); }
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//      foo() { bar(); }
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//      bar() {
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//        void* result[10];
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//        int sizes[10];
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//        int depth = GetStackFrames(result, sizes, 10, 1);
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//      }
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The GetStackFrames call will skip the frame for "bar".  It will
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// return 2 and will produce pc values that map to the following
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// procedures:
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//      result[0]       foo
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//      result[1]       main
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// (Actually, there may be a few more entries after "main" to account for
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// startup procedures.)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// And corresponding stack frame sizes will also be recorded:
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//    sizes[0]       16
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//    sizes[1]       16
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// (Stack frame sizes of 16 above are just for illustration purposes.)
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Stack frame sizes of 0 or less indicate that those frame sizes couldn't
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// be identified.
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This routine may return fewer stack frame entries than are
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// available. Also note that "result" and "sizes" must both be non-NULL.
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern PERFTOOLS_DLL_DECL int GetStackFrames(void** result, int* sizes, int max_depth,
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          int skip_count);
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Same as above, but to be used from a signal handler. The "uc" parameter
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// should be the pointer to ucontext_t which was passed as the 3rd parameter
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// to sa_sigaction signal handler. It may help the unwinder to get a
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// better stack trace under certain conditions. The "uc" may safely be NULL.
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern PERFTOOLS_DLL_DECL int GetStackFramesWithContext(void** result, int* sizes, int max_depth,
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     int skip_count, const void *uc);
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This is similar to the GetStackFrames routine, except that it returns
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the stack trace only, and not the stack frame sizes as well.
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Example:
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//      main() { foo(); }
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//      foo() { bar(); }
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//      bar() {
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//        void* result[10];
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//        int depth = GetStackTrace(result, 10, 1);
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//      }
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This produces:
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//      result[0]       foo
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//      result[1]       main
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//           ....       ...
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// "result" must not be NULL.
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern PERFTOOLS_DLL_DECL int GetStackTrace(void** result, int max_depth,
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            int skip_count);
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Same as above, but to be used from a signal handler. The "uc" parameter
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// should be the pointer to ucontext_t which was passed as the 3rd parameter
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// to sa_sigaction signal handler. It may help the unwinder to get a
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// better stack trace under certain conditions. The "uc" may safely be NULL.
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern PERFTOOLS_DLL_DECL int GetStackTraceWithContext(void** result, int max_depth,
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    int skip_count, const void *uc);
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* GOOGLE_STACKTRACE_H_ */
117