]> git.sesse.net Git - casparcg/blob - common/os/windows/stack_trace.cpp
[logging] Suppress the logging of full path names in stack traces so that only the...
[casparcg] / common / os / windows / stack_trace.cpp
1 /*
2 * Copyright (c) 2011 Sveriges Television AB <info@casparcg.com>
3 *
4 * This file is part of CasparCG (www.casparcg.com).
5 *
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.
10 *
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.
15 *
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/>.
18 *
19 * Author: Helge Norberg, helge.norberg@svt.se
20 */
21
22 #include "../../stdafx.h"
23
24 #include "../stack_trace.h"
25 #include "../../utf.h"
26
27 #include "../../compiler/vs/StackWalker.h"
28
29 #include <boost/algorithm/string/replace.hpp>
30
31 #include <utility>
32
33 #include <tbb/enumerable_thread_specific.h>
34 #include <boost/algorithm/string/find.hpp>
35
36 namespace caspar {
37
38 std::wstring get_call_stack()
39 {
40         class log_call_stack_walker : public StackWalker
41         {
42                 std::string str_ = "\n";
43         public:
44                 log_call_stack_walker()
45                         : StackWalker()
46                 {
47                 }
48
49                 std::string flush()
50                 {
51                         auto result = std::move(str_);
52
53                         str_ = "\n";
54
55                         return result;
56                 }
57         protected:
58                 virtual void OnSymInit(LPCSTR szSearchPath, DWORD symOptions, LPCSTR szUserName) override
59                 {
60                 }
61                 virtual void OnLoadModule(LPCSTR img, LPCSTR mod, DWORD64 baseAddr, DWORD size, DWORD result, LPCSTR symType, LPCSTR pdbName, ULONGLONG fileVersion) override
62                 {
63                 }
64                 virtual void OnDbgHelpErr(LPCSTR szFuncName, DWORD gle, DWORD64 addr) override
65                 {
66                 }
67                 virtual void OnOutput(LPCSTR szText) override
68                 {
69                         std::string str = szText;
70
71                         auto include_path = boost::find_first(str, "\\include\\");
72
73                         if (include_path)
74                         {
75                                 str.erase(str.begin(), include_path.end());
76                         }
77
78                         boost::ireplace_all(str, get_source_prefix(), "");
79
80                         if (str.find("caspar::get_call_stack") == std::string::npos &&
81                                 str.find("StackWalker::ShowCallstack") == std::string::npos)
82                         {
83                                 str_ += "    " + std::move(str);
84                         }
85                 }
86         };
87
88         static tbb::enumerable_thread_specific<log_call_stack_walker> walkers;
89         try
90         {
91                 auto& walker = walkers.local();
92                 walker.ShowCallstack();
93                 return u16(walker.flush());
94         }
95         catch(...)
96         {
97                 return L"Bug in stacktrace code!!!";
98         }
99 }
100
101 const std::string& get_source_prefix()
102 {
103         static const std::string SOURCE_PREFIX = []
104         {
105                 std::string result = CASPAR_SOURCE_PREFIX;
106
107                 boost::replace_all(result, "/", "\\");
108                 result += "\\";
109
110                 return result;
111         }();
112
113         return SOURCE_PREFIX;
114 }
115
116 }