1 /* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 /*
3  *     Copyright 2016 Couchbase, Inc
4  *
5  *   Licensed under the Apache License, Version 2.0 (the "License");
6  *   you may not use this file except in compliance with the License.
7  *   You may obtain a copy of the License at
8  *
9  *       http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *   Unless required by applicable law or agreed to in writing, software
12  *   distributed under the License is distributed on an "AS IS" BASIS,
13  *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *   See the License for the specific language governing permissions and
15  *   limitations under the License.
16  */
17 
18 #include "breakpad.h"
19 
20 #include "client/windows/handler/exception_handler.h"
21 
22 #include <stdio.h>
23 #include <stdlib.h>
24 
25 using namespace google_breakpad;
26 static ExceptionHandler* handler = nullptr;
27 
28 /* Called when an exception triggers a dump, outputs details to caller's logs */
dumpCallback(const wchar_t* dump_path, const wchar_t* minidump_id, void* context, EXCEPTION_POINTERS* exinfo, MDRawAssertionInfo* assertion, bool succeeded)29 static bool dumpCallback(const wchar_t* dump_path, const wchar_t* minidump_id,
30                          void* context, EXCEPTION_POINTERS* exinfo,
31                          MDRawAssertionInfo* assertion, bool succeeded) {
32     fprintf(stderr, "Breakpad caught a crash in forestdb. Writing crash dump "
33             "to %S\\%S before terminating.\n", dump_path, minidump_id);
34 
35     return succeeded;
36 }
37 
create_breakpad(const char* minidump_dir)38 static void create_breakpad(const char* minidump_dir) {
39     // Takes a wchar_t* on Windows.
40     size_t len = strlen(minidump_dir) + 1;
41     wchar_t* wc_minidump_dir = new wchar_t[len];
42     size_t wlen = 0;
43     mbstowcs_s(&wlen, wc_minidump_dir, len, minidump_dir, _TRUNCATE);
44 
45     handler = new ExceptionHandler(wc_minidump_dir,
46                                    /*filter*/nullptr,
47                                    dumpCallback,
48                                    /*callback-context*/NULL,
49                                    ExceptionHandler::HANDLER_ALL,
50                                    MiniDumpNormal,
51                                    /*pipe*/(wchar_t*) nullptr,
52                                    /*custom_info*/nullptr);
53 
54     delete[] wc_minidump_dir;
55 }
56 
initialize_breakpad(const char* minidump_dir)57 void initialize_breakpad(const char* minidump_dir) {
58     // We cannot actually change any of breakpad's setings once created, only
59     // remove it and re-create with new settings.
60     destroy_breakpad();
61 
62     if (minidump_dir != nullptr && minidump_dir[0] != '\0') {
63         create_breakpad(minidump_dir);
64     }
65 }
66 
destroy_breakpad(void)67 void destroy_breakpad(void) {
68     delete handler;
69     handler = nullptr;
70 }
71