timemory 3.3.0
Modular C++ Toolkit for Performance Analysis and Logging. Profiling API and Tools for C, C++, CUDA, Fortran, and Python. The C++ template API is essentially a framework to creating tools: it is designed to provide a unifying interface for recording various performance measurements alongside data logging and interfaces to other tools.
demangle.cpp
Go to the documentation of this file.
1// MIT License
2//
3// Copyright (c) 2020, The Regents of the University of California,
4// through Lawrence Berkeley National Laboratory (subject to receipt of any
5// required approvals from the U.S. Dept. of Energy). All rights reserved.
6//
7// Permission is hereby granted, free of charge, to any person obtaining a copy
8// of this software and associated documentation files (the "Software"), to deal
9// in the Software without restriction, including without limitation the rights
10// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11// copies of the Software, and to permit persons to whom the Software is
12// furnished to do so, subject to the following conditions:
13//
14// The above copyright notice and this permission notice shall be included in all
15// copies or substantial portions of the Software.
16//
17// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23// SOFTWARE.
24
25#ifndef TIMEMORY_UTILITY_DEMANGLE_CPP_
26#define TIMEMORY_UTILITY_DEMANGLE_CPP_ 1
27
29
30#if !defined(TIMEMORY_UTILITY_HEADER_MODE)
32#endif
33
35
36#include <iostream>
37#include <sstream>
38#include <string>
39#include <utility>
40
41namespace tim
42{
43#if defined(TIMEMORY_UNIX)
44//
46demangle_backtrace(const char* cstr)
47{
48 auto _trim = [](std::string& _sub, size_t& _len) {
49 size_t _pos = 0;
50 while(!_sub.empty() && (_pos = _sub.find_first_of(' ')) == 0)
51 {
52 _sub = _sub.erase(_pos, 1);
53 --_len;
54 }
55 while(!_sub.empty() && (_pos = _sub.find_last_of(' ')) == _sub.length() - 1)
56 {
57 _sub = _sub.substr(0, _sub.length() - 1);
58 --_len;
59 }
60 return _sub;
61 };
62
63 auto _save = std::string{ cstr };
64 auto str = demangle(std::string(cstr));
65 if(str.empty())
66 return str;
67 auto beg = str.find('(');
68 if(beg == std::string::npos)
69 {
70 beg = str.find("_Z");
71 if(beg != std::string::npos)
72 beg -= 1;
73 }
74 auto end = str.find('+', beg);
75 if(beg != std::string::npos && end != std::string::npos)
76 {
77 auto len = end - (beg + 1);
78 auto sub = str.substr(beg + 1, len);
79 auto dem = demangle(_trim(sub, len));
80 str = str.replace(beg + 1, len, dem);
81 }
82 else if(beg != std::string::npos)
83 {
84 auto len = str.length() - (beg + 1);
85 auto sub = str.substr(beg + 1, len);
86 auto dem = demangle(_trim(sub, len));
87 str = str.replace(beg + 1, len, dem);
88 }
89 else if(end != std::string::npos)
90 {
91 auto len = end;
92 auto sub = str.substr(beg, len);
93 auto dem = demangle(_trim(sub, len));
94 str = str.replace(beg, len, dem);
95 }
96
97 if(str.empty())
98 {
99 TIMEMORY_TESTING_EXCEPTION(__FUNCTION__ << " resulted in empty string. input: "
100 << _save);
101 return _save;
102 }
103
104 // cleanup std::_1::basic_<...> types since demangled versions are for diagnostics
105 using pair_t = std::pair<std::string, std::string>;
106 for(auto&& itr : { pair_t{ demangle<std::string>(), "std::string" },
107 pair_t{ demangle<std::istream>(), "std::istream" },
108 pair_t{ demangle<std::ostream>(), "std::ostream" },
109 pair_t{ demangle<std::stringstream>(), "std::stringstream" },
110 pair_t{ demangle<std::istringstream>(), "std::istringstream" },
111 pair_t{ demangle<std::ostringstream>(), "std::ostringstream" } })
112 str = str_transform(str, itr.first, "", [itr](const std::string&) -> std::string {
113 return itr.second;
114 });
115 return str;
116}
117//
119demangle_backtrace(const std::string& str)
120{
121 return demangle_backtrace(str.c_str());
122}
123//
125demangle_unw_backtrace(const char* cstr)
126{
127 auto _save = std::string{ cstr };
128 auto _str = tim::demangle(cstr);
129 if(_str.empty())
130 return _str;
131 auto _beg = _str.find("_Z");
132 auto _end = _str.find(' ', _beg);
133 if(_beg != std::string::npos && _end != std::string::npos)
134 {
135 auto _len = _end - _beg;
136 auto _sub = _str.substr(_beg, _len);
137 auto _dem = demangle(_sub);
138 _str = _str.replace(_beg, _len, _dem);
139 }
140
141 if(_str.empty())
142 {
143 TIMEMORY_TESTING_EXCEPTION(__FUNCTION__ << " resulted in empty string. input: "
144 << _save);
145 return _save;
146 }
147
148 // cleanup std::_1::basic_<...> types since demangled versions are for diagnostics
149 using pair_t = std::pair<std::string, std::string>;
150 for(auto&& itr : { pair_t{ demangle<std::string>(), "std::string" },
151 pair_t{ demangle<std::istream>(), "std::istream" },
152 pair_t{ demangle<std::ostream>(), "std::ostream" },
153 pair_t{ demangle<std::stringstream>(), "std::stringstream" },
154 pair_t{ demangle<std::istringstream>(), "std::istringstream" },
155 pair_t{ demangle<std::ostringstream>(), "std::ostringstream" } })
156 _str =
157 str_transform(_str, itr.first, "", [itr](const std::string&) -> std::string {
158 return itr.second;
159 });
160
161 return _str;
162}
163//
165demangle_unw_backtrace(const std::string& _str)
166{
167 return demangle_unw_backtrace(_str.c_str());
168}
169//
170#endif // defined(TIMEMORY_UNIX)
171} // namespace tim
172
173#endif
return _hash_map end()
Definition: kokkosp.cpp:39
std::string str_transform(const std::string &input, const std::string &_begin, const std::string &_end, PredicateT &&predicate)
apply a string transformation to substring inbetween a common delimiter. e.g.
Definition: delimit.hpp:111
std::string demangle(const char *_mangled_name, int *_status=nullptr)
Definition: demangle.hpp:47
tim::mpl::apply< std::string > string
Definition: macros.hpp:53
#define TIMEMORY_TESTING_EXCEPTION(...)
Definition: types.hpp:156