office-gobmx/include/desktop/crashreport.hxx
Mike Kaganski 12b5892cf9 Delete google_breakpad::ExceptionHandler before calling _exit()
While debugging tdf#129712 on Windows, I saw this sequence:

1. nullptr was dereferenced (the reason for tdf#129712).
2. ExceptionHandler::HandleException was called (in
   workdir/UnpackedTarball/breakpad/src/client/windows/handler/exception_handler.cc).
3. It called ExceptionHandler::WriteMinidumpOnHandlerThread.
4. Minidump was created in ExceptionHandler::ExceptionHandlerThreadMain.
5. Document Recovery dialog was shown in Desktop::Exception (in
   desktop/source/app/app.cxx).
6. After closing dialog, _exit() was called in Desktop::Exception.
7. All threads except main were terminated.
8. Another access violation was thrown in the "minimal CRT cleanup".
9. ExceptionHandler::HandleException called again.
10. ExceptionHandler::WriteMinidumpOnHandlerThread hung on WaitForSingleObject
    because handler thread that should release the semaphore was terminated
    already at step 7.

The process had to be killed manually.

This change destroys the breakpad handler at the start of Desktop::Exception,
which de-registers itself (on Windows it uses SetUnhandledExceptionFilter).
Other than preventing the hang, the rationale also is that keeping the handler
after first minidump creation is wrong: even if the second minidump creation
succeeded, uploading it to crashdump server would give not the actual problem,
but some unrelated stack.

Change-Id: If12d0c7db519693f733b5ab3b8a288cef800a149
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/86104
Reviewed-by: Markus Mohrhard <markus.mohrhard@googlemail.com>
Tested-by: Mike Kaganski <mike.kaganski@collabora.com>
2020-01-10 18:05:01 +01:00

95 lines
2.7 KiB
C++

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#ifndef INCLUDED_DESKTOP_CRASHREPORT_HXX
#define INCLUDED_DESKTOP_CRASHREPORT_HXX
#include <desktop/dllapi.h>
#include <rtl/ustring.hxx>
#include <osl/mutex.hxx>
#include <config_features.h>
// vector not sort the entries
#include <memory>
#include <vector>
#include <string>
namespace google_breakpad
{
class ExceptionHandler;
}
/**
* Provides access to the crash reporter service.
*
* Valid keys are:
* * AdapterVendorId
* * AdapterDeviceId
*
*/
class
#if HAVE_FEATURE_BREAKPAD
// MSVC 2013 has undefined symbols for inline functions if it's exported
CRASHREPORT_DLLPUBLIC
#endif
/*class*/ CrashReporter
{
public:
typedef enum {AddItem, Write, Create} tAddKeyHandling;
#if HAVE_FEATURE_BREAKPAD
static void addKeyValue(const OUString& rKey, const OUString& rValue, tAddKeyHandling AddKeyHandling);
static void installExceptionHandler();
static void removeExceptionHandler();
static bool crashReportInfoExists();
static bool readSendConfig(std::string& response);
static bool IsDumpEnable();
private:
static osl::Mutex maMutex;
static bool mbInit;
typedef struct _mpair
{
OUString first;
OUString second;
_mpair(const OUString& First, const OUString& Second)
{
first = First;
second = Second;
};
} mpair;
typedef std::vector<mpair> vmaKeyValues;
static vmaKeyValues maKeyValues; // used to temporarily save entries before the old info has been uploaded
static std::unique_ptr<google_breakpad::ExceptionHandler> mpExceptionHandler;
static std::string getIniFileName();
static void writeCommonInfo();
static void writeToFile(std::ios_base::openmode Openmode);
// when we create the ExceptionHandler we have no access to the user
// profile yet, so update when we have access
static void updateMinidumpLocation();
#else
// Add dummy methods for the non-breakpad case. That allows us to use
// // the code without linking to the lib and without adding HAVE_FEATURE_BREAKPAD
// // everywhere we want to log something to the crash report system.
inline static void addKeyValue(SAL_UNUSED_PARAMETER const OUString& /*rKey*/, SAL_UNUSED_PARAMETER const OUString& /*rValue*/, SAL_UNUSED_PARAMETER tAddKeyHandling /*AddKeyHandling*/) {};
#endif // HAVE_FEATURE_BREAKPAD
};
#endif // INCLUDED_DESKTOP_CRASHREPORT_HXX
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */