2 * Copyright (C) 2000-2017 Paul Davis <paul@linuxaudiosystems.com>
3 * Copyright (C) 2006-2007 Taybin Rutkin <taybin@taybin.com>
4 * Copyright (C) 2009-2010 Carl Hetherington <carl@carlh.net>
5 * Copyright (C) 2013-2015 John Emmas <john@creativepost.co.uk>
6 * Copyright (C) 2015-2019 Robin Gareus <robin@gareus.org>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23 #include "libpbd-config.h"
25 #include "pbd/stacktrace.h"
26 #include "pbd/debug.h"
27 #include "pbd/demangle.h"
28 #include "pbd/compose.h"
29 #include "pbd/pthread_utils.h"
35 #ifdef PLATFORM_WINDOWS
45 /* Obtain a backtrace and print it to stdout. */
52 PBD::stacktrace (std::ostream& out, int levels)
59 size = backtrace (array, 200);
62 strings = backtrace_symbols (array, size);
66 for (i = 0; i < size && (levels == 0 || i < size_t(levels)); i++) {
67 out << " " << demangle (strings[i]) << std::endl;
73 out << "no stacktrace available!" << std::endl;
77 #elif defined (PLATFORM_WINDOWS)
79 #if defined DEBUG && !defined CaptureStackBackTrace
80 #define CaptureStackBackTrace RtlCaptureStackBackTrace
83 __declspec(dllimport) USHORT WINAPI CaptureStackBackTrace (
85 ULONG FramesToCapture,
87 PULONG BackTraceHash);
92 PBD::stacktrace (std::ostream& out, int)
95 const size_t levels = 62; // does not support more then 62 levels of stacktrace
97 void * stack[ levels ];
98 unsigned short frames;
102 process = GetCurrentProcess();
103 out << "+++++Backtrace process: " << DEBUG_THREAD_SELF << std::endl;
105 SymInitialize (process, NULL, TRUE);
107 frames = CaptureStackBackTrace (0, levels, stack, NULL);
109 out << "+++++Backtrace frames: " << frames << std::endl;
111 symbol = (SYMBOL_INFO*)calloc (sizeof (SYMBOL_INFO) + 256 * sizeof (char), 1);
112 symbol->MaxNameLen = 255;
113 symbol->SizeOfStruct = sizeof (SYMBOL_INFO);
115 for (i = 0; i < frames; ++i) {
116 SymFromAddr (process, (DWORD64)(stack[i]), 0, symbol);
117 out << string_compose ("%1: %2 - %3\n", samples - i - 1, symbol->Name, symbol->Address);
129 PBD::stacktrace (std::ostream& out, int /*levels*/)
131 out << "stack tracing is not enabled on this platform" << std::endl;
139 PBD::stacktrace (std::cout);