2 * Copyright (c) 2011 Sveriges Television AB <info@casparcg.com>
4 * This file is part of CasparCG (www.casparcg.com).
6 * CasparCG is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * CasparCG is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with CasparCG. If not, see <http://www.gnu.org/licenses/>.
19 * Author: Helge Norberg, helge.norberg@svt.se
22 #include "../stack_trace.h"
33 std::string demangle(const std::string& mangled)
35 auto start_of_name = mangled.find_first_of('(');
37 if (start_of_name == std::string::npos)
40 auto start_of_offset = mangled.find_first_of('+', start_of_name);
42 if (start_of_offset == std::string::npos)
45 auto end_of_name = mangled.find_first_of(')', start_of_offset);
47 if (end_of_name == std::string::npos)
50 auto file = mangled.substr(0, start_of_name);
51 auto mangled_symbol_name = mangled.substr(start_of_name + 1, start_of_offset - start_of_name - 1);
52 auto offset = mangled.substr(start_of_offset + 1, end_of_name - start_of_offset - 1);
55 auto demangled = abi::__cxa_demangle(mangled_symbol_name.c_str(), nullptr, nullptr, &status);
56 bool demangled_success = status == 0;
58 if (demangled_success)
60 auto demangled_guard = std::shared_ptr<char>(demangled, free);
62 return file + " : " + demangled + " + " + offset;
70 std::wstring get_call_stack()
72 std::array<void*, 100> stackframes;
73 auto size = backtrace(stackframes.data(), stackframes.size());
74 auto strings = backtrace_symbols(stackframes.data(), size);
76 if (strings == nullptr)
77 return L"Out of memory while generating stack trace";
81 auto entries = std::shared_ptr<char*>(strings, free);
82 std::wostringstream stream;
85 for (int i = 0; i != size; ++i)
87 auto demangled = demangle(strings[i]);
89 if (!demangled.empty() && demangled.find("caspar::get_call_stack") == std::string::npos)
90 stream << L" " << demangled.c_str() << std::endl;
95 catch (const std::bad_alloc&)
97 return L"Out of memory while generating stack trace";
101 return L"Error while generating stack trace";
105 const std::string& get_source_prefix()
107 static const std::string SOURCE_PREFIX;
108 return SOURCE_PREFIX;