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
92typedef 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
97typedef char HD_CHAR;
98#define CRASH_REPORTER_BINARY "crashhandler"
99#endif
100
101static 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.
107static 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
159int 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
183KisCrashHandler::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
208KisCrashHandler::~KisCrashHandler()
209{
210 delete exceptionHandler;
211}
212

Warning: That file was not part of the compilation database. It may have many parsing errors.