[Libreoffice-commits] core.git: Branch 'feature/breakpad' - 29 commits - bin/symbolstore.py bin/upload_symbols.py config_host/config_features.h.in config_host.mk.in configure.ac desktop/Executable_minidump_upload.mk desktop/inc desktop/Library_crashreport.mk desktop/Library_sofficeapp.mk desktop/Module_desktop.mk desktop/source distro-configs/LibreOfficeLinux.conf download.lst external/breakpad external/Module_external.mk include/desktop include/vcl Makefile.fetch RepositoryExternal.mk Repository.mk sc/source svx/Library_svx.mk svx/source svx/uiconfig svx/UIConfig_svx.mk svx/util vcl/inc vcl/Library_vcl.mk vcl/opengl vcl/source

Markus Mohrhard markus.mohrhard at googlemail.com
Sat Feb 20 14:07:16 UTC 2016


Rebased ref, commits from common ancestor:
commit f2f5b7a3ed2504b93957800875afd6484505aee6
Author: Markus Mohrhard <markus.mohrhard at googlemail.com>
Date:   Sun Feb 7 16:21:13 2016 +0100

    fix indetation
    
    Change-Id: Iea12f654d737cfdadae99461ff996220fcb7901c

diff --git a/sc/source/filter/lotus/filter.cxx b/sc/source/filter/lotus/filter.cxx
index 06e9ba2..bc87806 100644
--- a/sc/source/filter/lotus/filter.cxx
+++ b/sc/source/filter/lotus/filter.cxx
@@ -47,12 +47,12 @@ generate_Opcodes(LotusContext &rContext, SvStream& aStream,
     {
         case eWK_1:
         case eWK_2:
-        pOps = rContext.pOpFkt;
-        nOps = FKT_LIMIT;
+            pOps = rContext.pOpFkt;
+            nOps = FKT_LIMIT;
         break;
         case eWK123:
-        pOps = rContext.pOpFkt123;
-        nOps = FKT_LIMIT123;
+            pOps = rContext.pOpFkt123;
+            nOps = FKT_LIMIT123;
         break;
         case eWK3:      return eERR_NI;
         case eWK_Error: return eERR_FORMAT;
commit 73587b69902e3d9e79b327a92a9d0af8f987ef19
Author: Markus Mohrhard <markus.mohrhard at googlemail.com>
Date:   Wed Feb 3 20:28:40 2016 +0100

    tdf#93300, handle hard formatting with cond format correct
    
    For number formats we always applied the conditional format above the
    hard formatting.
    
    Now we handle styles, conditional formatting and hard formatting
    correctly.
    
    Change-Id: I52dbeeb848b982985d6b17dad920baedffb218e4

diff --git a/sc/source/core/data/patattr.cxx b/sc/source/core/data/patattr.cxx
index eead1a6..fccfb43 100644
--- a/sc/source/core/data/patattr.cxx
+++ b/sc/source/core/data/patattr.cxx
@@ -1291,12 +1291,24 @@ bool ScPatternAttr::IsSymbolFont() const
         return false;
 }
 
+namespace {
+
+sal_uInt32 getNumberFormatKey(const SfxItemSet& rSet)
+{
+    return static_cast<const SfxUInt32Item&>(rSet.Get(ATTR_VALUE_FORMAT)).GetValue();
+}
+
+LanguageType getLanguageType(const SfxItemSet& rSet)
+{
+    return static_cast<const SvxLanguageItem&>(rSet.Get(ATTR_LANGUAGE_FORMAT)).GetLanguage();
+}
+
+}
+
 sal_uLong ScPatternAttr::GetNumberFormat( SvNumberFormatter* pFormatter ) const
 {
-    sal_uLong nFormat =
-        static_cast<const SfxUInt32Item*>(&GetItemSet().Get( ATTR_VALUE_FORMAT ))->GetValue();
-    LanguageType eLang =
-        static_cast<const SvxLanguageItem*>(&GetItemSet().Get( ATTR_LANGUAGE_FORMAT ))->GetLanguage();
+    sal_uLong nFormat = getNumberFormatKey(GetItemSet());
+    LanguageType eLang = getLanguageType(GetItemSet());
     if ( nFormat < SV_COUNTRY_LANGUAGE_OFFSET && eLang == LANGUAGE_SYSTEM )
         ;       // it remains as it is
     else if ( pFormatter )
@@ -1313,17 +1325,33 @@ sal_uLong ScPatternAttr::GetNumberFormat( SvNumberFormatter* pFormatter,
     if (!pCondSet)
         return GetNumberFormat(pFormatter);
 
+    /* In the case of a conditional format we need to overwrite a cell style
+     * but leave a hard cell formatting alone. So check first if the number
+     * format is set in the cell format, then the conditional format and
+     * finally in the style.
+     *
+     * The style is represented here if the name is empty.
+     */
+
     const SfxPoolItem* pFormItem;
-    if ( pCondSet->GetItemState(ATTR_VALUE_FORMAT,true,&pFormItem) != SfxItemState::SET )
-        pFormItem = &GetItemSet().Get(ATTR_VALUE_FORMAT);
+    sal_uLong nFormat = 0;
+    if (GetItemSet().GetItemState(ATTR_VALUE_FORMAT, false, &pFormItem) == SfxItemState::SET)
+        nFormat = static_cast<const SfxUInt32Item*>(pFormItem)->GetValue();
+    else if (pCondSet->GetItemState(ATTR_VALUE_FORMAT, true, &pFormItem) == SfxItemState::SET )
+        nFormat = getNumberFormatKey(*pCondSet);
+    else
+        nFormat = getNumberFormatKey(GetItemSet());
 
     const SfxPoolItem* pLangItem;
-    if ( pCondSet->GetItemState(ATTR_LANGUAGE_FORMAT,true,&pLangItem) != SfxItemState::SET )
-        pLangItem = &GetItemSet().Get(ATTR_LANGUAGE_FORMAT);
+    LanguageType eLang;
+    if (GetItemSet().GetItemState(ATTR_LANGUAGE_FORMAT, false, &pLangItem) == SfxItemState::SET)
+        eLang = static_cast<const SvxLanguageItem*>(pLangItem)->GetLanguage();
+    else if (pCondSet->GetItemState(ATTR_LANGUAGE_FORMAT, true, &pLangItem) == SfxItemState::SET)
+        eLang = getLanguageType(*pCondSet);
+    else
+        eLang = getLanguageType(GetItemSet());
 
-    return pFormatter->GetFormatForLanguageIfBuiltIn(
-                    static_cast<const SfxUInt32Item*>(pFormItem)->GetValue(),
-                    static_cast<const SvxLanguageItem*>(pLangItem)->GetLanguage() );
+    return pFormatter->GetFormatForLanguageIfBuiltIn(nFormat, eLang);
 }
 
 const SfxPoolItem& ScPatternAttr::GetItem( sal_uInt16 nWhich, const SfxItemSet& rItemSet, const SfxItemSet* pCondSet )
commit cfd8c58d4750610c018b2af11102ea9fa27e9e16
Author: Markus Mohrhard <markus.mohrhard at googlemail.com>
Date:   Wed Feb 3 05:02:41 2016 +0100

    simplify code a bit
    
    Change-Id: Iffc3fa3240750892e40393c147acc6ba32cec117

diff --git a/sc/source/core/data/patattr.cxx b/sc/source/core/data/patattr.cxx
index 61d8879..eead1a6 100644
--- a/sc/source/core/data/patattr.cxx
+++ b/sc/source/core/data/patattr.cxx
@@ -1309,14 +1309,16 @@ sal_uLong ScPatternAttr::GetNumberFormat( SvNumberFormatter* pFormatter ) const
 sal_uLong ScPatternAttr::GetNumberFormat( SvNumberFormatter* pFormatter,
                                         const SfxItemSet* pCondSet ) const
 {
-    OSL_ENSURE(pFormatter,"GetNumberFormat without Formatter");
+    assert(pFormatter);
+    if (!pCondSet)
+        return GetNumberFormat(pFormatter);
 
     const SfxPoolItem* pFormItem;
-    if ( !pCondSet || pCondSet->GetItemState(ATTR_VALUE_FORMAT,true,&pFormItem) != SfxItemState::SET )
+    if ( pCondSet->GetItemState(ATTR_VALUE_FORMAT,true,&pFormItem) != SfxItemState::SET )
         pFormItem = &GetItemSet().Get(ATTR_VALUE_FORMAT);
 
     const SfxPoolItem* pLangItem;
-    if ( !pCondSet || pCondSet->GetItemState(ATTR_LANGUAGE_FORMAT,true,&pLangItem) != SfxItemState::SET )
+    if ( pCondSet->GetItemState(ATTR_LANGUAGE_FORMAT,true,&pLangItem) != SfxItemState::SET )
         pLangItem = &GetItemSet().Get(ATTR_LANGUAGE_FORMAT);
 
     return pFormatter->GetFormatForLanguageIfBuiltIn(
commit af8e4a3e81b5b2cf40954accb824b853e8aeeabd
Author: Markus Mohrhard <markus.mohrhard at googlemail.com>
Date:   Mon Feb 15 07:44:30 2016 +0100

    remove unneeded case for system breakpad
    
    breakpad is limited to TDF builds so there is no system version support
    needed
    
    Change-Id: I8339037035e03fcd0ecf5c8d930fa7fe78344dd2

diff --git a/RepositoryExternal.mk b/RepositoryExternal.mk
index 8079c1b..86ff6bd 100644
--- a/RepositoryExternal.mk
+++ b/RepositoryExternal.mk
@@ -3362,8 +3362,6 @@ endif # DESKTOP
 
 ifeq ($(ENABLE_BREAKPAD),TRUE)
 
-# ifneq ($(SYSTEM_LIBBREAKPAD),TRUE)
-
 define gb_LinkTarget__use_breakpad
 $(call gb_LinkTarget_set_include,$(1),\
     -I$(call gb_UnpackedTarball_get_dir,breakpad)/src \
@@ -3384,18 +3382,7 @@ $(call gb_LinkTarget_use_external_project,$(1),breakpad)
 
 endef
 
-# else # SYSTEM_LIBBREAKPAD
-# 
-# define gb_LinkTarget__use_libgltf
-# $(call gb_LinkTarget_set_include,$(1),\
-# 	$$(INCLUDE) \
-# 	$(LIBBREAKPAD_CFLAGS) \
-# )
-# $(call gb_LinkTarget_add_libs,$(1),$(LIBBREAKPAD_LIBS))
-#
-# endef
-
-endif # SYSTEN_LIBBREAKPAD
+endif # ENABLE_BREAKPAD
 
 ifeq ($(ENABLE_GLTF),TRUE)
 
commit 38135d4950365f7bc387cd5ae5628698750d6448
Author: David Tardon <dtardon at redhat.com>
Date:   Mon Feb 15 07:52:34 2016 +0100

    AFAICS breakpad does use neither glew nor libgltf
    
    Change-Id: Icfea7b921d990a3d7adcbebbda2cddbc62d8ea39

diff --git a/external/breakpad/ExternalProject_breakpad.mk b/external/breakpad/ExternalProject_breakpad.mk
index 350ad99..c0ea5df 100644
--- a/external/breakpad/ExternalProject_breakpad.mk
+++ b/external/breakpad/ExternalProject_breakpad.mk
@@ -22,8 +22,6 @@ $(call gb_ExternalProject_get_state_target,breakpad,build) :
 			/p:Configuration=$(if $(MSVC_USE_DEBUG_RUNTIME),Debug,Release) \
 			$(if $(filter 120,$(VCVER)),/p:PlatformToolset=v120 /p:VisualStudioVersion=12.0 /ToolsVersion:12.0) \
 			$(if $(filter 140,$(VCVER)),/p:PlatformToolset=v140 /p:VisualStudioVersion=14.0 /ToolsVersion:14.0) \
-			'/p:AdditionalIncludeDirectories=$(subst $(WHITESPACE),;,$(subst /,\,$(strip $(libgltf_AdditionalIncludes))))' \
-			/p:AdditionalLibraryDirectories=$(if $(SYSTEM_GLEW),,"$(subst /,\,$(call gb_UnpackedTarball_get_dir,glew))\lib\$(if $(MSVC_USE_DEBUG_RUNTIME),Debug,Release)\Win32") \
 	,build/win32)
 
 else # !ifeq($(COM),MSC)
commit e7da45fd1853a74ebff828b2b40ae70363e5dd5f
Author: David Tardon <dtardon at redhat.com>
Date:   Mon Feb 15 07:50:25 2016 +0100

    _use_autoconf is not needed
    
    It enables building with gcc wrappers on Windows, which is not used here
    
    Change-Id: I8b27ae9f8952fd3fbae37d17fdddfc1d3b9d5fb6

diff --git a/external/breakpad/ExternalProject_breakpad.mk b/external/breakpad/ExternalProject_breakpad.mk
index 713276e..350ad99 100644
--- a/external/breakpad/ExternalProject_breakpad.mk
+++ b/external/breakpad/ExternalProject_breakpad.mk
@@ -9,8 +9,6 @@
 
 $(eval $(call gb_ExternalProject_ExternalProject,breakpad))
 
-$(eval $(call gb_ExternalProject_use_autoconf,breakpad,build))
-
 $(eval $(call gb_ExternalProject_register_targets,breakpad,\
 	build \
 ))
commit e0cf9d8e68310e3dc148fd4e86f768ebf07bacb1
Author: David Tardon <dtardon at redhat.com>
Date:   Mon Feb 15 07:48:58 2016 +0100

    actually allow gbuild to see breakpad makefiles...
    
    Change-Id: I12ba34f30508c0a888445a2d9b68d48807b74e8c

diff --git a/external/Module_external.mk b/external/Module_external.mk
index 6528629..2512b85 100644
--- a/external/Module_external.mk
+++ b/external/Module_external.mk
@@ -24,6 +24,7 @@ $(eval $(call gb_Module_add_moduledirs,external,\
 	$(call gb_Helper_optional,APACHE_COMMONS,apache-commons) \
 	$(call gb_Helper_optional,APR,apr) \
 	$(call gb_Helper_optional,BOOST,boost) \
+	$(call gb_Helper_optional,BREAKPAD,breakpad) \
 	$(call gb_Helper_optional,BSH,beanshell) \
 	$(call gb_Helper_optional,BZIP2,bzip2) \
 	$(call gb_Helper_optional,CAIRO,cairo) \
commit 1609d3f67787402f82e497a89f2f311797562ea9
Author: Markus Mohrhard <markus.mohrhard at googlemail.com>
Date:   Sun Feb 7 22:54:48 2016 +0100

    add TODO comment for showing the user the generated uuid
    
    Change-Id: I0f54f7e7f3b6b49fda926e7c579bb67c2924a943

diff --git a/svx/source/dialog/crashreportdlg.cxx b/svx/source/dialog/crashreportdlg.cxx
index 74066a8..23f0bbe 100644
--- a/svx/source/dialog/crashreportdlg.cxx
+++ b/svx/source/dialog/crashreportdlg.cxx
@@ -58,6 +58,7 @@ IMPL_LINK_TYPED(CrashReportDialog, BtnHdl, Button*, pBtn, void)
         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);
+        // TODO: moggi: return the id for the user to look it up
         Close();
     }
     else if (pBtn == mpBtnCancel.get())
commit b84c456f4529a5bfca8cfa3ed96428f64f3a6f0b
Author: Markus Mohrhard <markus.mohrhard at googlemail.com>
Date:   Sun Feb 7 19:32:28 2016 +0100

    fix a number of Wshadow warnings in breakpad
    
    Change-Id: I8133e03e4ed21ac1efd9982860276d4776850bba

diff --git a/external/breakpad/UnpackedTarball_breakpad.mk b/external/breakpad/UnpackedTarball_breakpad.mk
index 8424a02..59073eb 100644
--- a/external/breakpad/UnpackedTarball_breakpad.mk
+++ b/external/breakpad/UnpackedTarball_breakpad.mk
@@ -13,6 +13,8 @@ $(eval $(call gb_UnpackedTarball_set_tarball,breakpad,$(BREAKPAD_TARBALL)))
 
 $(eval $(call gb_UnpackedTarball_add_patches,breakpad,\
 	external/breakpad/breakpad-use-correct-http-header.patch.1 \
+	external/breakpad/breakpad-wshadow.patch.1 \
+	external/breakpad/breakpad-wshadow2.patch.1 \
 ))
 
 # vim: set noet sw=4 ts=4:
diff --git a/external/breakpad/breakpad-wshadow.patch.1 b/external/breakpad/breakpad-wshadow.patch.1
new file mode 100644
index 0000000..d696e5b
--- /dev/null
+++ b/external/breakpad/breakpad-wshadow.patch.1
@@ -0,0 +1,232 @@
+Only in breakpad: breakpad-client.pc
+Only in breakpad: breakpad.pc
+Only in breakpad: build.log
+Only in breakpad: config.log
+Only in breakpad: config.status
+Only in breakpad: Makefile
+Only in breakpad/src/client: .deps
+Only in breakpad/src/client: .dirstamp
+Only in breakpad/src/client/linux/crash_generation: crash_generation_client.o
+Only in breakpad/src/client/linux/crash_generation: crash_generation_server.o
+Only in breakpad/src/client/linux/crash_generation: .deps
+Only in breakpad/src/client/linux/crash_generation: .dirstamp
+Only in breakpad/src/client/linux: .dirstamp
+Only in breakpad/src/client/linux/dump_writer_common: .deps
+Only in breakpad/src/client/linux/dump_writer_common: .dirstamp
+Only in breakpad/src/client/linux/dump_writer_common: thread_info.o
+Only in breakpad/src/client/linux/dump_writer_common: ucontext_reader.o
+Only in breakpad/src/client/linux/handler: .deps
+Only in breakpad/src/client/linux/handler: .dirstamp
+Only in breakpad/src/client/linux/handler: exception_handler.o
+diff -ur breakpad.org/src/client/linux/handler/minidump_descriptor.h breakpad/src/client/linux/handler/minidump_descriptor.h
+--- breakpad.org/src/client/linux/handler/minidump_descriptor.h	2016-02-07 19:22:24.329411023 +0100
++++ breakpad/src/client/linux/handler/minidump_descriptor.h	2016-02-07 19:24:28.600438386 +0100
+@@ -55,18 +55,18 @@
+         fd_(-1),
+         size_limit_(-1) {}
+ 
+-  explicit MinidumpDescriptor(const string& directory)
++  explicit MinidumpDescriptor(const string& dir)
+       : mode_(kWriteMinidumpToFile),
+         fd_(-1),
+-        directory_(directory),
++        directory_(dir),
+         c_path_(NULL),
+         size_limit_(-1) {
+     assert(!directory.empty());
+   }
+ 
+-  explicit MinidumpDescriptor(int fd)
++  explicit MinidumpDescriptor(int file_descriptor)
+       : mode_(kWriteMinidumpToFd),
+-        fd_(fd),
++        fd_(file_descriptor),
+         c_path_(NULL),
+         size_limit_(-1) {
+     assert(fd != -1);
+Only in breakpad/src/client/linux/handler: .minidump_descriptor.h.un~
+Only in breakpad/src/client/linux/handler: minidump_descriptor.o
+Only in breakpad/src/client/linux: libbreakpad_client.a
+Only in breakpad/src/client/linux: linux_dumper_unittest_helper
+Only in breakpad/src/client/linux/log: .deps
+Only in breakpad/src/client/linux/log: .dirstamp
+Only in breakpad/src/client/linux/log: log.o
+Only in breakpad/src/client/linux/microdump_writer: .deps
+Only in breakpad/src/client/linux/microdump_writer: .dirstamp
+Only in breakpad/src/client/linux/microdump_writer: microdump_writer.o
+Only in breakpad/src/client/linux/minidump_writer: .deps
+Only in breakpad/src/client/linux/minidump_writer: .dirstamp
+Only in breakpad/src/client/linux/minidump_writer: linux_core_dumper.o
+diff -ur breakpad.org/src/client/linux/minidump_writer/linux_dumper.h breakpad/src/client/linux/minidump_writer/linux_dumper.h
+--- breakpad.org/src/client/linux/minidump_writer/linux_dumper.h	2016-02-07 19:22:24.330410999 +0100
++++ breakpad/src/client/linux/minidump_writer/linux_dumper.h	2016-02-07 19:26:10.870017835 +0100
+@@ -130,15 +130,15 @@
+                                    uint8_t identifier[sizeof(MDGUID)]);
+ 
+   uintptr_t crash_address() const { return crash_address_; }
+-  void set_crash_address(uintptr_t crash_address) {
+-    crash_address_ = crash_address;
++  void set_crash_address(uintptr_t crash_addr) {
++    crash_address_ = crash_addr;
+   }
+ 
+   int crash_signal() const { return crash_signal_; }
+-  void set_crash_signal(int crash_signal) { crash_signal_ = crash_signal; }
++  void set_crash_signal(int crash_sig) { crash_signal_ = crash_sig; }
+ 
+   pid_t crash_thread() const { return crash_thread_; }
+-  void set_crash_thread(pid_t crash_thread) { crash_thread_ = crash_thread; }
++  void set_crash_thread(pid_t thread) { crash_thread_ = thread; }
+ 
+   // Extracts the effective path and file name of from |mapping|. In most cases
+   // the effective name/path are just the mapping's path and basename. In some
+Only in breakpad/src/client/linux/minidump_writer: .linux_dumper.h.un~
+Only in breakpad/src/client/linux/minidump_writer: linux_dumper.o
+Only in breakpad/src/client/linux/minidump_writer: linux_ptrace_dumper.o
+Only in breakpad/src/client/linux/minidump_writer: minidump_writer.o
+Only in breakpad/src/client/linux/minidump_writer: src_client_linux_linux_dumper_unittest_helper-linux_dumper_unittest_helper.o
+Only in breakpad/src/client: minidump_file_writer.o
+Only in breakpad/src/common/android: .deps
+Only in breakpad/src/common: convert_UTF.o
+Only in breakpad/src/common: .deps
+Only in breakpad/src/common: .dirstamp
+Only in breakpad/src/common/dwarf: bytereader.o
+Only in breakpad/src/common/dwarf: .deps
+Only in breakpad/src/common/dwarf: .dirstamp
+Only in breakpad/src/common/dwarf: dwarf2diehandler.o
+Only in breakpad/src/common/dwarf: dwarf2reader.o
+Only in breakpad/src/common/dwarf: src_tools_mac_dump_syms_dump_syms-bytereader.o
+Only in breakpad/src/common/dwarf: src_tools_mac_dump_syms_dump_syms-dwarf2diehandler.o
+Only in breakpad/src/common/dwarf: src_tools_mac_dump_syms_dump_syms-dwarf2reader.o
+Only in breakpad/src/common: dwarf_cfi_to_module.o
+Only in breakpad/src/common: dwarf_cu_to_module.o
+Only in breakpad/src/common: dwarf_line_to_module.o
+Only in breakpad/src/common: language.o
+Only in breakpad/src/common/linux: crc32.o
+Only in breakpad/src/common/linux: .deps
+Only in breakpad/src/common/linux: .dirstamp
+Only in breakpad/src/common/linux: dump_symbols.o
+Only in breakpad/src/common/linux: elf_core_dump.o
+Only in breakpad/src/common/linux: elf_symbols_to_module.o
+Only in breakpad/src/common/linux: elfutils.o
+Only in breakpad/src/common/linux: file_id.o
+Only in breakpad/src/common/linux: guid_creator.o
+Only in breakpad/src/common/linux: http_upload.o
+Only in breakpad/src/common/linux: linux_libc_support.o
+Only in breakpad/src/common/linux: memory_mapped_file.o
+Only in breakpad/src/common/linux: safe_readlink.o
+Only in breakpad/src/common/linux/tests: .deps
+Only in breakpad/src/common/mac: .deps
+Only in breakpad/src/common/mac: .dirstamp
+Only in breakpad/src/common/mac: src_tools_mac_dump_syms_dump_syms-arch_utilities.o
+Only in breakpad/src/common/mac: src_tools_mac_dump_syms_dump_syms-dump_syms.o
+Only in breakpad/src/common/mac: src_tools_mac_dump_syms_dump_syms-file_id.o
+Only in breakpad/src/common/mac: src_tools_mac_dump_syms_dump_syms-macho_id.o
+Only in breakpad/src/common/mac: src_tools_mac_dump_syms_dump_syms-macho_reader.o
+Only in breakpad/src/common/mac: src_tools_mac_dump_syms_dump_syms-macho_utilities.o
+Only in breakpad/src/common/mac: src_tools_mac_dump_syms_dump_syms-macho_walker.o
+Only in breakpad/src/common: md5.o
+Only in breakpad/src/common: module.o
+Only in breakpad/src/common: src_tools_mac_dump_syms_dump_syms-dwarf_cfi_to_module.o
+Only in breakpad/src/common: src_tools_mac_dump_syms_dump_syms-dwarf_cu_to_module.o
+Only in breakpad/src/common: src_tools_mac_dump_syms_dump_syms-dwarf_line_to_module.o
+Only in breakpad/src/common: src_tools_mac_dump_syms_dump_syms-language.o
+Only in breakpad/src/common: src_tools_mac_dump_syms_dump_syms-md5.o
+Only in breakpad/src/common: src_tools_mac_dump_syms_dump_syms-module.o
+Only in breakpad/src/common: src_tools_mac_dump_syms_dump_syms-stabs_reader.o
+Only in breakpad/src/common: src_tools_mac_dump_syms_dump_syms-stabs_to_module.o
+Only in breakpad/src/common: stabs_reader.o
+Only in breakpad/src/common: stabs_to_module.o
+Only in breakpad/src/common: string_conversion.o
+Only in breakpad/src/common/tests: .deps
+Only in breakpad/src: config.h
+Only in breakpad/src: .dirstamp
+Only in breakpad/src: libbreakpad.a
+Only in breakpad/src/processor: basic_code_modules.o
+Only in breakpad/src/processor: basic_source_line_resolver.o
+Only in breakpad/src/processor: call_stack.o
+Only in breakpad/src/processor: cfi_frame_info.o
+Only in breakpad/src/processor: .deps
+Only in breakpad/src/processor: .dirstamp
+Only in breakpad/src/processor: disassembler_x86.o
+Only in breakpad/src/processor: dump_context.o
+Only in breakpad/src/processor: dump_object.o
+Only in breakpad/src/processor: exploitability_linux.o
+Only in breakpad/src/processor: exploitability.o
+Only in breakpad/src/processor: exploitability_win.o
+Only in breakpad/src/processor: fast_source_line_resolver.o
+Only in breakpad/src/processor: logging.o
+Only in breakpad/src/processor: microdump.o
+Only in breakpad/src/processor: microdump_processor.o
+Only in breakpad/src/processor: microdump_stackwalk
+Only in breakpad/src/processor: microdump_stackwalk.o
+Only in breakpad/src/processor: minidump_dump
+Only in breakpad/src/processor: minidump_dump.o
+Only in breakpad/src/processor: minidump.o
+Only in breakpad/src/processor: minidump_processor.o
+Only in breakpad/src/processor: minidump_stackwalk
+Only in breakpad/src/processor: minidump_stackwalk.o
+Only in breakpad/src/processor: module_comparer.o
+Only in breakpad/src/processor: module_serializer.o
+Only in breakpad/src/processor: pathname_stripper.o
+Only in breakpad/src/processor: process_state.o
+Only in breakpad/src/processor: proc_maps_linux.o
+Only in breakpad/src/processor: simple_symbol_supplier.o
+Only in breakpad/src/processor: source_line_resolver_base.o
+Only in breakpad/src/processor: stack_frame_cpu.o
+Only in breakpad/src/processor: stack_frame_symbolizer.o
+Only in breakpad/src/processor: stackwalk_common.o
+Only in breakpad/src/processor: stackwalker_address_list.o
+Only in breakpad/src/processor: stackwalker_amd64.o
+Only in breakpad/src/processor: stackwalker_arm64.o
+Only in breakpad/src/processor: stackwalker_arm.o
+Only in breakpad/src/processor: stackwalker_mips.o
+Only in breakpad/src/processor: stackwalker.o
+Only in breakpad/src/processor: stackwalker_ppc64.o
+Only in breakpad/src/processor: stackwalker_ppc.o
+Only in breakpad/src/processor: stackwalker_sparc.o
+Only in breakpad/src/processor: stackwalker_x86.o
+Only in breakpad/src/processor: symbolic_constants_win.o
+Only in breakpad/src/processor: tokenize.o
+Only in breakpad/src: stamp-h1
+Only in breakpad/src/testing/gtest/src: .deps
+Only in breakpad/src/testing/src: .deps
+Only in breakpad/src/third_party/libdisasm: .deps
+Only in breakpad/src/third_party/libdisasm: .dirstamp
+Only in breakpad/src/third_party/libdisasm: ia32_implicit.o
+Only in breakpad/src/third_party/libdisasm: ia32_insn.o
+Only in breakpad/src/third_party/libdisasm: ia32_invariant.o
+Only in breakpad/src/third_party/libdisasm: ia32_modrm.o
+Only in breakpad/src/third_party/libdisasm: ia32_opcode_tables.o
+Only in breakpad/src/third_party/libdisasm: ia32_operand.o
+Only in breakpad/src/third_party/libdisasm: ia32_reg.o
+Only in breakpad/src/third_party/libdisasm: ia32_settings.o
+Only in breakpad/src/third_party/libdisasm: libdisasm.a
+Only in breakpad/src/third_party/libdisasm: x86_disasm.o
+Only in breakpad/src/third_party/libdisasm: x86_format.o
+Only in breakpad/src/third_party/libdisasm: x86_imm.o
+Only in breakpad/src/third_party/libdisasm: x86_insn.o
+Only in breakpad/src/third_party/libdisasm: x86_misc.o
+Only in breakpad/src/third_party/libdisasm: x86_operand_list.o
+Only in breakpad/src/tools/linux/core2md: core2md
+Only in breakpad/src/tools/linux/core2md: core2md.o
+Only in breakpad/src/tools/linux/core2md: .deps
+Only in breakpad/src/tools/linux/core2md: .dirstamp
+Only in breakpad/src/tools/linux/dump_syms: .deps
+Only in breakpad/src/tools/linux/dump_syms: .dirstamp
+Only in breakpad/src/tools/linux/dump_syms: dump_syms
+Only in breakpad/src/tools/linux/dump_syms: dump_syms.o
+Only in breakpad/src/tools/linux/md2core: .deps
+Only in breakpad/src/tools/linux/md2core: .dirstamp
+Only in breakpad/src/tools/linux/md2core: minidump-2-core
+Only in breakpad/src/tools/linux/md2core: minidump-2-core.o
+Only in breakpad/src/tools/linux/symupload: .deps
+Only in breakpad/src/tools/linux/symupload: .dirstamp
+Only in breakpad/src/tools/linux/symupload: minidump_upload
+Only in breakpad/src/tools/linux/symupload: minidump_upload.o
+Only in breakpad/src/tools/linux/symupload: sym_upload
+Only in breakpad/src/tools/linux/symupload: sym_upload.o
+Only in breakpad/src/tools/mac/dump_syms: .deps
+Only in breakpad/src/tools/mac/dump_syms: .dirstamp
+Only in breakpad/src/tools/mac/dump_syms: dump_syms
+Only in breakpad/src/tools/mac/dump_syms: src_tools_mac_dump_syms_dump_syms-dump_syms_tool.o
diff --git a/external/breakpad/breakpad-wshadow2.patch.1 b/external/breakpad/breakpad-wshadow2.patch.1
new file mode 100644
index 0000000..40267b3
--- /dev/null
+++ b/external/breakpad/breakpad-wshadow2.patch.1
@@ -0,0 +1,144 @@
+Only in breakpad: breakpad-client.pc
+Only in breakpad: breakpad.pc
+Only in breakpad: build.log
+Only in breakpad: config.log
+Only in breakpad: config.status
+Only in breakpad: Makefile
+Only in breakpad/src/client: .deps
+Only in breakpad/src/client: .dirstamp
+Only in breakpad/src/client/linux/crash_generation: crash_generation_client.o
+Only in breakpad/src/client/linux/crash_generation: .deps
+Only in breakpad/src/client/linux/crash_generation: .dirstamp
+Only in breakpad/src/client/linux: .dirstamp
+Only in breakpad/src/client/linux/dump_writer_common: .deps
+Only in breakpad/src/client/linux/dump_writer_common: .dirstamp
+Only in breakpad/src/client/linux/dump_writer_common: thread_info.o
+Only in breakpad/src/client/linux/dump_writer_common: ucontext_reader.o
+Only in breakpad/src/client/linux/handler: .deps
+Only in breakpad/src/client/linux/handler: .dirstamp
+diff -ur breakpad.org/src/client/linux/handler/minidump_descriptor.h breakpad/src/client/linux/handler/minidump_descriptor.h
+--- breakpad.org/src/client/linux/handler/minidump_descriptor.h	2016-02-07 19:28:40.335518286 +0100
++++ breakpad/src/client/linux/handler/minidump_descriptor.h	2016-02-07 19:29:14.706713302 +0100
+@@ -61,7 +61,7 @@
+         directory_(dir),
+         c_path_(NULL),
+         size_limit_(-1) {
+-    assert(!directory.empty());
++    assert(!dir.empty());
+   }
+ 
+   explicit MinidumpDescriptor(int file_descriptor)
+@@ -69,7 +69,7 @@
+         fd_(file_descriptor),
+         c_path_(NULL),
+         size_limit_(-1) {
+-    assert(fd != -1);
++    assert(file_descriptor != -1);
+   }
+ 
+   explicit MinidumpDescriptor(const MicrodumpOnConsole&)
+Only in breakpad/src/client/linux/handler: .minidump_descriptor.h.un~
+Only in breakpad/src/client/linux/log: .deps
+Only in breakpad/src/client/linux/log: .dirstamp
+Only in breakpad/src/client/linux/log: log.o
+Only in breakpad/src/client/linux/microdump_writer: .deps
+Only in breakpad/src/client/linux/microdump_writer: .dirstamp
+Only in breakpad/src/client/linux/minidump_writer: .deps
+Only in breakpad/src/client/linux/minidump_writer: .dirstamp
+Only in breakpad/src/client/linux/minidump_writer: linux_dumper.o
+Only in breakpad/src/client/linux/minidump_writer: linux_ptrace_dumper.o
+Only in breakpad/src/client: minidump_file_writer.o
+Only in breakpad/src/common/android: .deps
+Only in breakpad/src/common: convert_UTF.o
+Only in breakpad/src/common: .deps
+Only in breakpad/src/common: .dirstamp
+Only in breakpad/src/common/dwarf: .deps
+Only in breakpad/src/common/dwarf: .dirstamp
+Only in breakpad/src/common/dwarf: src_tools_mac_dump_syms_dump_syms-bytereader.o
+Only in breakpad/src/common/dwarf: src_tools_mac_dump_syms_dump_syms-dwarf2diehandler.o
+Only in breakpad/src/common/dwarf: src_tools_mac_dump_syms_dump_syms-dwarf2reader.o
+Only in breakpad/src/common: dwarf_cfi_to_module.o
+Only in breakpad/src/common: dwarf_cu_to_module.o
+Only in breakpad/src/common: dwarf_line_to_module.o
+Only in breakpad/src/common: language.o
+Only in breakpad/src/common/linux: crc32.o
+Only in breakpad/src/common/linux: .deps
+Only in breakpad/src/common/linux: .dirstamp
+Only in breakpad/src/common/linux: dump_symbols.o
+Only in breakpad/src/common/linux: elf_symbols_to_module.o
+Only in breakpad/src/common/linux: http_upload.o
+Only in breakpad/src/common/linux/tests: .deps
+Only in breakpad/src/common/mac: .deps
+Only in breakpad/src/common/mac: .dirstamp
+Only in breakpad/src/common: module.o
+Only in breakpad/src/common: src_tools_mac_dump_syms_dump_syms-dwarf_cfi_to_module.o
+Only in breakpad/src/common: src_tools_mac_dump_syms_dump_syms-dwarf_cu_to_module.o
+Only in breakpad/src/common: src_tools_mac_dump_syms_dump_syms-dwarf_line_to_module.o
+Only in breakpad/src/common: src_tools_mac_dump_syms_dump_syms-language.o
+Only in breakpad/src/common: src_tools_mac_dump_syms_dump_syms-md5.o
+Only in breakpad/src/common: src_tools_mac_dump_syms_dump_syms-module.o
+Only in breakpad/src/common: src_tools_mac_dump_syms_dump_syms-stabs_reader.o
+Only in breakpad/src/common: src_tools_mac_dump_syms_dump_syms-stabs_to_module.o
+Only in breakpad/src/common: stabs_reader.o
+Only in breakpad/src/common: stabs_to_module.o
+Only in breakpad/src/common/tests: .deps
+Only in breakpad/src: config.h
+Only in breakpad/src: .dirstamp
+Only in breakpad/src/processor: basic_code_modules.o
+Only in breakpad/src/processor: basic_source_line_resolver.o
+Only in breakpad/src/processor: call_stack.o
+Only in breakpad/src/processor: cfi_frame_info.o
+Only in breakpad/src/processor: .deps
+Only in breakpad/src/processor: .dirstamp
+Only in breakpad/src/processor: disassembler_x86.o
+Only in breakpad/src/processor: dump_context.o
+Only in breakpad/src/processor: dump_object.o
+Only in breakpad/src/processor: exploitability_linux.o
+Only in breakpad/src/processor: exploitability.o
+Only in breakpad/src/processor: exploitability_win.o
+Only in breakpad/src/processor: fast_source_line_resolver.o
+Only in breakpad/src/processor: logging.o
+Only in breakpad/src/processor: microdump.o
+Only in breakpad/src/processor: microdump_processor.o
+Only in breakpad/src/processor: microdump_stackwalk.o
+Only in breakpad/src/processor: minidump_dump.o
+Only in breakpad/src/processor: minidump.o
+Only in breakpad/src/processor: minidump_processor.o
+Only in breakpad/src/processor: minidump_stackwalk.o
+Only in breakpad/src/processor: module_comparer.o
+Only in breakpad/src/processor: module_serializer.o
+Only in breakpad/src/processor: pathname_stripper.o
+Only in breakpad/src/processor: process_state.o
+Only in breakpad/src/processor: proc_maps_linux.o
+Only in breakpad/src/processor: simple_symbol_supplier.o
+Only in breakpad/src/processor: source_line_resolver_base.o
+Only in breakpad/src/processor: stack_frame_cpu.o
+Only in breakpad/src/processor: stack_frame_symbolizer.o
+Only in breakpad/src/processor: stackwalk_common.o
+Only in breakpad/src/processor: stackwalker_address_list.o
+Only in breakpad/src/processor: stackwalker_amd64.o
+Only in breakpad/src/processor: stackwalker_arm64.o
+Only in breakpad/src/processor: stackwalker_arm.o
+Only in breakpad/src/processor: stackwalker_mips.o
+Only in breakpad/src/processor: stackwalker.o
+Only in breakpad/src/processor: stackwalker_ppc64.o
+Only in breakpad/src/processor: stackwalker_ppc.o
+Only in breakpad/src/processor: stackwalker_sparc.o
+Only in breakpad/src/processor: stackwalker_x86.o
+Only in breakpad/src/processor: symbolic_constants_win.o
+Only in breakpad/src/processor: tokenize.o
+Only in breakpad/src: stamp-h1
+Only in breakpad/src/testing/gtest/src: .deps
+Only in breakpad/src/testing/src: .deps
+Only in breakpad/src/third_party/libdisasm: .deps
+Only in breakpad/src/third_party/libdisasm: .dirstamp
+Only in breakpad/src/tools/linux/core2md: .deps
+Only in breakpad/src/tools/linux/core2md: .dirstamp
+Only in breakpad/src/tools/linux/dump_syms: .deps
+Only in breakpad/src/tools/linux/dump_syms: .dirstamp
+Only in breakpad/src/tools/linux/md2core: .deps
+Only in breakpad/src/tools/linux/md2core: .dirstamp
+Only in breakpad/src/tools/linux/symupload: .deps
+Only in breakpad/src/tools/linux/symupload: .dirstamp
+Only in breakpad/src/tools/mac/dump_syms: .deps
+Only in breakpad/src/tools/mac/dump_syms: .dirstamp
commit 86d19201abdba590019c65bc5b35056d739eddde
Author: Markus Mohrhard <markus.mohrhard at googlemail.com>
Date:   Sun Feb 7 00:19:09 2016 +0100

    work on adding crash report UI
    
    Change-Id: I66f4dca3cd32381ecd52cc36490e7ee1dddf3699

diff --git a/desktop/source/app/app.cxx b/desktop/source/app/app.cxx
index d5e5c2c..0e51ec0 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,48 @@ 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;
+}
+
+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;
+}
 
 /** @short  check if recovery must be started or not.
 
@@ -1038,7 +1085,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 +1132,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 +1141,6 @@ bool impl_callRecoveryUI(bool bEmergencySave     ,
  * returns sal_True if at least one document could be saved...
  *
  */
-
 bool Desktop::SaveTasks()
 {
     return impl_callRecoveryUI(
@@ -2216,6 +2264,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
@@ -2290,6 +2343,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 0b5b98a..967097c 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>
 
@@ -23,7 +25,18 @@ void CrashReporter::AddKeyValue(const OUString& rKey, const OUString& rValue)
     ini_file << rtl::OUStringToOString(rValue, RTL_TEXTENCODING_UTF8).getStr() << "\n";
 }
 
-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 3af06c5..84ea2c8 100644
--- a/desktop/source/app/sofficemain.cxx
+++ b/desktop/source/app/sofficemain.cxx
@@ -18,8 +18,8 @@
  */
 
 #include <sal/config.h>
-#include <config_version.h>
 #include <config_folders.h>
+#include <config_features.h>
 
 #include <desktop/dllapi.h>
 
@@ -64,14 +64,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)
 {
@@ -81,9 +73,6 @@ static bool dumpCallback(const google_breakpad::MinidumpDescriptor& descriptor,
     minidump_file.close();
     // send the minidump to the server (not yet implemented)
     SAL_WARN("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, "crashreport", "Failed to upload minidump. Error Code: " << retVal);
     return succeeded;
 }
 #endif
@@ -92,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 f0b04be..e5bcfeb 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 c26c036..7d27d1a 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 650ecf9..39df1db 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 0000000..74066a8
--- /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 0000000..e6041f8
--- /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 0000000..28cac67
--- /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 0000000..e8d1355
--- /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 3f0e38e..31c8005 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"/>
commit 8980d9dba6297cabb271ff54b2e91fcd9fb42017
Author: Markus Mohrhard <markus.mohrhard at googlemail.com>
Date:   Wed Jan 6 13:57:24 2016 +0100

    better error reporting for crash uploader
    
    Change-Id: I6a2b5bd72187de2b646ec0d6fdb5fe20f5d6a2d8

diff --git a/desktop/source/minidump/minidump_upload.cxx b/desktop/source/minidump/minidump_upload.cxx
index e49eab0..9b1160d 100644
--- a/desktop/source/minidump/minidump_upload.cxx
+++ b/desktop/source/minidump/minidump_upload.cxx
@@ -131,11 +131,7 @@ bool uploadContent(std::map<std::string, std::string>& parameters)
                 url.c_str(),
                 curl_easy_strerror(cc));
 #endif
-    /*
-     * TODO
-    if (error_description != NULL)
-        *error_description = curl_easy_strerror(cc);
-    */
+    const char* error_description = curl_easy_strerror(cc);
 
     if (formpost != NULL)
     {
@@ -146,7 +142,7 @@ bool uploadContent(std::map<std::string, std::string>& parameters)
         curl_slist_free_all(headerlist);
     }
 
-    std::cerr << response_body << std::endl;
+    std::cerr << response_body << " " << error_description << std::endl;
 
 
     if( CURLE_OK != cc )
commit 4c071cd814837149fc0c5fadf5529a822fcf9e00
Author: Markus Mohrhard <markus.mohrhard at googlemail.com>
Date:   Wed Jan 6 13:56:47 2016 +0100

    store the URL in the crash ini file
    
    Change-Id: I1b5f29f864d01c238f2e21de87dde8005236f332

diff --git a/desktop/source/app/sofficemain.cxx b/desktop/source/app/sofficemain.cxx
index 7a3515b..3af06c5 100644
--- a/desktop/source/app/sofficemain.cxx
+++ b/desktop/source/app/sofficemain.cxx
@@ -98,6 +98,7 @@ extern "C" int DESKTOP_DLLPUBLIC soffice_main()
     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
diff --git a/desktop/source/minidump/minidump_upload.cxx b/desktop/source/minidump/minidump_upload.cxx
index 220286a..e49eab0 100644
--- a/desktop/source/minidump/minidump_upload.cxx
+++ b/desktop/source/minidump/minidump_upload.cxx
@@ -68,15 +68,16 @@ bool uploadContent(std::map<std::string, std::string>& parameters)
     if (!curl)
         return false;
 
-    std::string proxy, proxy_user_pwd, ca_certificate_file, file;
-
-    std::string url = "http://libreofficecrash.org/submit";
+    std::string proxy, proxy_user_pwd, ca_certificate_file, file, url;
 
     getProperty("Proxy", proxy, parameters);
     getProperty("ProxyUserPW", proxy_user_pwd, parameters);
     getProperty("CAFile", ca_certificate_file, parameters);
 
     getProperty("DumpFile", file, parameters);
+    getProperty("URL", file, parameters);
+    if (url.empty())
+        return false;
 
     curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
     curl_easy_setopt(curl, CURLOPT_USERAGENT, kUserAgent);
commit 34a54dc38a905a7aa8b9bc82c102e39235569bca
Author: Markus Mohrhard <markus.mohrhard at googlemail.com>
Date:   Fri Dec 18 23:08:02 2015 +0100

    add script to upload symbols to crash reporting site
    
    Change-Id: I85f6c0757550192443909f08331d65c21c7f4350

diff --git a/bin/upload_symbols.py b/bin/upload_symbols.py
new file mode 100644
index 0000000..8d99ab9
--- /dev/null
+++ b/bin/upload_symbols.py
@@ -0,0 +1,24 @@
+# -*- Mode: python; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+#
+# 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/.
+#
+
+import requests, sys
+
+def main():
+    if len(sys.argv) != 3:
+        print("Invalid number of parameters")
+        sys.exit(1)
+
+    url = "http://localhost:8000/upload/"
+    files = {'symbols': open(sys.argv[1], 'rb'), 'comment':sys.argv[2]}
+    comment = {'comment': sys.argv[2]}
+    r = requests.post(url, files = files, data = {"comment":"whatever", "tempt":"tempt"})
+    print(r)
+
+if __name__ == "__main__":
+    main()
+
+# vim:set shiftwidth=4 softtabstop=4 expandtab: */
commit 09360532d14f4665dbcbe84db44b47e3796529c0
Author: Markus Mohrhard <markus.mohrhard at googlemail.com>
Date:   Tue Dec 15 14:01:27 2015 +0100

    add script to generate symbols
    
    Change-Id: Icae707709307bc86360676692e55780b9ec89639

diff --git a/bin/symbolstore.py b/bin/symbolstore.py
new file mode 100755
index 0000000..941f448
--- /dev/null
+++ b/bin/symbolstore.py
@@ -0,0 +1,644 @@
+#!/usr/bin/env python
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is mozilla.org code.
+#
+# The Initial Developer of the Original Code is
+# The Mozilla Foundation
+# Portions created by the Initial Developer are Copyright (C) 2007
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+# Ted Mielczarek <ted.mielczarek at gmail.com>
+# Ben Turner <mozilla at songbirdnest.com>
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+#
+# Usage: symbolstore.py <params> <dump_syms path> <symbol store path>
+#                                <debug info files or dirs>
+#   Runs dump_syms on each debug info file specified on the command line,
+#   then places the resulting symbol file in the proper directory
+#   structure in the symbol store path.  Accepts multiple files
+#   on the command line, so can be called as part of a pipe using
+#   find <dir> | xargs symbolstore.pl <dump_syms> <storepath>
+#   But really, you might just want to pass it <dir>.
+#
+#   Parameters accepted:
+#     -c           : Copy debug info files to the same directory structure
+#                    as sym files
+#     -a "<archs>" : Run dump_syms -a <arch> for each space separated
+#                    cpu architecture in <archs> (only on OS X)
+#     -s <srcdir>  : Use <srcdir> as the top source directory to
+#                    generate relative filenames.
+
+import sys
+import os
+import re
+import shutil
+from optparse import OptionParser
+
+# Utility classes
+
+class VCSFileInfo:
+    """ A base class for version-controlled file information. Ensures that the
+        following attributes are generated only once (successfully):
+
+            self.root
+            self.clean_root
+            self.revision
+            self.filename
+
+        The attributes are generated by a single call to the GetRoot,
+        GetRevision, and GetFilename methods. Those methods are explicitly not
+        implemented here and must be implemented in derived classes. """
+
+    def __init__(self, file):
+        if not file:
+            raise ValueError
+        self.file = file
+
+    def __getattr__(self, name):
+        """ __getattr__ is only called for attributes that are not set on self,
+            so setting self.[attr] will prevent future calls to the GetRoot,
+            GetRevision, and GetFilename methods. We don't set the values on
+            failure on the off chance that a future call might succeed. """
+
+        if name == "root":
+            root = self.GetRoot()
+            if root:
+                self.root = root
+            return root
+
+        elif name == "clean_root":
+            clean_root = self.GetCleanRoot()
+            if clean_root:
+                self.clean_root = clean_root
+            return clean_root
+
+        elif name == "revision":
+            revision = self.GetRevision()
+            if revision:
+                self.revision = revision
+            return revision
+
+        elif name == "filename":
+            filename = self.GetFilename()
+            if filename:
+                self.filename = filename
+            return filename
+
+        raise AttributeError
+
+    def GetRoot(self):
+        """ This method should return the unmodified root for the file or 'None'
+            on failure. """
+        raise NotImplementedError
+
+    def GetCleanRoot(self):
+        """ This method should return the repository root for the file or 'None'
+            on failure. """
+        raise NotImplementedErrors
+
+    def GetRevision(self):
+        """ This method should return the revision number for the file or 'None'
+            on failure. """
+        raise NotImplementedError
+
+    def GetFilename(self):
+        """ This method should return the repository-specific filename for the
+            file or 'None' on failure. """
+        raise NotImplementedError
+
+class CVSFileInfo(VCSFileInfo):
+    """ A class to maintiain version information for files in a CVS repository.
+        Derived from VCSFileInfo. """
+
+    def __init__(self, file, srcdir):
+        VCSFileInfo.__init__(self, file)
+        self.srcdir = srcdir
+
+    def GetRoot(self):
+        (path, filename) = os.path.split(self.file)
+        root = os.path.join(path, "CVS", "Root")
+        if not os.path.isfile(root):
+            return None
+        f = open(root, "r")
+        root_name = f.readline().strip()
+        f.close()
+        if root_name:
+            return root_name
+        print >> sys.stderr, "Failed to get CVS Root for %s" % filename
+        return None
+
+    def GetCleanRoot(self):
+        parts = self.root.split('@')
+        if len(parts) > 1:
+            # we don't want the extra colon
+            return parts[1].replace(":","")
+        print >> sys.stderr, "Failed to get CVS Root for %s" % filename
+        return None
+
+    def GetRevision(self):
+        (path, filename) = os.path.split(self.file)
+        entries = os.path.join(path, "CVS", "Entries")
+        if not os.path.isfile(entries):
+            return None
+        f = open(entries, "r")
+        for line in f:
+            parts = line.split("/")
+            if len(parts) > 1 and parts[1] == filename:
+                return parts[2]
+        print >> sys.stderr, "Failed to get CVS Revision for %s" % filename
+        return None
+
+    def GetFilename(self):
+        file = self.file
+        if self.revision and self.clean_root:
+            if self.srcdir:
+                # strip the base path off
+                # but we actually want the last dir in srcdir
+                file = os.path.normpath(file)
+                # the lower() is to handle win32+vc8, where
+                # the source filenames come out all lowercase,
+                # but the srcdir can be mixed case
+                if file.lower().startswith(self.srcdir.lower()):
+                    file = file[len(self.srcdir):]
+                (head, tail) = os.path.split(self.srcdir)
+                if tail == "":
+                    tail = os.path.basename(head)
+                file = tail + file
+            return "cvs:%s:%s:%s" % (self.clean_root, file, self.revision)
+        return file
+
+class SVNFileInfo(VCSFileInfo):
+    url = None
+    repo = None
+    svndata = {}
+
+    # This regex separates protocol and optional username/password from a url.
+    # For instance, all the following urls will be transformed into
+    # 'foo.com/bar':
+    #
+    #   http://foo.com/bar
+    #   svn+ssh://user@foo.com/bar
+    #   svn+ssh://user:pass@foo.com/bar
+    #
+    rootRegex = re.compile(r'^\S+?:/+(?:[^\s/]*@)?(\S+)$')
+
+    def __init__(self, file):
+        """ We only want to run subversion's info tool once so pull all the data
+            here. """
+
+        VCSFileInfo.__init__(self, file)
+
+        if os.path.isfile(file):
+            command = os.popen("svn info %s" % file, "r")
+            for line in command:
+                # The last line of the output is usually '\n'
+                if line.strip() == '':
+                    continue
+                # Split into a key/value pair on the first colon
+                key, value = line.split(':', 1)
+                if key in ["Repository Root", "Revision", "URL"]:
+                    self.svndata[key] = value.strip()
+
+            exitStatus = command.close()
+            if exitStatus:
+              print >> sys.stderr, "Failed to get SVN info for %s" % file
+
+    def GetRoot(self):
+        key = "Repository Root"
+        if key in self.svndata:
+            match = self.rootRegex.match(self.svndata[key])
+            if match:
+                return match.group(1)
+        print >> sys.stderr, "Failed to get SVN Root for %s" % self.file
+        return None
+
+    # File bug to get this teased out from the current GetRoot, this is temporary
+    def GetCleanRoot(self):
+        return self.root
+
+    def GetRevision(self):
+        key = "Revision"
+        if key in self.svndata:
+            return self.svndata[key]
+        print >> sys.stderr, "Failed to get SVN Revision for %s" % self.file
+        return None
+
+    def GetFilename(self):
+        if self.root and self.revision:
+            if "URL" in self.svndata and "Repository Root" in self.svndata:
+                url, repo = self.svndata["URL"], self.svndata["Repository Root"]
+                file = url[len(repo) + 1:]
+            return "svn:%s:%s:%s" % (self.root, file, self.revision)
+        print >> sys.stderr, "Failed to get SVN Filename for %s" % self.file
+        return self.file
+
+# Utility functions
+
+# A cache of files for which VCS info has already been determined. Used to
+# prevent extra filesystem activity or process launching.
+vcsFileInfoCache = {}
+
+def GetVCSFilename(file, srcdir):
+    """Given a full path to a file, and the top source directory,
+    look for version control information about this file, and return
+    a tuple containing
+    1) a specially formatted filename that contains the VCS type,
+    VCS location, relative filename, and revision number, formatted like:
+    vcs:vcs location:filename:revision
+    For example:
+    cvs:cvs.mozilla.org/cvsroot:mozilla/browser/app/nsBrowserApp.cpp:1.36
+    2) the unmodified root information if it exists"""
+    (path, filename) = os.path.split(file)
+    if path == '' or filename == '':
+        return (file, None)
+
+    fileInfo = None
+    root = ''
+    if file in vcsFileInfoCache:
+        # Already cached this info, use it.
+        fileInfo = vcsFileInfoCache[file]
+    else:
+        if os.path.isdir(os.path.join(path, "CVS")):
+            fileInfo = CVSFileInfo(file, srcdir)
+            if fileInfo:
+               root = fileInfo.root
+        elif os.path.isdir(os.path.join(path, ".svn")) or \
+             os.path.isdir(os.path.join(path, "_svn")):
+            fileInfo = SVNFileInfo(file);
+        vcsFileInfoCache[file] = fileInfo
+
+    if fileInfo:
+        file = fileInfo.filename
+
+    # we want forward slashes on win32 paths
+    return (file.replace("\\", "/"), root)
+
+def GetPlatformSpecificDumper(**kwargs):
+    """This function simply returns a instance of a subclass of Dumper
+    that is appropriate for the current platform."""
+    return {'win32': Dumper_Win32,
+            'cygwin': Dumper_Win32,
+            'linux2': Dumper_Linux,
+            'sunos5': Dumper_Solaris,
+            'darwin': Dumper_Mac}[sys.platform](**kwargs)
+
+def SourceIndex(fileStream, outputPath, cvs_root):
+    """Takes a list of files, writes info to a data block in a .stream file"""
+    # Creates a .pdb.stream file in the mozilla\objdir to be used for source indexing
+    # Create the srcsrv data block that indexes the pdb file
+    result = True
+    pdbStreamFile = open(outputPath, "w")
+    pdbStreamFile.write('''SRCSRV: ini ------------------------------------------------\r\nVERSION=1\r\nSRCSRV: variables ------------------------------------------\r\nCVS_EXTRACT_CMD=%fnchdir%(%targ%)cvs.exe -d %fnvar%(%var2%) checkout -r %var4% -d %var4% -N %var3%\r\nMYSERVER=''')
+    pdbStreamFile.write(cvs_root)
+    pdbStreamFile.write('''\r\nSRCSRVTRG=%targ%\%var4%\%fnbksl%(%var3%)\r\nSRCSRVCMD=%CVS_EXTRACT_CMD%\r\nSRCSRV: source files ---------------------------------------\r\n''')
+    pdbStreamFile.write(fileStream) # can't do string interpolation because the source server also uses this and so there are % in the above
+    pdbStreamFile.write("SRCSRV: end ------------------------------------------------\r\n\n")
+    pdbStreamFile.close()
+    return result
+
+class Dumper:
+    """This class can dump symbols from a file with debug info, and
+    store the output in a directory structure that is valid for use as
+    a Breakpad symbol server.  Requires a path to a dump_syms binary--
+    |dump_syms| and a directory to store symbols in--|symbol_path|.
+    Optionally takes a list of processor architectures to process from
+    each debug file--|archs|, the full path to the top source
+    directory--|srcdir|, for generating relative source file names,
+    and an option to copy debug info files alongside the dumped
+    symbol files--|copy_debug|, mostly useful for creating a
+    Microsoft Symbol Server from the resulting output.
+
+    You don't want to use this directly if you intend to call
+    ProcessDir.  Instead, call GetPlatformSpecificDumper to
+    get an instance of a subclass."""
+    def __init__(self, dump_syms, symbol_path,
+                 archs=None, srcdir=None, copy_debug=False, vcsinfo=False, srcsrv=False):
+        # popen likes absolute paths, at least on windows
+        self.dump_syms = os.path.abspath(dump_syms)
+        self.symbol_path = symbol_path
+        if archs is None:
+            # makes the loop logic simpler
+            self.archs = ['']
+        else:
+            self.archs = ['-a %s' % a for a in archs.split()]
+        if srcdir is not None:
+            self.srcdir = os.path.normpath(srcdir)
+        else:
+            self.srcdir = None
+        self.copy_debug = copy_debug
+        self.vcsinfo = vcsinfo
+        self.srcsrv = srcsrv
+
+    # subclasses override this
+    def ShouldProcess(self, file):
+        return False
+
+    def RunFileCommand(self, file):
+        """Utility function, returns the output of file(1)"""
+        try:
+            # we use -L to read the targets of symlinks,
+            # and -b to print just the content, not the filename
+            return os.popen("file -Lb " + file).read()
+        except:
+            return ""
+
+    # This is a no-op except on Win32
+    def FixFilenameCase(self, file):
+        return file
+
+    # This is a no-op except on Win32
+    def SourceServerIndexing(self, debug_file, guid, sourceFileStream, cvs_root):
+        return ""
+
+    # subclasses override this if they want to support this
+    def CopyDebug(self, file, debug_file, guid):
+        pass
+
+    def Process(self, file_or_dir):
+        "Process a file or all the (valid) files in a directory."
+        if os.path.isdir(file_or_dir):
+            return self.ProcessDir(file_or_dir)
+        elif os.path.isfile(file_or_dir):
+            return self.ProcessFile(file_or_dir)
+        # maybe it doesn't exist?
+        return False
+
+    def ProcessDir(self, dir):
+        """Process all the valid files in this directory.  Valid files
+        are determined by calling ShouldProcess."""
+        result = True
+        for root, dirs, files in os.walk(dir):
+            for f in files:
+                fullpath = os.path.join(root, f)
+                if self.ShouldProcess(fullpath):
+                    if not self.ProcessFile(fullpath):
+                        result = False
+        return result
+
+    def ProcessFile(self, file):
+        """Dump symbols from this file into a symbol file, stored
+        in the proper directory structure in  |symbol_path|."""
+        result = False
+        sourceFileStream = ''
+        # tries to get cvsroot from the .mozconfig first - if it's not set
+        # the tinderbox cvs_path will be assigned further down
+        cvs_root = os.environ.get("SRCSRV_ROOT")
+        for arch in self.archs:
+            try:
+                cmd = os.popen("%s %s %s" % (self.dump_syms, arch, file), "r")
+                module_line = cmd.next()
+                if module_line.startswith("MODULE"):
+                    # MODULE os cpu guid debug_file
+                    (guid, debug_file) = (module_line.split())[3:5]
+                    # strip off .pdb extensions, and append .sym
+                    sym_file = re.sub("\.pdb$", "", debug_file) + ".sym"
+                    # we do want forward slashes here
+                    rel_path = os.path.join(debug_file,
+                                            guid,
+                                            sym_file).replace("\\", "/")
+                    full_path = os.path.normpath(os.path.join(self.symbol_path,
+                                                              rel_path))
+                    try:
+                        os.makedirs(os.path.dirname(full_path))
+                    except OSError: # already exists
+                        pass
+                    f = open(full_path, "w")
+                    f.write(module_line)
+                    # now process the rest of the output
+                    for line in cmd:
+                        if line.startswith("FILE"):
+                            # FILE index filename
+                            (x, index, filename) = line.split(None, 2)
+                            if sys.platform == "sunos5":
+                                start = filename.find(self.srcdir)
+                                if start == -1:
+                                    start = 0
+                                filename = filename[start:]
+                            filename = self.FixFilenameCase(filename.rstrip())
+                            sourcepath = filename
+                            if self.vcsinfo:
+                                (filename, rootname) = GetVCSFilename(filename, self.srcdir)
+                                # sets cvs_root in case the loop through files were to end on an empty rootname
+                                if cvs_root is None:
+                                  if rootname:
+                                     cvs_root = rootname
+                            # gather up files with cvs for indexing   
+                            if filename.startswith("cvs"):
+                                (ver, checkout, source_file, revision) = filename.split(":", 3)
+                                sourceFileStream += sourcepath + "*MYSERVER*" + source_file + '*' + revision + "\r\n"
+                            f.write("FILE %s %s\n" % (index, filename))
+                        else:
+                            # pass through all other lines unchanged
+                            f.write(line)
+                    f.close()
+                    cmd.close()
+                    # we output relative paths so callers can get a list of what
+                    # was generated
+                    print rel_path
+                    if self.copy_debug:
+                        self.CopyDebug(file, debug_file, guid)
+                    if self.srcsrv:
+                        # Call on SourceServerIndexing
+                        result = self.SourceServerIndexing(debug_file, guid, sourceFileStream, cvs_root)
+                    result = True
+            except StopIteration:
+                pass
+            except:
+                print >> sys.stderr, "Unexpected error: ", sys.exc_info()[0]
+                raise
+        return result
+
+# Platform-specific subclasses.  For the most part, these just have
+# logic to determine what files to extract symbols from.
+
+class Dumper_Win32(Dumper):
+    fixedFilenameCaseCache = {}
+
+    def ShouldProcess(self, file):
+        """This function will allow processing of pdb files that have dll
+        or exe files with the same base name next to them."""
+        if file.endswith(".pdb"):
+            (path,ext) = os.path.splitext(file)
+            if os.path.isfile(path + ".exe") or os.path.isfile(path + ".dll"):
+                return True
+        return False
+
+    def FixFilenameCase(self, file):
+        """Recent versions of Visual C++ put filenames into
+        PDB files as all lowercase.  If the file exists
+        on the local filesystem, fix it."""
+
+        # Use a cached version if we have one.
+        if file in self.fixedFilenameCaseCache:
+            return self.fixedFilenameCaseCache[file]
+
+        result = file
+
+        (path, filename) = os.path.split(file)
+        if os.path.isdir(path):
+            lc_filename = filename.lower()
+            for f in os.listdir(path):
+                if f.lower() == lc_filename:
+                    result = os.path.join(path, f)
+                    break
+
+        # Cache the corrected version to avoid future filesystem hits.
+        self.fixedFilenameCaseCache[file] = result
+        return result
+
+    def CopyDebug(self, file, debug_file, guid):
+        rel_path = os.path.join(debug_file,
+                                guid,
+                                debug_file).replace("\\", "/")
+        print rel_path
+        full_path = os.path.normpath(os.path.join(self.symbol_path,
+                                                  rel_path))
+        shutil.copyfile(file, full_path)
+        pass
+        
+    def SourceServerIndexing(self, debug_file, guid, sourceFileStream, cvs_root):
+        # Creates a .pdb.stream file in the mozilla\objdir to be used for source indexing
+        cwd = os.getcwd()
+        streamFilename = debug_file + ".stream"
+        stream_output_path = os.path.join(cwd, streamFilename)
+        # Call SourceIndex to create the .stream file
+        result = SourceIndex(sourceFileStream, stream_output_path, cvs_root)
+        
+        if self.copy_debug:
+            pdbstr_path = os.environ.get("PDBSTR_PATH")
+            pdbstr = os.path.normpath(pdbstr_path)
+            pdb_rel_path = os.path.join(debug_file, guid, debug_file)
+            pdb_filename = os.path.normpath(os.path.join(self.symbol_path, pdb_rel_path))
+            # move to the dir with the stream files to call pdbstr
+            os.chdir(os.path.dirname(stream_output_path))
+            os.spawnv(os.P_WAIT, pdbstr, [pdbstr, "-w", "-p:" + pdb_filename, "-i:" + streamFilename, "-s:srcsrv"])
+            # clean up all the .stream files when done
+            os.remove(stream_output_path)
+        return result
+
+class Dumper_Linux(Dumper):
+    def ShouldProcess(self, file):
+        """This function will allow processing of files that are
+        executable, or end with the .so extension, and additionally
+        file(1) reports as being ELF files.  It expects to find the file
+        command in PATH."""
+        if file.endswith(".so") or file.endswith(".bin") or os.access(file, os.X_OK):
+            return self.RunFileCommand(file).startswith("ELF")
+        return False
+
+    def CopyDebug(self, file, debug_file, guid):
+        # We want to strip out the debug info, and add a
+        # .gnu_debuglink section to the object, so the debugger can
+        # actually load our debug info later.
+        file_dbg = file + ".dbg"
+        os.system("objcopy --only-keep-debug %s %s" % (file, file_dbg))
+        os.system("objcopy --add-gnu-debuglink=%s %s" % (file_dbg, file))
+        
+        rel_path = os.path.join(debug_file,
+                                guid,
+                                debug_file + ".dbg")
+        full_path = os.path.normpath(os.path.join(self.symbol_path,
+                                                  rel_path))
+        shutil.copyfile(file_dbg, full_path)
+        # gzip the shipped debug files
+        os.system("gzip %s" % full_path)
+        print rel_path + ".gz"
+
+class Dumper_Solaris(Dumper):
+    def RunFileCommand(self, file):
+        """Utility function, returns the output of file(1)"""
+        try:
+            output = os.popen("file " + file).read()
+            return output.split('\t')[1];
+        except:
+            return ""
+
+    def ShouldProcess(self, file):
+        """This function will allow processing of files that are
+        executable, or end with the .so extension, and additionally
+        file(1) reports as being ELF files.  It expects to find the file
+        command in PATH."""
+        if file.endswith(".so") or os.access(file, os.X_OK):
+            return self.RunFileCommand(file).startswith("ELF")
+        return False
+
+class Dumper_Mac(Dumper):
+    def ShouldProcess(self, file):
+        """This function will allow processing of files that are
+        executable, or end with the .dylib extension, and additionally
+        file(1) reports as being Mach-O files.  It expects to find the file
+        command in PATH."""
+        if file.endswith(".dylib") or os.access(file, os.X_OK):
+            return self.RunFileCommand(file).startswith("Mach-O")
+        return False
+
+# Entry point if called as a standalone program
+def main():
+    parser = OptionParser(usage="usage: %prog [options] <dump_syms binary> <symbol store path> <debug info files>")
+    parser.add_option("-c", "--copy",
+                      action="store_true", dest="copy_debug", default=False,
+                      help="Copy debug info files into the same directory structure as symbol files")
+    parser.add_option("-a", "--archs",
+                      action="store", dest="archs",
+                      help="Run dump_syms -a <arch> for each space separated cpu architecture in ARCHS (only on OS X)")
+    parser.add_option("-s", "--srcdir",
+                      action="store", dest="srcdir",
+                      help="Use SRCDIR to determine relative paths to source files")
+    parser.add_option("-v", "--vcs-info",
+                      action="store_true", dest="vcsinfo",
+                      help="Try to retrieve VCS info for each FILE listed in the output")
+    parser.add_option("-i", "--source-index",
+                      action="store_true", dest="srcsrv", default=False,
+                      help="Add source index information to debug files, making them suitable for use in a source server.")
+    (options, args) = parser.parse_args()
+    
+    #check to see if the pdbstr.exe exists
+    if options.srcsrv:
+        pdbstr = os.environ.get("PDBSTR_PATH")
+        if not os.path.exists(pdbstr):
+            print >> sys.stderr, "Invalid path to pdbstr.exe - please set/check PDBSTR_PATH.\n"
+            sys.exit(1)
+            
+    if len(args) < 3:
+        parser.error("not enough arguments")
+        exit(1)
+
+    dumper = GetPlatformSpecificDumper(dump_syms=args[0],
+                                       symbol_path=args[1],
+                                       copy_debug=options.copy_debug,
+                                       archs=options.archs,
+                                       srcdir=options.srcdir,
+                                       vcsinfo=options.vcsinfo,
+                                       srcsrv=options.srcsrv)
+    for arg in args[2:]:
+        dumper.Process(arg)
+
+# run main if run directly
+if __name__ == "__main__":
+    main()
commit c72e3311173176c7b8543c833004f951b5bee0a9
Author: Markus Mohrhard <markus.mohrhard at googlemail.com>
Date:   Wed Dec 9 07:39:58 2015 +0100

    store the id of each vcl::Window
    
    We will use the ID in the UI testing to identify the widget.
    
    Change-Id: I4dd79a02355e1de40f3c2ddc6a61a805b4e30778

diff --git a/include/vcl/window.hxx b/include/vcl/window.hxx
index c9a6d0b..dda799e 100644
--- a/include/vcl/window.hxx
+++ b/include/vcl/window.hxx
@@ -1527,6 +1527,16 @@ public:
      */
     void reorderWithinParent(sal_uInt16 nNewPosition);
 
+    /**
+     * Sets an ID.
+     */
+    void set_id(const OUString& rID);
+
+    /**
+     * Get the ID of the window.
+     */
+    const OUString& get_id() const;
+
 
     //  Native Widget Rendering functions
 
diff --git a/vcl/inc/window.h b/vcl/inc/window.h
index db8bdfb..a1df543 100644
--- a/vcl/inc/window.h
+++ b/vcl/inc/window.h
@@ -231,6 +231,7 @@ public:
     OString             maUniqId;
     OUString            maHelpText;
     OUString            maQuickHelpText;
+    OUString            maID;
     InputContext        maInputContext;
     css::uno::Reference< css::awt::XWindowPeer > mxWindowPeer;
     css::uno::Reference< css::accessibility::XAccessible > mxAccessible;
diff --git a/vcl/source/window/builder.cxx b/vcl/source/window/builder.cxx
index cc11c28..a48f3fd 100644
--- a/vcl/source/window/builder.cxx
+++ b/vcl/source/window/builder.cxx
@@ -1845,6 +1845,7 @@ VclPtr<vcl::Window> VclBuilder::insertObject(vcl::Window *pParent, const OString
 
     if (pCurrentChild)
     {
+        pCurrentChild->set_id(OStringToOUString(rID, RTL_TEXTENCODING_UTF8));
         if (pCurrentChild == m_pParent.get() && m_bToplevelHasDeferredProperties)
             m_aDeferredProperties = rProps;
         else
diff --git a/vcl/source/window/window.cxx b/vcl/source/window/window.cxx
index 599514d..1998b6d 100644
--- a/vcl/source/window/window.cxx
+++ b/vcl/source/window/window.cxx
@@ -3847,6 +3847,16 @@ bool Window::CompatNotify( NotifyEvent& rNEvt )
         return Notify( rNEvt );
 }
 
+void Window::set_id(const OUString& rID)
+{
+    mpWindowImpl->maID = rID;
+}
+
+const OUString& Window::get_id() const
+{
+    return mpWindowImpl->maID;
+}
+
 } /* namespace vcl */
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
commit bfffe45c1bc756a839d3b594fc7784cfae334c78
Author: Markus Mohrhard <markus.mohrhard at googlemail.com>
Date:   Tue Dec 1 15:01:23 2015 +0100

    fix crashreport build
    
    There was a circular dependency between vcl and sofficeapp
    
    Change-Id: I7f7c10ddcb2966b324469ce9cb9693da628c3781

diff --git a/Repository.mk b/Repository.mk
index 2b6f10a..ea242bd 100644
--- a/Repository.mk
+++ b/Repository.mk
@@ -543,6 +543,7 @@ $(eval $(call gb_Helper_register_libraries_for_install,PLAINLIBS_OOO,ooo, \
 	collator_data \
 	comphelper \
 	$(call gb_Helper_optional,DBCONNECTIVITY,dbpool2) \
+	$(call gb_Helper_optional,BREAKPAD,crashreport) \
 	deployment \
 	deploymentgui \
 	dict_ja \
diff --git a/desktop/Library_sofficeapp.mk b/desktop/Library_sofficeapp.mk
index c7e1e69..2d173ad 100644
--- a/desktop/Library_sofficeapp.mk
+++ b/desktop/Library_sofficeapp.mk
@@ -25,6 +25,10 @@ $(eval $(call gb_Library_add_libs,sofficeapp,\
 
 $(eval $(call gb_Library_use_external,sofficeapp,boost_headers))
 
+ifeq ($(ENABLE_BREAKPAD),TRUE)
+$(eval $(call gb_Library_use_external,sofficeapp,breakpad))
+endif
+
 $(eval $(call gb_Library_use_custom_headers,sofficeapp,\
 	officecfg/registry \
 ))
@@ -44,6 +48,9 @@ $(eval $(call gb_Library_use_libraries,sofficeapp,\
     comphelper \
     cppu \
     cppuhelper \
+    $(if $(filter TRUE,$(ENABLE_BREAKPAD)), \
+        crashreport \
+    ) \
     deploymentmisc \
     editeng \
     i18nlangtag \
@@ -87,7 +94,6 @@ $(eval $(call gb_Library_add_exception_objects,sofficeapp,\
     desktop/source/app/check_ext_deps \
     desktop/source/app/cmdlineargs \
     desktop/source/app/cmdlinehelp \
-    desktop/source/app/crashreport \
     desktop/source/app/desktopcontext \
     desktop/source/app/desktopresid \
     desktop/source/app/dispatchwatcher \
@@ -118,10 +124,6 @@ $(eval $(call gb_Library_add_libs,sofficeapp,\
 endif
 endif
 
-ifeq ($(ENABLE_BREAKPAD),TRUE)
-$(eval $(call gb_Library_use_external,sofficeapp,breakpad))
-endif
-
 # LibreOfficeKit bits
 ifneq ($(filter $(OS),ANDROID IOS MACOSX WNT),)
 $(eval $(call gb_Library_add_exception_objects,sofficeapp,\
diff --git a/desktop/Module_desktop.mk b/desktop/Module_desktop.mk
index c87a777..619c060 100644
--- a/desktop/Module_desktop.mk
+++ b/desktop/Module_desktop.mk
@@ -17,6 +17,7 @@ $(eval $(call gb_Module_add_targets,desktop,\
     Library_deploymentmisc \
     Library_offacc \
     Library_sofficeapp \
+    $(if $(ENABLE_BREAKPAD),Library_crashreport) \
     $(if $(ENABLE_HEADLESS),,Library_spl) \
     Package_branding \
     $(if $(CUSTOM_BRAND_DIR),Package_branding_custom) \
diff --git a/include/desktop/crashreport.hxx b/include/desktop/crashreport.hxx
index f6a3595..f0b04be 100644
--- a/include/desktop/crashreport.hxx
+++ b/include/desktop/crashreport.hxx
@@ -27,7 +27,7 @@
  *      * AdapterDeviceId
  *
  */
-class DESKTOP_DLLPUBLIC CrashReporter
+class CRASHREPORT_DLLPUBLIC CrashReporter
 {
 public:
     static void AddKeyValue(const OUString& rKey, const OUString& rValue);
diff --git a/include/desktop/dllapi.h b/include/desktop/dllapi.h
index ebc75f1..fd23aeb 100644
--- a/include/desktop/dllapi.h
+++ b/include/desktop/dllapi.h
@@ -19,6 +19,12 @@
 #   define DESKTOP_DLLPUBLIC SAL_DLLPUBLIC_IMPORT
 #endif
 
+#if defined(CRASHREPORT_DLLIMPLEMENTATION)
+#   define CRASHREPORT_DLLPUBLIC SAL_DLLPUBLIC_EXPORT
+#else
+#   define CRASHREPORT_DLLPUBLIC SAL_DLLPUBLIC_IMPORT
+#endif
+
 #endif
 
 /* vim: set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/Library_vcl.mk b/vcl/Library_vcl.mk
index 7ddc830..ef244fe 100644
--- a/vcl/Library_vcl.mk
+++ b/vcl/Library_vcl.mk
@@ -90,7 +90,6 @@ $(eval $(call gb_Library_use_libraries,vcl,\
     cppu \
     sal \
     salhelper \
-    sofficeapp \
     xmlreader \
 	$(gb_UWINAPI) \
 ))
commit 11ecc4e5d5b103f41957bbc01f6908e39135f256
Author: Markus Mohrhard <markus.mohrhard at googlemail.com>
Date:   Thu Nov 26 00:35:55 2015 +0100

    add TODO for location of dump.ini file
    
    Change-Id: Idbe473c9fdfe8856380b16c48ce868ca10045410

diff --git a/desktop/source/app/crashreport.cxx b/desktop/source/app/crashreport.cxx
index 063b15e..0b5b98a 100644
--- a/desktop/source/app/crashreport.cxx
+++ b/desktop/source/app/crashreport.cxx
@@ -25,6 +25,7 @@ void CrashReporter::AddKeyValue(const OUString& rKey, const OUString& rValue)
 
 const char* CrashReporter::getIniFileName()
 {
+    // TODO: we need a generic solution for the location
     return "/tmp/dump.ini";
 }
 
commit 27eb35239885b28a722a85a4d9d471868a4e0520
Author: Markus Mohrhard <markus.mohrhard at googlemail.com>
Date:   Thu Nov 26 00:15:27 2015 +0100

    use the new ini file based minidump uploader
    
    Change-Id: Iaf85fb53e6eff34e268b6948d62ca84b7f8e6dd2

diff --git a/desktop/Library_crashreport.mk b/desktop/Library_crashreport.mk
new file mode 100644
index 0000000..5b14519
--- /dev/null
+++ b/desktop/Library_crashreport.mk
@@ -0,0 +1,44 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# 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/.
+#
+
+$(eval $(call gb_Library_Library,crashreport))
+
+$(eval $(call gb_Library_set_include,crashreport,\
+    $$(INCLUDE) \
+    -I$(SRCDIR)/desktop/inc \
+))
+
+$(eval $(call gb_Library_use_external,crashreport,breakpad))
+
+$(eval $(call gb_Library_add_defs,crashreport,\
+    -DCRASHREPORT_DLLIMPLEMENTATION \
+))
+
+$(eval $(call gb_Library_add_libs,crashreport,\
+    $(if $(filter LINUX %BSD SOLARIS, $(OS)), \
+        $(DLOPEN_LIBS) \
+        -lpthread \
+    ) \
+))
+
+$(eval $(call gb_Library_use_libraries,crashreport,\
+    comphelper \
+    cppu \
+    cppuhelper \
+    sal \
+    salhelper \
+	$(gb_UWINAPI) \
+))
+
+$(eval $(call gb_Library_add_exception_objects,crashreport,\
+    desktop/source/app/crashreport \
+))
+
+
+# vim: set ts=4 sw=4 et:
diff --git a/desktop/source/app/crashreport.cxx b/desktop/source/app/crashreport.cxx
new file mode 100644
index 0000000..063b15e
--- /dev/null
+++ b/desktop/source/app/crashreport.cxx
@@ -0,0 +1,31 @@
+/* -*- 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 <desktop/crashreport.hxx>
+
+#include <string>
+#include <fstream>
+
+osl::Mutex CrashReporter::maMutex;
+
+void CrashReporter::AddKeyValue(const OUString& rKey, const OUString& rValue)
+{
+    osl::MutexGuard aGuard(maMutex);
+    std::string ini_path = getIniFileName();
+    std::ofstream ini_file(ini_path, std::ios_base::app);
+    ini_file << rtl::OUStringToOString(rKey, RTL_TEXTENCODING_UTF8).getStr() << "=";
+    ini_file << rtl::OUStringToOString(rValue, RTL_TEXTENCODING_UTF8).getStr() << "\n";
+}
+
+const char* CrashReporter::getIniFileName()
+{
+    return "/tmp/dump.ini";
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/app/sofficemain.cxx b/desktop/source/app/sofficemain.cxx
index 921de86..7a3515b 100644
--- a/desktop/source/app/sofficemain.cxx
+++ b/desktop/source/app/sofficemain.cxx
@@ -43,6 +43,8 @@
 #include <unotools/mediadescriptor.hxx>
 
 #if HAVE_FEATURE_BREAKPAD
+#include <fstream>
+#include <desktop/crashreport.hxx>
 
 #if defined( UNX ) && !defined MACOSX && !defined IOS && !defined ANDROID
 #include <client/linux/handler/exception_handler.h>
@@ -73,10 +75,13 @@ OString getLibDir()
 #if defined( UNX ) && !defined MACOSX && !defined IOS && !defined ANDROID
 static bool dumpCallback(const google_breakpad::MinidumpDescriptor& descriptor, void* /*context*/, bool succeeded)
 {
+    std::string ini_path = CrashReporter::getIniFileName();
+    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("crashreport", "minidump generated: " << descriptor.path());
-    OString aCommand = getLibDir().copy(7) + "/minidump_upload -p LibreOffice -v \"" + LIBO_VERSION_DOTTED + "\" ";
-    aCommand = aCommand + descriptor.path() + " " + "http://libreofficecrash.org/submit";
+    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);
     return succeeded;
@@ -89,6 +94,12 @@ 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.close();
+
 #if defined( UNX ) && !defined MACOSX && !defined IOS && !defined ANDROID
     google_breakpad::MinidumpDescriptor descriptor("/tmp");
     google_breakpad::ExceptionHandler eh(descriptor, NULL, dumpCallback, NULL, true, -1);
diff --git a/include/desktop/crashreport.hxx b/include/desktop/crashreport.hxx
index b1f15fb..f6a3595 100644
--- a/include/desktop/crashreport.hxx
+++ b/include/desktop/crashreport.hxx
@@ -32,9 +32,9 @@ class DESKTOP_DLLPUBLIC CrashReporter
 public:
     static void AddKeyValue(const OUString& rKey, const OUString& rValue);
 
-private:
+    static const char* getIniFileName();
 
-    static std::map<OUString, OUString> maValueMap;
+private:
 
     static osl::Mutex maMutex;
 };
commit b4a8f19f1c7cd9bf12bfffde5d93060db498d258
Author: Markus Mohrhard <markus.mohrhard at googlemail.com>
Date:   Wed Nov 25 23:48:20 2015 +0100

    write an own minidump uploader
    
    This one is platform independent and uses a key-value file.
    
    Change-Id: I28a4483763666a5a8520874bf8e984eaaf24e9c0

diff --git a/Repository.mk b/Repository.mk
index a99e8f5..2b6f10a 100644
--- a/Repository.mk
+++ b/Repository.mk
@@ -88,6 +88,7 @@ $(eval $(call gb_Helper_register_executables_for_install,SDK,sdk, \
 ))
 
 $(eval $(call gb_Helper_register_executables_for_install,OOO,brand, \
+	minidump_upload \
 	$(if $(filter-out ANDROID IOS MACOSX WNT,$(OS)),oosplash) \
 	soffice_bin \
 	$(if $(filter DESKTOP,$(BUILD_TYPE)),unopkg_bin) \
diff --git a/desktop/Executable_minidump_upload.mk b/desktop/Executable_minidump_upload.mk
new file mode 100644
index 0000000..7fe9546
--- /dev/null
+++ b/desktop/Executable_minidump_upload.mk
@@ -0,0 +1,22 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# 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/.
+#
+
+$(eval $(call gb_Executable_Executable,minidump_upload))
+
+$(eval $(call gb_Executable_use_libraries,minidump_upload,\
+    sal \
+))
+
+$(eval $(call gb_Executable_use_external,minidump_upload,curl))
+
+$(eval $(call gb_Executable_add_exception_objects,minidump_upload,\
+    desktop/source/minidump/minidump_upload \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/desktop/Module_desktop.mk b/desktop/Module_desktop.mk
index d74d406..c87a777 100644
--- a/desktop/Module_desktop.mk
+++ b/desktop/Module_desktop.mk
@@ -33,6 +33,7 @@ ifneq (,$(filter DESKTOP,$(BUILD_TYPE)))
 $(eval $(call gb_Module_add_targets,desktop,\
     Executable_soffice_bin \
     Executable_unopkg_bin \
+    Executable_minidump_upload \
     Library_migrationoo2 \
     Library_migrationoo3 \
     Library_unopkgapp \
diff --git a/desktop/source/minidump/minidump_upload.cxx b/desktop/source/minidump/minidump_upload.cxx
new file mode 100644
index 0000000..220286a
--- /dev/null
+++ b/desktop/source/minidump/minidump_upload.cxx
@@ -0,0 +1,202 @@
+/* -*- 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 <string>
+#include <map>
+#include <memory>
+#include <iostream>
+#include <fstream>
+
+#include <curl/curl.h>
+
+static const char kUserAgent[] = "Breakpad/1.0 (Linux)";
+
+std::map<std::string, std::string> readStrings(std::istream& file)
+{
+    std::map<std::string, std::string> parameters;
+
+
+    while (!file.eof())
+    {
+        std::string line;
+        std::getline(file, line);
+        int sep = line.find('=');
+        if (sep >= 0)
+        {
+            std::string key = line.substr(0, sep);
+            std::string value = line.substr(sep + 1);
+            parameters[key] = value;
+        }
+    }
+
+    return parameters;
+}
+
+// Callback to get the response data from server.
+static size_t WriteCallback(void *ptr, size_t size,
+                            size_t nmemb, void *userp)
+{
+  if (!userp)
+    return 0;
+
+  std::string* response = reinterpret_cast<std::string *>(userp);
+  size_t real_size = size * nmemb;

... etc. - the rest is truncated


More information about the Libreoffice-commits mailing list