Warning: That file was not part of the compilation database. It may have many parsing errors.
1 | /* |
---|---|
2 | * Copyright (C) 2008-2009 Hyves (Startphone Ltd.) |
3 | * Copyright (c) 2014 Boudewijn Rempt <boud@kde.org> |
4 | * |
5 | * This program is free software; you can redistribute it and/or modify |
6 | * it under the terms of the GNU General Public License as published by |
7 | * the Free Software Foundation; either version 2 of the License, or |
8 | * (at your option) any later version. |
9 | * |
10 | * This program is distributed in the hope that it will be useful, |
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
13 | * GNU General Public License for more details. |
14 | * |
15 | * You should have received a copy of the GNU General Public License |
16 | * along with this program; if not, write to the Free Software |
17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 US |
18 | * |
19 | * Version: MPL 1.1/GPL 2.0/LGPL 2.1 |
20 | * |
21 | * The contents of this file are subject to the Mozilla Public License Version |
22 | * 1.1 (the "License"); you may not use this file except in compliance with |
23 | * the License. You may obtain a copy of the License at |
24 | * http://www.mozilla.org/MPL/ |
25 | * |
26 | * Software distributed under the License is distributed on an "AS IS" basis, |
27 | * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License |
28 | * for the specific language governing rights and limitations under the |
29 | * License. |
30 | * |
31 | * The Original Code is Mozilla Breakpad integration |
32 | * |
33 | * The Initial Developer of the Original Code is |
34 | * Ted Mielczarek <ted.mielczarek@gmail.com> |
35 | * Portions created by the Initial Developer are Copyright (C) 2006 |
36 | * the Initial Developer. All Rights Reserved. |
37 | * |
38 | * Contributor(s): |
39 | * Josh Aas <josh@mozilla.com> |
40 | * |
41 | * Alternatively, the contents of this file may be used under the terms of |
42 | * either the GNU General Public License Version 2 or later (the "GPL"), or |
43 | * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), |
44 | * in which case the provisions of the GPL or the LGPL are applicable instead |
45 | * of those above. If you wish to allow use of your version of this file only |
46 | * under the terms of either the GPL or the LGPL, and not to allow others to |
47 | * use your version of this file under the terms of the MPL, indicate your |
48 | * decision by deleting the provisions above and replace them with the notice |
49 | * and other provisions required by the GPL or the LGPL. If you do not delete |
50 | * the provisions above, a recipient may use your version of this file under |
51 | * the terms of any one of the MPL, the GPL or the LGPL. |
52 | * |
53 | * ***** END LICENSE BLOCK ***** */ |
54 | |
55 | #include "kis_crash_handler.h" |
56 | |
57 | #include <QDebug> |
58 | #include <QDesktopServices> |
59 | #include <QTextStream> |
60 | |
61 | #ifdef Q_WS_MAC |
62 | #include <string> |
63 | #include <fcntl.h> |
64 | #include <sys/types.h> |
65 | #include <unistd.h> |
66 | #include <errno.h> |
67 | #include <stdio.h> |
68 | #include <client/mac/handler/exception_handler.h> |
69 | #elif defined Q_WS_WIN |
70 | #include <string.h> |
71 | #include <windows.h> |
72 | #include <iostream> |
73 | #include <client/windows/handler/exception_handler.h> |
74 | #elif defined Q_WS_X11 |
75 | #include <fcntl.h> |
76 | #include <sys/types.h> |
77 | #include <unistd.h> |
78 | #include <errno.h> |
79 | #include <stdio.h> |
80 | #include <client/linux/handler/exception_handler.h> |
81 | #else |
82 | #error "Breakpad does not exist for this platform!" |
83 | #endif |
84 | |
85 | #include <stdlib.h> |
86 | #include <time.h> |
87 | |
88 | #ifdef Q_WS_WIN |
89 | #ifndef UNICODE |
90 | #define UNICODE |
91 | #endif |
92 | typedef wchar_t HD_CHAR; |
93 | // sort of arbitrary, but MAX_PATH is kinda small |
94 | #define HD_MAX_PATH 4096 |
95 | #define CRASH_REPORTER_BINARY L"crashhandler.exe" |
96 | #else |
97 | typedef char HD_CHAR; |
98 | #define CRASH_REPORTER_BINARY "crashhandler" |
99 | #endif |
100 | |
101 | static google_breakpad::ExceptionHandler *exceptionHandler = 0; |
102 | |
103 | // if this is true, we pass the exception on to the OS crash reporter |
104 | // static bool showOSCrashReporter = false; |
105 | |
106 | // Note: we've crashed so we cannot use the heap here. So we cannot use any Q* class. |
107 | static bool startCrashReporter(const HD_CHAR *dumpPath, const HD_CHAR *minidumpID, void *context, |
108 | #ifdef Q_WS_WIN |
109 | EXCEPTION_POINTERS *exceptionInfo, |
110 | MDRawAssertionInfo *assertion, |
111 | #endif |
112 | bool succeeded) { |
113 | |
114 | if (!succeeded) { |
115 | return false; |
116 | } |
117 | |
118 | #ifdef Q_WS_WIN |
119 | |
120 | wchar_t command[(HD_MAX_PATH * 2) + 6]; |
121 | wcscpy(command, CRASH_REPORTER_BINARY L" \""); |
122 | wcscat(command, dumpPath); |
123 | wcscat(command, L"\" \""); |
124 | wcscat(command, minidumpID); |
125 | wcscat(command, L"\""); |
126 | |
127 | STARTUPINFOW si; |
128 | PROCESS_INFORMATION pi; |
129 | |
130 | ZeroMemory(&si, sizeof(si)); |
131 | si.cb = sizeof(si); |
132 | si.dwFlags = STARTF_USESHOWWINDOW; |
133 | si.wShowWindow = SW_SHOWNORMAL; |
134 | ZeroMemory(&pi, sizeof(pi)); |
135 | |
136 | if (CreateProcessW(NULL, command, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) { |
137 | CloseHandle( pi.hProcess ); |
138 | ( pi.hThread ); |
139 | TerminateProcess(GetCurrentProcess(), 1); |
140 | } |
141 | |
142 | return false; |
143 | #else |
144 | pid_t pid = fork(); |
145 | |
146 | if (pid == -1) { |
147 | return false; |
148 | } else if (pid == 0) { |
149 | execl(CRASH_REPORTER_BINARY, CRASH_REPORTER_BINARY, dumpPath, minidumpID, (char*)0); |
150 | } |
151 | #ifdef Q_WS_X11 |
152 | abort(); |
153 | #endif |
154 | return true; |
155 | #endif |
156 | } |
157 | |
158 | // Copied from Qt's QString class because of weird linking errors |
159 | int toWCharArray(const QString str, wchar_t *array) |
160 | { |
161 | if (sizeof(wchar_t) == sizeof(QChar)) { |
162 | memcpy(array, str.utf16(), sizeof(wchar_t)*str.length()); |
163 | return str.length(); |
164 | } else { |
165 | wchar_t *a = array; |
166 | const unsigned short *uc = str.utf16(); |
167 | for (int i = 0; i < str.length(); ++i) { |
168 | uint u = uc[i]; |
169 | if (u >= 0xd800 && u < 0xdc00 && i < str.length()-1) { |
170 | ushort low = uc[i+1]; |
171 | if (low >= 0xdc00 && low < 0xe000) { |
172 | ++i; |
173 | u = (u - 0xd800)*0x400 + (low - 0xdc00) + 0x10000; |
174 | } |
175 | } |
176 | *a = wchar_t(u); |
177 | ++a; |
178 | } |
179 | return a - array; |
180 | } |
181 | } |
182 | |
183 | KisCrashHandler::KisCrashHandler() |
184 | { |
185 | |
186 | QString tempPath = QDesktopServices::storageLocation(QDesktopServices::TempLocation); |
187 | |
188 | #ifdef Q_WS_WIN |
189 | qDebug() << "Installing CrashHandler"<< tempPath; |
190 | typedef std::basic_string<wchar_t> wstring; |
191 | wstring str; |
192 | str.resize(tempPath.length()); |
193 | str.resize(toWCharArray(tempPath, &(*str.begin()))); |
194 | exceptionHandler = new google_breakpad::ExceptionHandler(str, 0, |
195 | startCrashReporter, 0, |
196 | google_breakpad::ExceptionHandler::HANDLER_ALL); |
197 | |
198 | #else |
199 | qDebug() << "Installing CrashHandler"; // do not remove this line; it is needed to make it work on linux. |
200 | |
201 | exceptionHandler = new google_breakpad::ExceptionHandler(tempPath.toStdString(), 0, |
202 | startCrashReporter, 0, |
203 | true); |
204 | #endif |
205 | Q_CHECK_PTR(exceptionHandler); |
206 | } |
207 | |
208 | KisCrashHandler::~KisCrashHandler() |
209 | { |
210 | delete exceptionHandler; |
211 | } |
212 |
Warning: That file was not part of the compilation database. It may have many parsing errors.