summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--desktop/source/app/app.cxx62
-rw-r--r--desktop/source/app/crashreport.cxx15
-rw-r--r--desktop/source/app/sofficemain.cxx22
-rw-r--r--include/desktop/crashreport.hxx5
-rw-r--r--svx/Library_svx.mk5
-rw-r--r--svx/UIConfig_svx.mk1
-rw-r--r--svx/source/dialog/crashreportdlg.cxx73
-rw-r--r--svx/source/dialog/crashreportdlg.hxx36
-rw-r--r--svx/source/dialog/crashreportui.cxx100
-rw-r--r--svx/uiconfig/ui/crashreportdlg.ui67
-rw-r--r--svx/util/svx.component4
11 files changed, 365 insertions, 25 deletions
diff --git a/desktop/source/app/app.cxx b/desktop/source/app/app.cxx
index cc69bbb60257..3d0435b43b07 100644
--- a/desktop/source/app/app.cxx
+++ b/desktop/source/app/app.cxx
@@ -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();
diff --git a/desktop/source/app/crashreport.cxx b/desktop/source/app/crashreport.cxx
index 1ded7f0ed80e..6d148c56157d 100644
--- a/desktop/source/app/crashreport.cxx
+++ b/desktop/source/app/crashreport.cxx
@@ -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";
diff --git a/desktop/source/app/sofficemain.cxx b/desktop/source/app/sofficemain.cxx
index 866c19859f10..3484b8437737 100644
--- a/desktop/source/app/sofficemain.cxx
+++ b/desktop/source/app/sofficemain.cxx
@@ -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");
diff --git a/include/desktop/crashreport.hxx b/include/desktop/crashreport.hxx
index b9bbb7ce01bf..c6d72be92ffb 100644
--- a/include/desktop/crashreport.hxx
+++ b/include/desktop/crashreport.hxx
@@ -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:
diff --git a/svx/Library_svx.mk b/svx/Library_svx.mk
index 296312d2aa27..8869014381a7 100644
--- a/svx/Library_svx.mk
+++ b/svx/Library_svx.mk
@@ -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 \
diff --git a/svx/UIConfig_svx.mk b/svx/UIConfig_svx.mk
index 650ecf917408..39df1db7c2b8 100644
--- a/svx/UIConfig_svx.mk
+++ b/svx/UIConfig_svx.mk
@@ -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 \
diff --git a/svx/source/dialog/crashreportdlg.cxx b/svx/source/dialog/crashreportdlg.cxx
new file mode 100644
index 000000000000..74066a8dea7e
--- /dev/null
+++ b/svx/source/dialog/crashreportdlg.cxx
@@ -0,0 +1,73 @@
+/* -*- 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: */
diff --git a/svx/source/dialog/crashreportdlg.hxx b/svx/source/dialog/crashreportdlg.hxx
new file mode 100644
index 000000000000..e6041f88f325
--- /dev/null
+++ b/svx/source/dialog/crashreportdlg.hxx
@@ -0,0 +1,36 @@
+/* -*- 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: */
diff --git a/svx/source/dialog/crashreportui.cxx b/svx/source/dialog/crashreportui.cxx
new file mode 100644
index 000000000000..28cac67a3ab5
--- /dev/null
+++ b/svx/source/dialog/crashreportui.cxx
@@ -0,0 +1,100 @@
+/* -*- 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: */
diff --git a/svx/uiconfig/ui/crashreportdlg.ui b/svx/uiconfig/ui/crashreportdlg.ui
new file mode 100644
index 000000000000..e8d1355e7202
--- /dev/null
+++ b/svx/uiconfig/ui/crashreportdlg.ui
@@ -0,0 +1,67 @@
+<?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>
diff --git a/svx/util/svx.component b/svx/util/svx.component
index 3f0e38e1eba3..31c8005fd692 100644
--- a/svx/util/svx.component
+++ b/svx/util/svx.component
@@ -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"/>