Kaydet (Commit) b78209ae authored tarafından Markus Mohrhard's avatar Markus Mohrhard

work on adding crash report UI

Change-Id: I66f4dca3cd32381ecd52cc36490e7ee1dddf3699
Reviewed-on: https://gerrit.libreoffice.org/22566Tested-by: 's avatarJenkins <ci@libreoffice.org>
Reviewed-by: 's avatarMarkus Mohrhard <markus.mohrhard@googlemail.com>
üst 65694793
......@@ -105,6 +105,7 @@
#include <svl/itemset.hxx>
#include <svl/eitem.hxx>
#include <basic/sbstar.hxx>
#include <desktop/crashreport.hxx>
#include <svtools/fontsubstconfig.hxx>
#include <svtools/accessibilityoptions.hxx>
......@@ -119,6 +120,10 @@
#include <tubes/manager.hxx>
#endif
#if HAVE_FEATURE_BREAKPAD
#include <fstream>
#endif
#if defined MACOSX
#include <errno.h>
#include <sys/wait.h>
......@@ -1017,6 +1022,50 @@ bool Desktop::isUIOnSessionShutdownAllowed()
::get();
}
namespace {
bool crashReportInfoExists()
{
#if HAVE_FEATURE_BREAKPAD
std::string path = CrashReporter::getIniFileName();
std::ifstream aFile(path);
while (!aFile.eof())
{
std::string line;
std::getline(aFile, line);
int sep = line.find('=');
if (sep >= 0)
{
std::string key = line.substr(0, sep);
std::string value = line.substr(sep + 1);
if (key == "DumpFile")
return true;
}
}
#endif
return false;
}
#if HAVE_FEATURE_BREAKPAD
void handleCrashReport()
{
static const char SERVICENAME_CRASHREPORT[] = "com.sun.star.comp.svx.CrashReportUI";
css::uno::Reference< css::uno::XComponentContext > xContext = ::comphelper::getProcessComponentContext();
Reference< css::frame::XSynchronousDispatch > xRecoveryUI(
xContext->getServiceManager()->createInstanceWithContext(SERVICENAME_CRASHREPORT, xContext),
css::uno::UNO_QUERY_THROW);
Reference< css::util::XURLTransformer > xURLParser =
css::util::URLTransformer::create(::comphelper::getProcessComponentContext());
css::util::URL aURL;
css::uno::Any aRet = xRecoveryUI->dispatchWithReturnValue(aURL, css::uno::Sequence< css::beans::PropertyValue >());
bool bRet = false;
aRet >>= bRet;
}
#endif
/** @short check if recovery must be started or not.
......@@ -1038,7 +1087,7 @@ void impl_checkRecoveryState(bool& bCrashed ,
bool& bRecoveryDataExists,
bool& bSessionDataExists )
{
bCrashed = officecfg::Office::Recovery::RecoveryInfo::Crashed::get();
bCrashed = officecfg::Office::Recovery::RecoveryInfo::Crashed::get() || crashReportInfoExists();
bool elements = officecfg::Office::Recovery::RecoveryList::get()->
hasElements();
bool session
......@@ -1085,6 +1134,8 @@ bool impl_callRecoveryUI(bool bEmergencySave ,
return !bEmergencySave || bRet;
}
}
/*
* Save all open documents so they will be reopened
* the next time the application is started
......@@ -1092,7 +1143,6 @@ bool impl_callRecoveryUI(bool bEmergencySave ,
* returns sal_True if at least one document could be saved...
*
*/
bool Desktop::SaveTasks()
{
return impl_callRecoveryUI(
......@@ -2218,6 +2268,11 @@ void Desktop::OpenClients()
// need some time, where the user won't see any results and wait for finishing the office startup...
bool bAllowRecoveryAndSessionManagement = ( !rArgs.IsNoRestore() ) && ( !rArgs.IsHeadless() );
#if HAVE_FEATURE_BREAKPAD
if (crashReportInfoExists())
handleCrashReport();
#endif
if ( ! bAllowRecoveryAndSessionManagement )
{
try
......@@ -2292,6 +2347,9 @@ void Desktop::OpenClients()
}
}
}
#if HAVE_FEATURE_BREAKPAD
CrashReporter::writeCommonInfo();
#endif
OfficeIPCThread::EnableRequests();
......
......@@ -9,6 +9,8 @@
#include <desktop/crashreport.hxx>
#include <config_version.h>
#include <string>
#include <fstream>
......@@ -27,7 +29,18 @@ void CrashReporter::AddKeyValue(const OUString& rKey, const OUString& rValue)
#endif
const char* CrashReporter::getIniFileName()
void CrashReporter::writeCommonInfo()
{
// limit the amount of code that needs to be executed before the crash reporting
std::string ini_path = CrashReporter::getIniFileName();
std::ofstream minidump_file(ini_path, std::ios_base::trunc);
minidump_file << "ProductName=LibreOffice\n";
minidump_file << "Version=" << LIBO_VERSION_DOTTED << "\n";
minidump_file << "URL=" << "http://127.0.0.1:8000/submit" << "\n";
minidump_file.close();
}
std::string CrashReporter::getIniFileName()
{
// TODO: we need a generic solution for the location
return "/tmp/dump.ini";
......
......@@ -65,14 +65,6 @@
#if HAVE_FEATURE_BREAKPAD
OString getLibDir()
{
OUString aOriginal = "$BRAND_BASE_DIR/" LIBO_LIBEXEC_FOLDER;
rtl::Bootstrap::expandMacros(aOriginal);
return rtl::OUStringToOString(aOriginal, RTL_TEXTENCODING_UTF8);
}
#if defined( UNX ) && !defined MACOSX && !defined IOS && !defined ANDROID
static bool dumpCallback(const google_breakpad::MinidumpDescriptor& descriptor, void* /*context*/, bool succeeded)
{
......@@ -80,11 +72,7 @@ static bool dumpCallback(const google_breakpad::MinidumpDescriptor& descriptor,
std::ofstream minidump_file(ini_path, std::ios_base::app);
minidump_file << "DumpFile=" << descriptor.path() << "\n";;
minidump_file.close();
// send the minidump to the server (not yet implemented)
SAL_WARN("destkop.crashreport", "minidump generated: " << descriptor.path());
OString aCommand = getLibDir().copy(7) + "/minidump_upload " + ini_path.c_str();
int retVal = std::system(aCommand.getStr());
SAL_WARN_IF(retVal != 0, "destkop.crashreport", "Failed to upload minidump. Error Code: " << retVal);
SAL_WARN("crashreport", "minidump generated: " << descriptor.path());
return succeeded;
}
#endif
......@@ -93,14 +81,6 @@ static bool dumpCallback(const google_breakpad::MinidumpDescriptor& descriptor,
extern "C" int DESKTOP_DLLPUBLIC soffice_main()
{
#if HAVE_FEATURE_BREAKPAD
//limit the amount of code that needs to be executed before the crash reporting
std::string ini_path = CrashReporter::getIniFileName();
std::ofstream minidump_file(ini_path, std::ios_base::trunc);
minidump_file << "ProductName=LibreOffice\n";
minidump_file << "Version=" LIBO_VERSION_DOTTED "\n";
minidump_file << "URL=http://127.0.0.1:8000/submit\n";
minidump_file.close();
#if defined( UNX ) && !defined MACOSX && !defined IOS && !defined ANDROID
google_breakpad::MinidumpDescriptor descriptor("/tmp");
......
......@@ -18,6 +18,7 @@
#include <config_features.h>
#include <map>
#include <string>
/**
* Provides access to the crash reporter service.
......@@ -32,7 +33,9 @@ class CRASHREPORT_DLLPUBLIC CrashReporter
public:
static void AddKeyValue(const OUString& rKey, const OUString& rValue);
static const char* getIniFileName();
static std::string getIniFileName();
static void writeCommonInfo();
private:
......
......@@ -46,6 +46,8 @@ $(eval $(call gb_Library_use_libraries,svx,\
comphelper \
cppuhelper \
cppu \
$(call gb_Helper_optional,BREAKPAD, \
crashreport) \
$(call gb_Helper_optional,DBCONNECTIVITY, \
dbtools) \
drawinglayer \
......@@ -108,6 +110,9 @@ $(eval $(call gb_Library_add_exception_objects,svx,\
svx/source/dialog/_contdlg \
svx/source/dialog/contwnd \
svx/source/dialog/compressgraphicdialog \
$(call gb_Helper_optional,BREAKPAD, \
svx/source/dialog/crashreportdlg \
svx/source/dialog/crashreportui) \
svx/source/dialog/ctredlin \
svx/source/dialog/databaseregistrationui \
svx/source/dialog/dialcontrol \
......
......@@ -22,6 +22,7 @@ $(eval $(call gb_UIConfig_add_uifiles,svx,\
svx/uiconfig/ui/chinesedictionary \
svx/uiconfig/ui/colorwindow \
svx/uiconfig/ui/compressgraphicdialog \
svx/uiconfig/ui/crashreportdlg \
svx/uiconfig/ui/datanavigator \
svx/uiconfig/ui/deleteheaderdialog \
svx/uiconfig/ui/deletefooterdialog \
......
/* -*- 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/.
*/
#include "crashreportdlg.hxx"
#include <config_folders.h>
#include <rtl/bootstrap.hxx>
#include <desktop/crashreport.hxx>
CrashReportDialog::CrashReportDialog(vcl::Window* pParent):
Dialog(pParent, "CrashReportDialog",
"svx/ui/crashreportdlg.ui")
{
get(mpBtnSend, "btn_send");
get(mpBtnCancel, "btn_cancel");
mpBtnSend->SetClickHdl(LINK(this, CrashReportDialog, BtnHdl));
mpBtnCancel->SetClickHdl(LINK(this, CrashReportDialog, BtnHdl));
}
CrashReportDialog::~CrashReportDialog()
{
disposeOnce();
}
void CrashReportDialog::dispose()
{
mpBtnSend.clear();
mpBtnCancel.clear();
Dialog::dispose();
}
namespace {
OString getLibDir()
{
OUString aOriginal = "$BRAND_BASE_DIR/" LIBO_LIBEXEC_FOLDER;
rtl::Bootstrap::expandMacros(aOriginal);
return rtl::OUStringToOString(aOriginal, RTL_TEXTENCODING_UTF8);
}
}
IMPL_LINK_TYPED(CrashReportDialog, BtnHdl, Button*, pBtn, void)
{
if (pBtn == mpBtnSend.get())
{
std::string ini_path = CrashReporter::getIniFileName();
OString aCommand = getLibDir().copy(7) + "/minidump_upload " + ini_path.c_str();
int retVal = std::system(aCommand.getStr());
SAL_WARN_IF(retVal != 0, "crashreport", "Failed to upload minidump. Error Code: " << retVal);
Close();
}
else if (pBtn == mpBtnCancel.get())
{
Close();
}
else
{
assert(false);
}
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
/* -*- 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_SVX_SOURCE_DIALOG_CRASHREPORTDLG_HXX
#define INCLUDED_SVX_SOURCE_DIALOG_CRASHREPORTDLG_HXX
#include <vcl/dialog.hxx>
#include <vcl/button.hxx>
class CrashReportDialog : public Dialog
{
public:
CrashReportDialog(vcl::Window* pParent);
~CrashReportDialog();
virtual void dispose() override;
private:
VclPtr<Button> mpBtnSend;
VclPtr<Button> mpBtnCancel;
DECL_LINK_TYPED(BtnHdl, Button*, void);
};
#endif
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
/* -*- 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/.
*/
#include <cppuhelper/implbase.hxx>
#include <com/sun/star/frame/XSynchronousDispatch.hpp>
#include <com/sun/star/lang/XServiceInfo.hpp>
#include <comphelper/processfactory.hxx>
#include <cppuhelper/supportsservice.hxx>
#include <vcl/svapp.hxx>
#include "crashreportdlg.hxx"
namespace {
class CrashReportUI : public ::cppu::WeakImplHelper< css::lang::XServiceInfo ,
css::frame::XSynchronousDispatch > // => XDispatch!
{
public:
CrashReportUI(const css::uno::Reference< css::uno::XComponentContext >& xContext);
virtual ~CrashReportUI();
// css.lang.XServiceInfo
virtual OUString SAL_CALL getImplementationName()
throw(css::uno::RuntimeException, std::exception) override;
virtual sal_Bool SAL_CALL supportsService(const OUString& sServiceName)
throw(css::uno::RuntimeException, std::exception) override;
virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames()
throw(css::uno::RuntimeException, std::exception) override;
virtual css::uno::Any SAL_CALL dispatchWithReturnValue(const css::util::URL& aURL,
const css::uno::Sequence< css::beans::PropertyValue >& lArguments )
throw(css::uno::RuntimeException, std::exception) override;
private:
css::uno::Reference< css::uno::XComponentContext > mxContext;
};
CrashReportUI::CrashReportUI(const css::uno::Reference<css::uno::XComponentContext>& xContext):
mxContext(xContext)
{
}
CrashReportUI::~CrashReportUI()
{
}
OUString SAL_CALL CrashReportUI::getImplementationName()
throw(css::uno::RuntimeException, std::exception)
{
return OUString("com.sun.star.comp.svx.CrashReportUI");
}
sal_Bool SAL_CALL CrashReportUI::supportsService(const OUString& sServiceName)
throw(css::uno::RuntimeException, std::exception)
{
return cppu::supportsService(this, sServiceName);
}
css::uno::Sequence< OUString > SAL_CALL CrashReportUI::getSupportedServiceNames()
throw(css::uno::RuntimeException, std::exception)
{
css::uno::Sequence< OUString > lServiceNames { "com.sun.star.dialog.CrashReportUI" };
return lServiceNames;
}
css::uno::Any SAL_CALL CrashReportUI::dispatchWithReturnValue(const css::util::URL&,
const css::uno::Sequence< css::beans::PropertyValue >& )
throw(css::uno::RuntimeException, std::exception)
{
SolarMutexGuard aGuard;
css::uno::Any aRet;
ScopedVclPtrInstance<CrashReportDialog> xDialog(new CrashReportDialog(nullptr));
xDialog->Execute();
return aRet;
}
}
extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface * SAL_CALL
com_sun_star_comp_svx_CrashReportUI_get_implementation(
css::uno::XComponentContext *context,
css::uno::Sequence<css::uno::Any> const &)
{
return cppu::acquire(new CrashReportUI(context));
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.18.3 -->
<interface>
<requires lib="gtk+" version="3.12"/>
<object class="GtkDialog" id="CrashReportDialog">
<property name="can_focus">False</property>
<property name="type_hint">dialog</property>
<child internal-child="vbox">
<object class="GtkBox" id="dialog-vbox1">
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<property name="spacing">2</property>
<child internal-child="action_area">
<object class="GtkButtonBox" id="dialog-action_area1">
<property name="can_focus">False</property>
<property name="layout_style">end</property>
<child>
<object class="GtkButton" id="btn_send">
<property name="label" translatable="yes">Send report</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="btn_cancel">
<property name="label" translatable="yes">Don't send report</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">We are sorry but it seems that LibreOffice crashed the last time.
You can help us fix this issue by sending the crash report to the
LibreOffice crash reporting server.</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
</object>
</interface>
......@@ -32,6 +32,10 @@
constructor="com_sun_star_comp_svx_RecoveryUI_get_implementation">
<service name="com.sun.star.dialog.RecoveryUI"/>
</implementation>
<implementation name="com.sun.star.comp.svx.CrashReportUI"
constructor="com_sun_star_comp_svx_CrashReportUI_get_implementation">
<service name="com.sun.star.dialog.CrashReportUI"/>
</implementation>
<implementation name="com.sun.star.drawing.EnhancedCustomShapeEngine"
constructor="com_sun_star_drawing_EnhancedCustomShapeEngine_get_implementation">
<service name="com.sun.star.drawing.CustomShapeEngine"/>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment