1 /*
2  *  Copyright (c) 2014 Dmitry Kazakov <dimula73@gmail.com>
3  *
4  *  This program is free software; you can redistribute it and/or modify
5  *  it under the terms of the GNU General Public License as published by
6  *  the Free Software Foundation; either version 2 of the License, or
7  *  (at your option) any later version.
8  *
9  *  This program is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *  GNU General Public License for more details.
13  *
14  *  You should have received a copy of the GNU General Public License
15  *  along with this program; if not, write to the Free Software
16  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  */
18 #include "kis_debug.h"
19 
20 #include "config-debug.h"
21 
22 #if HAVE_BACKTRACE
23 #include <execinfo.h>
24 #ifdef __GNUC__
25 #define HAVE_BACKTRACE_DEMANGLE
26 #include <cxxabi.h>
27 #endif
28 #endif
29 
30 #include <string>
31 
32 
33 #if HAVE_BACKTRACE
maybeDemangledName(char * name)34 static QString maybeDemangledName(char *name)
35 {
36 #ifdef HAVE_BACKTRACE_DEMANGLE
37     const int len = strlen(name);
38     QByteArray in = QByteArray::fromRawData(name, len);
39     const int mangledNameStart = in.indexOf("(_");
40     if (mangledNameStart >= 0) {
41         const int mangledNameEnd = in.indexOf('+', mangledNameStart + 2);
42         if (mangledNameEnd >= 0) {
43             int status;
44             // if we forget about this line and the one that undoes its effect we don't change the
45             // internal data of the QByteArray::fromRawData() ;)
46             name[mangledNameEnd] = 0;
47             char *demangled = abi::__cxa_demangle(name + mangledNameStart + 1, 0, 0, &status);
48             name[mangledNameEnd] = '+';
49             if (demangled) {
50                 QString ret = QString::fromLatin1(name, mangledNameStart + 1) +
51                               QString::fromLatin1(demangled) +
52                               QString::fromLatin1(name + mangledNameEnd, len - mangledNameEnd);
53                 free(demangled);
54                 return ret;
55             }
56         }
57     }
58 #endif
59     return QString::fromLatin1(name);
60 }
61 #endif
62 
kisBacktrace()63 QString kisBacktrace()
64 {
65     QString s;
66 #if HAVE_BACKTRACE
67     void *trace[256];
68     int n = backtrace(trace, 256);
69     if (!n) {
70         return s;
71     }
72     char **strings = backtrace_symbols(trace, n);
73 
74     s = QLatin1String("[\n");
75 
76     for (int i = 0; i < n; ++i)
77         s += QString::number(i) + QLatin1String(": ") +
78              maybeDemangledName(strings[i]) + QLatin1Char('\n');
79     s += QLatin1String("]\n");
80     free(strings);
81 #endif
82     return s;
83 }
84 
85 Q_LOGGING_CATEGORY(_30009, "krita.lib.resources", QtInfoMsg)
86 Q_LOGGING_CATEGORY(_41000, "krita.general", QtInfoMsg)
87 Q_LOGGING_CATEGORY(_41001, "krita.core", QtInfoMsg)
88 Q_LOGGING_CATEGORY(_41002, "krita.registry", QtInfoMsg)
89 Q_LOGGING_CATEGORY(_41003, "krita.tools", QtInfoMsg)
90 Q_LOGGING_CATEGORY(_41004, "krita.tiles", QtInfoMsg)
91 Q_LOGGING_CATEGORY(_41005, "krita.filters", QtInfoMsg)
92 Q_LOGGING_CATEGORY(_41006, "krita.plugins", QtInfoMsg)
93 Q_LOGGING_CATEGORY(_41007, "krita.ui", QtInfoMsg)
94 Q_LOGGING_CATEGORY(_41008, "krita.file", QtInfoMsg)
95 Q_LOGGING_CATEGORY(_41009, "krita.math", QtInfoMsg)
96 Q_LOGGING_CATEGORY(_41010, "krita.render", QtInfoMsg)
97 Q_LOGGING_CATEGORY(_41011, "krita.scripting", QtInfoMsg)
98 Q_LOGGING_CATEGORY(_41012, "krita.input", QtInfoMsg)
99 Q_LOGGING_CATEGORY(_41013, "krita.action", QtInfoMsg)
100 Q_LOGGING_CATEGORY(_41014, "krita.tabletlog", QtDebugMsg)
101 Q_LOGGING_CATEGORY(_41015, "krita.opengl", QtInfoMsg)
102 Q_LOGGING_CATEGORY(_41016, "krita.metadata", QtInfoMsg)
103 Q_LOGGING_CATEGORY(_41017, "krita.android", QtDebugMsg)
104 
__methodName(const char * _prettyFunction)105 QString __methodName(const char *_prettyFunction)
106 {
107     std::string prettyFunction(_prettyFunction);
108 
109     size_t colons = prettyFunction.find("::");
110     size_t begin = prettyFunction.substr(0,colons).rfind(" ") + 1;
111     size_t end = prettyFunction.rfind("(") - begin;
112 
113     return QString(std::string(prettyFunction.substr(begin,end) + "()").c_str());
114 }
115