[Libreoffice-commits] core.git: Branch 'distro/cib/libreoffice-6-3' - 5 commits - bin/symstore.sh config_host.mk.in configure.ac cui/Library_cui.mk cui/source cui/uiconfig desktop/source framework/source include/desktop instsetoo_native/CustomTarget_install.mk instsetoo_native/CustomTarget_setup.mk instsetoo_native/util scp2/source solenv/bin solenv/gbuild svx/source vcl/opengl vcl/source vcl/win

Mike Kaganski (via logerrit) logerrit at kemper.freedesktop.org
Mon Apr 27 23:00:59 UTC 2020


Rebased ref, commits from common ancestor:
commit 637cb0c8ae2dedba2fef2dce8b6a74509c84fdcf
Author:     Mike Kaganski <mike.kaganski at collabora.com>
AuthorDate: Thu Jan 2 15:30:36 2020 +0300
Commit:     Thorsten Behrens <Thorsten.Behrens at CIB.de>
CommitDate: Tue Apr 28 00:59:28 2020 +0200

    Delete google_breakpad::ExceptionHandler before calling _exit()
    
    While debugging tdf#129712 on Windows, I saw this sequence:
    
    1. nullptr was dereferenced (the reason for tdf#129712).
    2. ExceptionHandler::HandleException was called (in
       workdir/UnpackedTarball/breakpad/src/client/windows/handler/exception_handler.cc).
    3. It called ExceptionHandler::WriteMinidumpOnHandlerThread.
    4. Minidump was created in ExceptionHandler::ExceptionHandlerThreadMain.
    5. Document Recovery dialog was shown in Desktop::Exception (in
       desktop/source/app/app.cxx).
    6. After closing dialog, _exit() was called in Desktop::Exception.
    7. All threads except main were terminated.
    8. Another access violation was thrown in the "minimal CRT cleanup".
    9. ExceptionHandler::HandleException called again.
    10. ExceptionHandler::WriteMinidumpOnHandlerThread hung on WaitForSingleObject
        because handler thread that should release the semaphore was terminated
        already at step 7.
    
    The process had to be killed manually.
    
    This change destroys the breakpad handler at the start of Desktop::Exception,
    which de-registers itself (on Windows it uses SetUnhandledExceptionFilter).
    Other than preventing the hang, the rationale also is that keeping the handler
    after first minidump creation is wrong: even if the second minidump creation
    succeeded, uploading it to crashdump server would give not the actual problem,
    but some unrelated stack.
    
    Change-Id: If12d0c7db519693f733b5ab3b8a288cef800a149
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/86104
    Reviewed-by: Markus Mohrhard <markus.mohrhard at googlemail.com>
    Tested-by: Mike Kaganski <mike.kaganski at collabora.com>
    (cherry picked from commit 12b5892cf9c78dd917f2e50672cd250478e6c7d6)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/89690
    Tested-by: Thorsten Behrens <Thorsten.Behrens at CIB.de>
    Reviewed-by: Thorsten Behrens <Thorsten.Behrens at CIB.de>

diff --git a/desktop/source/app/app.cxx b/desktop/source/app/app.cxx
index af52ac73ef6e..4062874517b9 100644
--- a/desktop/source/app/app.cxx
+++ b/desktop/source/app/app.cxx
@@ -1131,6 +1131,10 @@ void Desktop::Exception(ExceptionCategory nCategory)
     // protect against recursive calls
     static bool bInException = false;
 
+#if HAVE_FEATURE_BREAKPAD
+    CrashReporter::removeExceptionHandler(); // disallow re-entry
+#endif
+
     SystemWindowFlags nOldMode = Application::GetSystemWindowMode();
     Application::SetSystemWindowMode( nOldMode & ~SystemWindowFlags::NOAUTOMODE );
     if ( bInException )
diff --git a/desktop/source/app/crashreport.cxx b/desktop/source/app/crashreport.cxx
index cadd3d8df346..c121b4fb8069 100644
--- a/desktop/source/app/crashreport.cxx
+++ b/desktop/source/app/crashreport.cxx
@@ -36,14 +36,44 @@
 #if defined __clang__
 #pragma clang diagnostic pop
 #endif
+#include <locale>
+#include <codecvt>
 #endif
 
 osl::Mutex CrashReporter::maMutex;
-google_breakpad::ExceptionHandler* CrashReporter::mpExceptionHandler = nullptr;
+std::unique_ptr<google_breakpad::ExceptionHandler> CrashReporter::mpExceptionHandler;
 bool CrashReporter::mbInit = false;
 CrashReporter::vmaKeyValues CrashReporter::maKeyValues;
 
 
+#if defined( UNX ) && !defined MACOSX && !defined IOS && !defined ANDROID
+static bool dumpCallback(const google_breakpad::MinidumpDescriptor& descriptor, void* /*context*/, bool succeeded)
+{
+    CrashReporter::addKeyValue("DumpFile", OStringToOUString(descriptor.path(), RTL_TEXTENCODING_UTF8), CrashReporter::Write);
+    SAL_WARN("desktop", "minidump generated: " << descriptor.path());
+
+    return succeeded;
+}
+#elif defined WNT
+static bool dumpCallback(const wchar_t* path, const wchar_t* id,
+    void* /*context*/, EXCEPTION_POINTERS* /*exinfo*/,
+    MDRawAssertionInfo* /*assertion*/,
+    bool succeeded)
+{
+    // TODO: moggi: can we avoid this conversion
+#ifdef _MSC_VER
+#pragma warning (disable: 4996)
+#endif
+    std::wstring_convert<std::codecvt_utf8<wchar_t>> conv1;
+    std::string aPath = conv1.to_bytes(std::wstring(path)) + conv1.to_bytes(std::wstring(id)) + ".dmp";
+    CrashReporter::addKeyValue("DumpFile", OStringToOUString(aPath.c_str(), RTL_TEXTENCODING_UTF8), CrashReporter::AddItem);
+    CrashReporter::addKeyValue("GDIHandles", OUString::number(::GetGuiResources(::GetCurrentProcess(), GR_GDIOBJECTS)), CrashReporter::Write);
+    SAL_WARN("desktop", "minidump generated: " << aPath);
+    return succeeded;
+}
+#endif
+
+
 void CrashReporter::writeToFile(std::ios_base::openmode Openmode)
 {
     std::ofstream ini_file(getIniFileName(), Openmode);
@@ -183,10 +213,21 @@ bool CrashReporter::readSendConfig(std::string& response)
     return crashreport::readConfig(CrashReporter::getIniFileName(), &response);
 }
 
-void CrashReporter::storeExceptionHandler(google_breakpad::ExceptionHandler* pExceptionHandler)
+void CrashReporter::installExceptionHandler()
+{
+    if (!IsDumpEnable())
+        return;
+#if defined( UNX ) && !defined MACOSX && !defined IOS && !defined ANDROID
+    google_breakpad::MinidumpDescriptor descriptor("/tmp");
+    mpExceptionHandler = std::make_unique<google_breakpad::ExceptionHandler>(descriptor, nullptr, dumpCallback, nullptr, true, -1);
+#elif defined WNT
+    mpExceptionHandler = std::make_unique<google_breakpad::ExceptionHandler>(L".", nullptr, dumpCallback, nullptr, google_breakpad::ExceptionHandler::HANDLER_ALL);
+#endif
+}
+
+void CrashReporter::removeExceptionHandler()
 {
-    if(IsDumpEnable())
-        mpExceptionHandler = pExceptionHandler;
+    mpExceptionHandler.reset();
 }
 
 
diff --git a/desktop/source/app/sofficemain.cxx b/desktop/source/app/sofficemain.cxx
index e5f986b042f1..d77512481962 100644
--- a/desktop/source/app/sofficemain.cxx
+++ b/desktop/source/app/sofficemain.cxx
@@ -42,22 +42,6 @@
 
 #if HAVE_FEATURE_BREAKPAD
 #include <desktop/crashreport.hxx>
-
-#if defined( UNX ) && !defined MACOSX && !defined IOS && !defined ANDROID
-#include <client/linux/handler/exception_handler.h>
-#elif defined WNT
-#if defined __clang__
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wmicrosoft-enum-value"
-#endif
-#include <client/windows/handler/exception_handler.h>
-#if defined __clang__
-#pragma clang diagnostic pop
-#endif
-#include <locale>
-#include <codecvt>
-#endif
-
 #endif
 
 
@@ -70,50 +54,10 @@
 #  define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, LOGTAG, __VA_ARGS__))
 #endif
 
-#if HAVE_FEATURE_BREAKPAD
-
-#if defined( UNX ) && !defined MACOSX && !defined IOS && !defined ANDROID
-static bool dumpCallback(const google_breakpad::MinidumpDescriptor& descriptor, void* /*context*/, bool succeeded)
-{
-    CrashReporter::addKeyValue("DumpFile", OStringToOUString(descriptor.path(), RTL_TEXTENCODING_UTF8), CrashReporter::Write);
-    SAL_WARN("desktop", "minidump generated: " << descriptor.path());
-
-    return succeeded;
-}
-#elif defined WNT
-static bool dumpCallback(const wchar_t* path, const wchar_t* id,
-                            void* /*context*/, EXCEPTION_POINTERS* /*exinfo*/,
-                            MDRawAssertionInfo* /*assertion*/,
-                            bool succeeded)
-{
-    // TODO: moggi: can we avoid this conversion
-#ifdef _MSC_VER
-#pragma warning (disable: 4996)
-#endif
-    std::wstring_convert<std::codecvt_utf8<wchar_t>> conv1;
-    std::string aPath = conv1.to_bytes(std::wstring(path)) + conv1.to_bytes(std::wstring(id)) + ".dmp";
-    CrashReporter::addKeyValue("DumpFile", OStringToOUString(aPath.c_str(), RTL_TEXTENCODING_UTF8), CrashReporter::AddItem);
-    CrashReporter::addKeyValue("GDIHandles", OUString::number(::GetGuiResources (::GetCurrentProcess(), GR_GDIOBJECTS)), CrashReporter::Write);
-    SAL_WARN("desktop", "minidump generated: " << aPath);
-    return succeeded;
-}
-#endif
-
-#endif
 extern "C" int DESKTOP_DLLPUBLIC soffice_main()
 {
 #if HAVE_FEATURE_BREAKPAD
-
-#if defined( UNX ) && !defined MACOSX && !defined IOS && !defined ANDROID
-    google_breakpad::MinidumpDescriptor descriptor("/tmp");
-    google_breakpad::ExceptionHandler eh(descriptor, nullptr, dumpCallback, nullptr, true, -1);
-
-    CrashReporter::storeExceptionHandler(&eh);
-#elif defined WNT
-    google_breakpad::ExceptionHandler eh(L".", nullptr, dumpCallback, nullptr, google_breakpad::ExceptionHandler::HANDLER_ALL);
-
-    CrashReporter::storeExceptionHandler(&eh);
-#endif
+    CrashReporter::installExceptionHandler();
 #endif
 
 #if defined( UNX ) && !defined MACOSX && !defined IOS && !defined ANDROID && !defined(LIBO_HEADLESS) && HAVE_FEATURE_OPENGL
diff --git a/include/desktop/crashreport.hxx b/include/desktop/crashreport.hxx
index 585c0af5e1a9..8235cff03501 100644
--- a/include/desktop/crashreport.hxx
+++ b/include/desktop/crashreport.hxx
@@ -18,6 +18,7 @@
 #include <config_features.h>
 
 // vector not sort the entries
+#include <memory>
 #include <vector>
 #include <string>
 
@@ -46,7 +47,8 @@ public:
 #if HAVE_FEATURE_BREAKPAD
     static void addKeyValue(const OUString& rKey, const OUString& rValue, tAddKeyHandling AddKeyHandling);
 
-    static void storeExceptionHandler(google_breakpad::ExceptionHandler* pExceptionHandler);
+    static void installExceptionHandler();
+    static void removeExceptionHandler();
 
     static bool crashReportInfoExists();
 
@@ -71,7 +73,7 @@ private:
     typedef std::vector<mpair> vmaKeyValues;
     static vmaKeyValues maKeyValues; // used to temporarily save entries before the old info has been uploaded
 
-    static google_breakpad::ExceptionHandler* mpExceptionHandler;
+    static std::unique_ptr<google_breakpad::ExceptionHandler> mpExceptionHandler;
 
     static std::string getIniFileName();
     static void writeCommonInfo();
commit 25ac185c646249f28b5647288853bf41aace8146
Author:     Thorsten Behrens <Thorsten.Behrens at CIB.de>
AuthorDate: Tue Apr 21 17:19:29 2020 +0200
Commit:     Thorsten Behrens <Thorsten.Behrens at CIB.de>
CommitDate: Tue Apr 28 00:59:28 2020 +0200

    Remove collect usage info from GUI
    
    Change-Id: I1a7420c557187097b424d298c020bcb837a8261c

diff --git a/cui/source/options/optgdlg.cxx b/cui/source/options/optgdlg.cxx
index 62063012432d..2a881afad275 100644
--- a/cui/source/options/optgdlg.cxx
+++ b/cui/source/options/optgdlg.cxx
@@ -272,7 +272,6 @@ OfaMiscTabPage::OfaMiscTabPage(TabPageParent pParent, const SfxItemSet& rSet)
     , m_xYearFrame(m_xBuilder->weld_widget("yearframe"))
     , m_xYearValueField(m_xBuilder->weld_spin_button("year"))
     , m_xToYearFT(m_xBuilder->weld_label("toyear"))
-    , m_xCollectUsageInfo(m_xBuilder->weld_check_button("collectusageinfo"))
     , m_xQuickStarterFrame(m_xBuilder->weld_widget("quickstarter"))
 #if defined(UNX)
     , m_xQuickLaunchCB(m_xBuilder->weld_check_button("systray"))
@@ -367,12 +366,6 @@ bool OfaMiscTabPage::FillItemSet( SfxItemSet* rSet )
         rSet->Put( SfxUInt16Item( SID_ATTR_YEAR2000, nNum ) );
     }
 
-    if (m_xCollectUsageInfo->get_state_changed_from_saved())
-    {
-        officecfg::Office::Common::Misc::CollectUsageInformation::set(m_xCollectUsageInfo->get_active(), batch);
-        bModified = true;
-    }
-
     batch->commit();
 
     if( m_xQuickLaunchCB->get_state_changed_from_saved())
@@ -412,10 +405,6 @@ void OfaMiscTabPage::Reset( const SfxItemSet* rSet )
     else
         m_xYearFrame->set_sensitive(false);
 
-    m_xCollectUsageInfo->set_active(officecfg::Office::Common::Misc::CollectUsageInformation::get());
-    m_xCollectUsageInfo->set_sensitive(!officecfg::Office::Common::Misc::CollectUsageInformation::isReadOnly());
-    m_xCollectUsageInfo->save_state();
-
     SfxItemState eState = rSet->GetItemState( SID_ATTR_QUICKLAUNCHER, false, &pItem );
     if ( SfxItemState::SET == eState )
         m_xQuickLaunchCB->set_active( static_cast<const SfxBoolItem*>(pItem)->GetValue() );
diff --git a/cui/source/options/optgdlg.hxx b/cui/source/options/optgdlg.hxx
index e048cc3e5e0c..e3d2ff6d7d4e 100644
--- a/cui/source/options/optgdlg.hxx
+++ b/cui/source/options/optgdlg.hxx
@@ -54,7 +54,6 @@ private:
     std::unique_ptr<weld::Widget> m_xYearFrame;
     std::unique_ptr<weld::SpinButton> m_xYearValueField;
     std::unique_ptr<weld::Label> m_xToYearFT;
-    std::unique_ptr<weld::CheckButton> m_xCollectUsageInfo;
     std::unique_ptr<weld::Widget> m_xQuickStarterFrame;
     std::unique_ptr<weld::CheckButton> m_xQuickLaunchCB;
 
diff --git a/cui/uiconfig/ui/optgeneralpage.ui b/cui/uiconfig/ui/optgeneralpage.ui
index 56c3a5a88fd1..e53cb7daacd3 100644
--- a/cui/uiconfig/ui/optgeneralpage.ui
+++ b/cui/uiconfig/ui/optgeneralpage.ui
@@ -316,47 +316,6 @@
         <property name="top_attach">4</property>
       </packing>
     </child>
-    <child>
-      <object class="GtkFrame" id="privacyframe">
-        <property name="visible">True</property>
-        <property name="can_focus">False</property>
-        <property name="label_xalign">0</property>
-        <property name="shadow_type">none</property>
-        <child>
-          <object class="GtkAlignment" id="alignment6">
-            <property name="visible">True</property>
-            <property name="can_focus">False</property>
-            <property name="top_padding">6</property>
-            <property name="left_padding">12</property>
-            <child>
-              <object class="GtkCheckButton" id="collectusageinfo">
-                <property name="label" translatable="yes" context="optgeneralpage|collectusageinfo">Collect usage data and send it to The Document Foundation</property>
-                <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="receives_default">False</property>
-                <property name="use_underline">True</property>
-                <property name="xalign">0</property>
-                <property name="draw_indicator">True</property>
-              </object>
-            </child>
-          </object>
-        </child>
-        <child type="label">
-          <object class="GtkLabel" id="label7">
-            <property name="visible">True</property>
-            <property name="can_focus">False</property>
-            <property name="label" translatable="yes" context="optgeneralpage|label7">Help Improve %PRODUCTNAME</property>
-            <attributes>
-              <attribute name="weight" value="bold"/>
-            </attributes>
-          </object>
-        </child>
-      </object>
-      <packing>
-        <property name="left_attach">0</property>
-        <property name="top_attach">5</property>
-      </packing>
-    </child>
     <child>
       <object class="GtkFrame" id="quickstarter">
         <property name="visible">True</property>
commit ae229608a9b5c5a50b65f5cd97fff3a734a33de8
Author:     Thorsten Behrens <Thorsten.Behrens at CIB.de>
AuthorDate: Tue Apr 21 01:13:46 2020 +0200
Commit:     Thorsten Behrens <Thorsten.Behrens at CIB.de>
CommitDate: Tue Apr 28 00:59:28 2020 +0200

    related tdf#127711: read crashdump URL from ini file
    
    Change-Id: I68f06aaf5b8c053d1deef2021876b1399e422dd7

diff --git a/desktop/source/app/app.cxx b/desktop/source/app/app.cxx
index 262b0e0da88f..af52ac73ef6e 100644
--- a/desktop/source/app/app.cxx
+++ b/desktop/source/app/app.cxx
@@ -1987,7 +1987,7 @@ void Desktop::OpenClients()
 #endif
 
 #if HAVE_FEATURE_BREAKPAD
-    if (CrashReporter::crashReportInfoExists())
+    if (CrashReporter::IsDumpEnable() && CrashReporter::crashReportInfoExists())
         handleCrashReport();
 #endif
 
diff --git a/desktop/source/app/crashreport.cxx b/desktop/source/app/crashreport.cxx
index 71434ac5b965..cadd3d8df346 100644
--- a/desktop/source/app/crashreport.cxx
+++ b/desktop/source/app/crashreport.cxx
@@ -82,9 +82,21 @@ void CrashReporter::writeCommonInfo()
     ucbhelper::InternetProxyDecider proxy_decider(::comphelper::getProcessComponentContext());
 
     const OUString protocol = "https";
-    const OUString url = "crashreport.libreoffice.org";
     const sal_Int32 port = 443;
 
+    // read configuration item 'CrashDumpUrl'
+    OUString url;
+    rtl::Bootstrap::get("CrashDumpUrl", url);
+    if (url.isEmpty())
+    {
+        // no url in config, bail out, but still set proper crash
+        // directory for local dump generation (incase CrashDumpEnable
+        // is on
+        updateMinidumpLocation();
+        mbInit = false;
+        return;
+    }
+
     const ucbhelper::InternetProxyServer proxy_server = proxy_decider.getProxy(protocol, url, port);
 
     // save the new Keys
@@ -181,15 +193,21 @@ void CrashReporter::storeExceptionHandler(google_breakpad::ExceptionHandler* pEx
 
 bool CrashReporter::IsDumpEnable()
 {
+    static bool bConfigRead = false;
+    static bool bEnable = true; // default, always on
+
+    if (bConfigRead)
+        return bEnable;
+
     OUString sToken;
     OString  sEnvVar(std::getenv("CRASH_DUMP_ENABLE"));
-    bool     bEnable = true;   // default, always on
     // read configuration item 'CrashDumpEnable' -> bool on/off
     if (rtl::Bootstrap::get("CrashDumpEnable", sToken) && sEnvVar.isEmpty())
     {
         bEnable = sToken.toBoolean();
     }
 
+    bConfigRead = true;
     return bEnable;
 }
 
commit ae649cd0850183140d839a8856dd54f21f2bdc93
Author:     Juergen Funk <juergen.funk_ml at cib.de>
AuthorDate: Mon Nov 4 10:42:06 2019 +0100
Commit:     Thorsten Behrens <Thorsten.Behrens at CIB.de>
CommitDate: Tue Apr 28 00:59:28 2020 +0200

    tdf#127711 - A runtime-switch for the MiniCrashDump and associated changes
    
    - add CrashDumpEnable to soffice.ini
    - also check env var CRASH_DUMP_ENABLE (overrides soffice.ini)
    - make sure _all_ binaries are added to symstore
    
    This is a squash of:
     https://gerrit.libreoffice.org/79273
     https://gerrit.libreoffice.org/81989
     https://gerrit.libreoffice.org/c/core/+/87260
     https://gerrit.libreoffice.org/c/core/+/87261
     https://gerrit.libreoffice.org/79272
     https://gerrit.libreoffice.org/83171
     https://gerrit.libreoffice.org/82751
     https://gerrit.libreoffice.org/83066
     https://gerrit.libreoffice.org/83726
     https://gerrit.libreoffice.org/c/core/+/86465

diff --git a/bin/symstore.sh b/bin/symstore.sh
index b368eb3e6715..564739a0279f 100755
--- a/bin/symstore.sh
+++ b/bin/symstore.sh
@@ -1,30 +1,75 @@
 #!/usr/bin/env bash
 
+# Files listed here would not be store in the symbolestore-server.
+# The format is a string with files e.g.
+#  BLACKLIST="python.exe
+#  file.dll
+#  next_file.exe"
+#
+# It removes "python.exe", "file.dll", and "next_file.exe" from what's
+# added to the symstore. Separator is the newline
+BLACK_LIST="python.exe"
+
+# List files here where it's ok for this script to find more than one
+# occurence in the build tree. Files _not_ included here will generate
+# an error, if duplicates are found.
+#
+# Same format as for BLACK_LIST above above
+MOREPDBS_OKLIST="libcurl.dll"
+
+
 add_pdb()
 {
     extension=$1
-    type=$2
+    pdbext=$2
     list=$3
-    for file in $(find "${INSTDIR}/" -name "*.${extension}"); do
+    stats_notfound=0
+    stats_found=0
+    stats_morefound=0
+    declare -a pdball
+    echo "Collect $extension"
+    ret=$(find "${INSTDIR}/" -type f -name "*.${extension}" | grep -vF "$BLACK_LIST")
+    while IFS= read -r file
+    do
         # store dll/exe itself (needed for minidumps)
-        if [ -f "$file" ]; then
+        if [ $WITHEXEC == 1 ] ; then
             cygpath -w "$file" >> "$list"
         fi
         # store pdb file
         filename=$(basename "$file" ".${extension}")
-        pdb="${WORKDIR}/LinkTarget/${type}/${filename}.pdb"
-        if [ -f "$pdb" ]; then
-            cygpath -w "$pdb" >> "$list"
+        pdball+=($(grep -i "/${filename}${pdbext}" <<< ${ALL_PDBS}))
+        if [ -n "${pdball[0]}" ]; then
+            cygpath -w "${pdball[0]}" >> "$list"
         fi
-    done
+        case ${#pdball[@]} in
+            0) ((++stats_notfound)) ;;
+            1) ((++stats_found)) ;;
+            *) ((++stats_morefound))
+                if [ -z "$(echo $file | grep -F "$MOREPDBS_OKLIST")" ]; then
+                    echo "Error: found duplicate PDBs:"
+                    for morepdbs in ${pdball[@]} ; do
+                       echo " $morepdbs"
+                    done
+                    exit 1
+                fi
+            ;;
+        esac
+        unset pdball
+    done <<EOF
+${ret}
+EOF
+
+    echo "  Found PDBs    : $stats_found"
+    echo "  Missing PDBs  : $stats_notfound"
+    echo "  Multiple PDBs : $stats_morefound"
 }
 
 # check preconditions
-if [ -z "${INSTDIR}" ] || [ -z "${WORKDIR}" ]; then
+if [ -z "${INSTDIR}" -o -z "${WORKDIR}" ]; then
     echo "INSTDIR or WORKDIR not set - script expects calling inside buildenv"
     exit 1
 fi
-if [ ! -d "${INSTDIR}" ] || [ ! -d "${WORKDIR}" ]; then
+if [ ! -d "${INSTDIR}" -o ! -d "${WORKDIR}" ]; then
     echo "INSTDIR or WORKDIR not present - script expects calling after full build"
     exit 1
 fi
@@ -36,12 +81,17 @@ which symstore.exe > /dev/null 2>&1 || {
 # defaults
 MAX_KEEP=5
 SYM_PATH=${WORKDIR}/symstore
+COMMENT=""
+COMCMD=""
+WITHEXEC=1
 
 USAGE="Usage: $0 [-h|-k <keep_num_versions>|-p <symbol_store_path>]
-       -h:         this cruft
-       -k <int>:   keep this number of old symbol versions around
-                   (default: ${MAX_KEEP}. Set to 0 for unlimited)
-       -p <path>:  specify full path to symbol store tree
+       -h:          this cruft
+       -c <comment> specifies a comment for the transaction
+       -n           do not store exe/dll on the symbole server
+       -k <int>:    keep this number of old symbol versions around
+                    (default: ${MAX_KEEP}. Set to 0 for unlimited)
+       -p <path>:   specify full path to symbol store tree
 If no path is specified, defaults to ${SYM_PATH}.
 "
 
@@ -51,7 +101,9 @@ do
    case "$1" in
     -k|--keep) MAX_KEEP="$2"; shift 2;;
     -p|--path) SYM_PATH="$2"; shift 2;;
-    -h|--help) echo "${USAGE}"; exit 0; shift;;
+    -c|--comment) COMCMD="/c"; COMMENT="$2"; shift 2;;
+    -n|--noexec) WITHEXEC=0; shift ;;
+    -h|--help) echo "${USAGE}"; exit 0;;
     -*) echo "${USAGE}" >&2; exit 1;;
     *) break;;
    esac
@@ -66,20 +118,25 @@ fi
 TMPFILE=$(mktemp) || exit 1
 trap '{ rm -f ${TMPFILE}; }' EXIT
 
+# collect all PDBs
+ALL_PDBS=$(find "${WORKDIR}/" -type f -name "*.pdb")
+
 # add dlls and executables
-add_pdb dll Library "${TMPFILE}"
-add_pdb exe Executable "${TMPFILE}"
+add_pdb dll .pdb "${TMPFILE}"
+add_pdb exe .pdb "${TMPFILE}"
+add_pdb bin .bin.pdb "${TMPFILE}"
 
 # stick all of it into symbol store
-symstore.exe add /compress /f "@$(cygpath -w "${TMPFILE}")" /s "$(cygpath -w "${SYM_PATH}")" /t "${PRODUCTNAME}" /v "${LIBO_VERSION_MAJOR}.${LIBO_VERSION_MINOR}.${LIBO_VERSION_MICRO}.${LIBO_VERSION_PATCH}${LIBO_VERSION_SUFFIX}${LIBO_VERSION_SUFFIX_SUFFIX}"
+symstore.exe add /compress /f "@$(cygpath -w "${TMPFILE}")" /s "$(cygpath -w "${SYM_PATH}")" /t "${PRODUCTNAME}" /v "${LIBO_VERSION_MAJOR}.${LIBO_VERSION_MINOR}.${LIBO_VERSION_MICRO}.${LIBO_VERSION_PATCH}${LIBO_VERSION_SUFFIX}${LIBO_VERSION_SUFFIX_SUFFIX}" "${COMCMD}" "${COMMENT}"
 rm -f "${TMPFILE}"
 
 # Cleanup symstore, older revisions will be removed.  Unless the
 # .dll/.exe changes, the .pdb should be shared, so with incremental
 # tinderbox several revisions should not be that space-demanding.
-if [ "${MAX_KEEP}" -gt 0 ] && [ -d "${SYM_PATH}/000Admin" ]; then
+if [ "${MAX_KEEP}" -gt 0 -a -d "${SYM_PATH}/000Admin" ]; then
     to_remove=$(ls -1 "${SYM_PATH}/000Admin" | grep -v '\.txt' | grep -v '\.deleted' | sort | head -n "-${MAX_KEEP}")
     for revision in $to_remove; do
+        echo "Remove $revision from symstore"
         symstore.exe del /i "${revision}" /s "$(cygpath -w "${SYM_PATH}")"
     done
 fi
diff --git a/config_host.mk.in b/config_host.mk.in
index d8936a3b1a38..8d1902609c5c 100644
--- a/config_host.mk.in
+++ b/config_host.mk.in
@@ -118,6 +118,7 @@ export EBOOK_LIBS=$(gb_SPACE)@EBOOK_LIBS@
 export ENABLE_ANDROID_EDITING=@ENABLE_ANDROID_EDITING@
 export ENABLE_AVAHI=@ENABLE_AVAHI@
 export ENABLE_BREAKPAD=@ENABLE_BREAKPAD@
+export DEFAULT_CRASHDUMP_VALUE=@DEFAULT_CRASHDUMP_VALUE@
 export ENABLE_CAIRO_CANVAS=@ENABLE_CAIRO_CANVAS@
 export ENABLE_CHART_TESTS=@ENABLE_CHART_TESTS@
 export ENABLE_CIPHER_OPENSSL_BACKEND=@ENABLE_CIPHER_OPENSSL_BACKEND@
diff --git a/configure.ac b/configure.ac
index af634d44bc19..5d328a481440 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1064,6 +1064,11 @@ libo_FUZZ_ARG_ENABLE(breakpad,
         [Enables breakpad for crash reporting.])
 )
 
+libo_FUZZ_ARG_ENABLE(crashdump,
+    AS_HELP_STRING([--disable-crashdump],
+        [Disable dump.ini and dump-file, when --enable-breakpad])
+)
+
 AC_ARG_ENABLE(fetch-external,
     AS_HELP_STRING([--disable-fetch-external],
         [Disables fetching external tarballs from web sources.])
@@ -9561,6 +9566,7 @@ AC_SUBST(ICU_UCHAR_TYPE)
 dnl ==================================================================
 dnl Breakpad
 dnl ==================================================================
+DEFAULT_CRASHDUMP_VALUE="true"
 AC_MSG_CHECKING([whether to enable breakpad])
 if test "$enable_breakpad" != yes; then
     AC_MSG_RESULT([no])
@@ -9571,6 +9577,14 @@ else
     AC_DEFINE(HAVE_FEATURE_BREAKPAD, 1)
     BUILD_TYPE="$BUILD_TYPE BREAKPAD"
 
+    AC_MSG_CHECKING([for disable crash dump])
+    if test "$enable_crashdump" = no; then
+        DEFAULT_CRASHDUMP_VALUE="false"
+        AC_MSG_RESULT([yes])
+    else
+       AC_MSG_RESULT([no])
+    fi
+
     AC_MSG_CHECKING([for crashreport config])
     if test "$with_symbol_config" = "no"; then
         BREAKPAD_SYMBOL_CONFIG="invalid"
@@ -9583,6 +9597,7 @@ else
     AC_SUBST(BREAKPAD_SYMBOL_CONFIG)
 fi
 AC_SUBST(ENABLE_BREAKPAD)
+AC_SUBST(DEFAULT_CRASHDUMP_VALUE)
 
 dnl ==================================================================
 dnl libfuzzer
diff --git a/cui/Library_cui.mk b/cui/Library_cui.mk
index cce2b7098da9..a60900ff579a 100644
--- a/cui/Library_cui.mk
+++ b/cui/Library_cui.mk
@@ -60,6 +60,9 @@ $(eval $(call gb_Library_use_libraries,cui,\
     ucbhelper \
     utl \
     vcl \
+    $(if $(ENABLE_BREAKPAD), \
+        crashreport \
+    ) \
 ))
 
 $(eval $(call gb_Library_use_externals,cui,\
diff --git a/cui/source/options/optgdlg.cxx b/cui/source/options/optgdlg.cxx
index 7ec79c6b2564..62063012432d 100644
--- a/cui/source/options/optgdlg.cxx
+++ b/cui/source/options/optgdlg.cxx
@@ -67,6 +67,8 @@
 #include <officecfg/Office/Common.hxx>
 #include <officecfg/Setup.hxx>
 #include <comphelper/configuration.hxx>
+#include <tools/diagnose_ex.h>
+#include <desktop/crashreport.hxx>
 
 #include <com/sun/star/configuration/theDefaultProvider.hpp>
 #include <com/sun/star/container/XNameAccess.hpp>
diff --git a/desktop/source/app/app.cxx b/desktop/source/app/app.cxx
index 3fb7b6017c70..262b0e0da88f 100644
--- a/desktop/source/app/app.cxx
+++ b/desktop/source/app/app.cxx
@@ -127,10 +127,6 @@
 #include <vcl/window.hxx>
 #include "langselect.hxx"
 
-#if HAVE_FEATURE_BREAKPAD
-#include <fstream>
-#endif
-
 #if defined MACOSX
 #include <errno.h>
 #include <sys/wait.h>
@@ -895,26 +891,6 @@ void Desktop::HandleBootstrapErrors(
 
 namespace {
 
-bool crashReportInfoExists()
-{
-#if HAVE_FEATURE_BREAKPAD
-    std::string path = CrashReporter::getIniFileName();
-    std::ifstream aFile(path);
-    while (aFile.good())
-    {
-        std::string line;
-        std::getline(aFile, line);
-        int sep = line.find('=');
-        if (sep >= 0)
-        {
-            std::string key = line.substr(0, sep);
-            if (key == "DumpFile")
-                return true;
-        }
-    }
-#endif
-    return false;
-}
 
 #if HAVE_FEATURE_BREAKPAD
 void handleCrashReport()
@@ -973,7 +949,12 @@ void impl_checkRecoveryState(bool& bCrashed           ,
                              bool& bRecoveryDataExists,
                              bool& bSessionDataExists )
 {
-    bCrashed = officecfg::Office::Recovery::RecoveryInfo::Crashed::get() || crashReportInfoExists();
+    bCrashed = officecfg::Office::Recovery::RecoveryInfo::Crashed::get()
+#if HAVE_FEATURE_BREAKPAD
+        || CrashReporter::crashReportInfoExists();
+#else
+        ;
+#endif
     bool elements = officecfg::Office::Recovery::RecoveryList::get()->
         hasElements();
     bool session
@@ -2006,7 +1987,7 @@ void Desktop::OpenClients()
 #endif
 
 #if HAVE_FEATURE_BREAKPAD
-    if (crashReportInfoExists())
+    if (CrashReporter::crashReportInfoExists())
         handleCrashReport();
 #endif
 
@@ -2084,11 +2065,9 @@ void Desktop::OpenClients()
             }
         }
     }
-#if HAVE_FEATURE_BREAKPAD
-    CrashReporter::writeCommonInfo();
+
     // write this information here to avoid depending on vcl in the crash reporter lib
-    CrashReporter::AddKeyValue("Language", Application::GetSettings().GetLanguageTag().getBcp47());
-#endif
+    CrashReporter::addKeyValue("Language", Application::GetSettings().GetLanguageTag().getBcp47(), CrashReporter::Create);
 
     RequestHandler::EnableRequests();
 
diff --git a/desktop/source/app/crashreport.cxx b/desktop/source/app/crashreport.cxx
index 4a702f4420bd..71434ac5b965 100644
--- a/desktop/source/app/crashreport.cxx
+++ b/desktop/source/app/crashreport.cxx
@@ -14,17 +14,17 @@
 #include <ucbhelper/proxydecider.hxx>
 #include <unotools/bootstrap.hxx>
 #include <o3tl/char16_t2wchar_t.hxx>
+#include <desktop/minidump.hxx>
 
 #include <config_version.h>
 #include <config_folders.h>
 
 #include <string>
-#include <fstream>
 
-osl::Mutex CrashReporter::maMutex;
 
 #if HAVE_FEATURE_BREAKPAD
 
+#include <fstream>
 #if defined( UNX ) && !defined MACOSX && !defined IOS && !defined ANDROID
 #include <client/linux/handler/exception_handler.h>
 #elif defined WNT
@@ -38,41 +38,47 @@ osl::Mutex CrashReporter::maMutex;
 #endif
 #endif
 
+osl::Mutex CrashReporter::maMutex;
 google_breakpad::ExceptionHandler* CrashReporter::mpExceptionHandler = nullptr;
 bool CrashReporter::mbInit = false;
-std::map<OUString, OUString> CrashReporter::maKeyValues;
+CrashReporter::vmaKeyValues CrashReporter::maKeyValues;
 
-namespace {
 
-void writeToStream(std::ofstream& strm, const OUString& rKey, const OUString& rValue)
+void CrashReporter::writeToFile(std::ios_base::openmode Openmode)
 {
-    strm << OUStringToOString(rKey, RTL_TEXTENCODING_UTF8).getStr() << "=";
-    strm << OUStringToOString(rValue, RTL_TEXTENCODING_UTF8).getStr() << "\n";
-}
+    std::ofstream ini_file(getIniFileName(), Openmode);
 
+    for (auto& keyValue : maKeyValues)
+    {
+        ini_file << rtl::OUStringToOString(keyValue.first, RTL_TEXTENCODING_UTF8).getStr() << "=";
+        ini_file << rtl::OUStringToOString(keyValue.second, RTL_TEXTENCODING_UTF8).getStr() << "\n";
+    }
+
+    maKeyValues.clear();
+    ini_file.close();
 }
 
-void CrashReporter::AddKeyValue(const OUString& rKey, const OUString& rValue)
+void CrashReporter::addKeyValue(const OUString& rKey, const OUString& rValue, tAddKeyHandling AddKeyHandling)
 {
     osl::MutexGuard aGuard(maMutex);
-    if (mbInit)
-    {
-        std::string ini_path = getIniFileName();
-        std::ofstream ini_file(ini_path, std::ios_base::app);
-        writeToStream(ini_file, rKey, rValue);
-    }
-    else
+
+    if (IsDumpEnable())
     {
-        maKeyValues.insert(std::pair<OUString, OUString>(rKey, rValue));
+        if (!rKey.isEmpty())
+            maKeyValues.push_back(mpair(rKey, rValue));
+
+        if (AddKeyHandling != AddItem)
+        {
+            if (mbInit)
+                writeToFile(std::ios_base::app);
+            else if (AddKeyHandling == Create)
+                writeCommonInfo();
+        }
     }
 }
 
-#endif
-
 void CrashReporter::writeCommonInfo()
 {
-    osl::MutexGuard aGuard(maMutex);
-
     ucbhelper::InternetProxyDecider proxy_decider(::comphelper::getProcessComponentContext());
 
     const OUString protocol = "https";
@@ -81,31 +87,33 @@ void CrashReporter::writeCommonInfo()
 
     const ucbhelper::InternetProxyServer proxy_server = proxy_decider.getProxy(protocol, url, port);
 
+    // save the new Keys
+    vmaKeyValues atlast = maKeyValues;
+    // clear the keys, the following Keys should be at the begin
+    maKeyValues.clear();
+
     // 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 << "BuildID=" << utl::Bootstrap::getBuildIdData("") << "\n";
-    minidump_file << "URL=" << protocol << "://" << url << "/submit/\n";
+    addKeyValue("ProductName", "LibreOffice", AddItem);
+    addKeyValue("Version", LIBO_VERSION_DOTTED, AddItem);
+    addKeyValue("BuildID", utl::Bootstrap::getBuildIdData(""), AddItem);
+    addKeyValue("URL", protocol + "://" + url + "/submit/", AddItem);
 
     if (proxy_server.aName != OUString())
     {
-        minidump_file << "Proxy=" << proxy_server.aName << ":" << proxy_server.nPort << "\n";
+        addKeyValue("Proxy", proxy_server.aName + ":" + OUString::number(proxy_server.nPort), AddItem);
     }
 
-    for (auto& keyValue : maKeyValues)
-    {
-        writeToStream(minidump_file, keyValue.first, keyValue.second);
-    }
-    maKeyValues.clear();
-    minidump_file.close();
+    // write the new keys at the end
+    maKeyValues.insert(maKeyValues.end(), atlast.begin(), atlast.end());
 
     mbInit = true;
 
+    writeToFile(std::ios_base::trunc);
+
     updateMinidumpLocation();
 }
 
+
 namespace {
 
 OUString getCrashDirectory()
@@ -144,11 +152,48 @@ void CrashReporter::updateMinidumpLocation()
 #endif
 }
 
+bool CrashReporter::crashReportInfoExists()
+{
+    static bool first = true;
+    static bool InfoExist = false;
+
+    if (first)
+    {
+        first = false;
+        InfoExist = crashreport::readConfig(CrashReporter::getIniFileName(), nullptr);
+    }
+
+    return InfoExist;
+}
+
+bool CrashReporter::readSendConfig(std::string& response)
+{
+    return crashreport::readConfig(CrashReporter::getIniFileName(), &response);
+}
+
 void CrashReporter::storeExceptionHandler(google_breakpad::ExceptionHandler* pExceptionHandler)
 {
-    mpExceptionHandler = pExceptionHandler;
+    if(IsDumpEnable())
+        mpExceptionHandler = pExceptionHandler;
 }
 
+
+
+bool CrashReporter::IsDumpEnable()
+{
+    OUString sToken;
+    OString  sEnvVar(std::getenv("CRASH_DUMP_ENABLE"));
+    bool     bEnable = true;   // default, always on
+    // read configuration item 'CrashDumpEnable' -> bool on/off
+    if (rtl::Bootstrap::get("CrashDumpEnable", sToken) && sEnvVar.isEmpty())
+    {
+        bEnable = sToken.toBoolean();
+    }
+
+    return bEnable;
+}
+
+
 std::string CrashReporter::getIniFileName()
 {
     OUString url = getCrashDirectory() + "dump.ini";
@@ -157,4 +202,7 @@ std::string CrashReporter::getIniFileName()
     return aRet;
 }
 
+
+#endif //HAVE_FEATURE_BREAKPAD
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/app/sofficemain.cxx b/desktop/source/app/sofficemain.cxx
index 805c4f07602e..e5f986b042f1 100644
--- a/desktop/source/app/sofficemain.cxx
+++ b/desktop/source/app/sofficemain.cxx
@@ -41,7 +41,6 @@
 #include <unotools/mediadescriptor.hxx>
 
 #if HAVE_FEATURE_BREAKPAD
-#include <fstream>
 #include <desktop/crashreport.hxx>
 
 #if defined( UNX ) && !defined MACOSX && !defined IOS && !defined ANDROID
@@ -76,11 +75,9 @@
 #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();
+    CrashReporter::addKeyValue("DumpFile", OStringToOUString(descriptor.path(), RTL_TEXTENCODING_UTF8), CrashReporter::Write);
     SAL_WARN("desktop", "minidump generated: " << descriptor.path());
+
     return succeeded;
 }
 #elif defined WNT
@@ -89,17 +86,14 @@ static bool dumpCallback(const wchar_t* path, const wchar_t* id,
                             MDRawAssertionInfo* /*assertion*/,
                             bool succeeded)
 {
-    std::string ini_path = CrashReporter::getIniFileName();
-    std::ofstream minidump_file(ini_path, std::ios_base::app);
     // TODO: moggi: can we avoid this conversion
 #ifdef _MSC_VER
 #pragma warning (disable: 4996)
 #endif
     std::wstring_convert<std::codecvt_utf8<wchar_t>> conv1;
     std::string aPath = conv1.to_bytes(std::wstring(path)) + conv1.to_bytes(std::wstring(id)) + ".dmp";
-    minidump_file << "DumpFile=" << aPath << "\n";
-    minidump_file << "GDIHandles=" << ::GetGuiResources (::GetCurrentProcess(), GR_GDIOBJECTS) << "\n";
-    minidump_file.close();
+    CrashReporter::addKeyValue("DumpFile", OStringToOUString(aPath.c_str(), RTL_TEXTENCODING_UTF8), CrashReporter::AddItem);
+    CrashReporter::addKeyValue("GDIHandles", OUString::number(::GetGuiResources (::GetCurrentProcess(), GR_GDIOBJECTS)), CrashReporter::Write);
     SAL_WARN("desktop", "minidump generated: " << aPath);
     return succeeded;
 }
diff --git a/desktop/source/minidump/minidump.cxx b/desktop/source/minidump/minidump.cxx
index 85b2374e4ad7..8b96d2ff37f1 100644
--- a/desktop/source/minidump/minidump.cxx
+++ b/desktop/source/minidump/minidump.cxx
@@ -23,7 +23,9 @@ static std::map<std::string, std::string> readStrings(std::istream& file)
 {
     std::map<std::string, std::string> parameters;
 
-    while (!file.eof())
+    // when file is not readable, the status eof would not be set
+    // better test of state is okay
+    while (file)
     {
         std::string line;
         std::getline(file, line);
@@ -189,7 +191,7 @@ static bool uploadContent(std::map<std::string, std::string>& parameters, std::s
 
 namespace crashreport {
 
-bool readConfig(const std::string& iniPath, std::string& response)
+bool readConfig(const std::string& iniPath, std::string * response)
 {
     std::ifstream file(iniPath);
     std::map<std::string, std::string> parameters = readStrings(file);
@@ -197,17 +199,29 @@ bool readConfig(const std::string& iniPath, std::string& response)
     // make sure that at least the mandatory parameters are in there
     if (parameters.find("DumpFile") == parameters.end())
     {
-        response = "ini file needs to contain a key DumpFile!";
+        if(response != nullptr)
+            *response = "ini file needs to contain a key DumpFile!";
         return false;
     }
 
     if (parameters.find("Version") == parameters.end())
     {
-        response = "ini file needs to contain a key Version!";
+        if (response != nullptr)
+            *response = "ini file needs to contain a key Version!";
         return false;
     }
 
-    return uploadContent(parameters, response);
+    if (parameters.find("URL") == parameters.end())
+    {
+        if (response != nullptr)
+            *response = "ini file needs to contain a key URL!";
+        return false;
+    }
+
+    if (response != nullptr)
+        return uploadContent(parameters, *response);
+
+    return true;
 }
 
 }
diff --git a/desktop/source/minidump/minidump_upload.cxx b/desktop/source/minidump/minidump_upload.cxx
index ded2f1df0a43..15af26430764 100644
--- a/desktop/source/minidump/minidump_upload.cxx
+++ b/desktop/source/minidump/minidump_upload.cxx
@@ -22,7 +22,7 @@ int main(int argc, char** argv)
 
     std::string iniPath(argv[1]);
     std::string response;
-    if (!crashreport::readConfig(iniPath, response))
+    if (!crashreport::readConfig(iniPath, &response))
         return EXIT_FAILURE;
 
     std::cout << "Response: " << response << std::endl;
diff --git a/framework/source/services/desktop.cxx b/framework/source/services/desktop.cxx
index 8a91db555c14..01442182f976 100644
--- a/framework/source/services/desktop.cxx
+++ b/framework/source/services/desktop.cxx
@@ -320,7 +320,7 @@ sal_Bool SAL_CALL Desktop::terminate()
         // see dispose() for further information.
         /* SAFE AREA --------------------------------------------------------------------------------------- */
         SolarMutexClearableGuard aWriteLock;
-        CrashReporter::AddKeyValue("ShutDown", OUString::boolean(true));
+        CrashReporter::addKeyValue("ShutDown", OUString::boolean(true), CrashReporter::Write);
         m_bIsTerminated = true;
         aWriteLock.clear();
         /* UNSAFE AREA ------------------------------------------------------------------------------------- */
diff --git a/include/desktop/crashreport.hxx b/include/desktop/crashreport.hxx
index 6056adbe1d28..585c0af5e1a9 100644
--- a/include/desktop/crashreport.hxx
+++ b/include/desktop/crashreport.hxx
@@ -17,7 +17,8 @@
 
 #include <config_features.h>
 
-#include <map>
+// vector not sort the entries
+#include <vector>
 #include <string>
 
 namespace google_breakpad
@@ -41,40 +42,52 @@ CRASHREPORT_DLLPUBLIC
 /*class*/ CrashReporter
 {
 public:
-    static void AddKeyValue(const OUString& rKey, const OUString& rValue);
+    typedef enum {AddItem, Write, Create} tAddKeyHandling;
+#if HAVE_FEATURE_BREAKPAD
+    static void addKeyValue(const OUString& rKey, const OUString& rValue, tAddKeyHandling AddKeyHandling);
 
-    static std::string getIniFileName();
+    static void storeExceptionHandler(google_breakpad::ExceptionHandler* pExceptionHandler);
 
-    static void writeCommonInfo();
+    static bool crashReportInfoExists();
 
-    static void storeExceptionHandler(google_breakpad::ExceptionHandler* pExceptionHandler);
+    static bool readSendConfig(std::string& response);
 
-    // when we create the ExceptionHandler we have no access to the user
-    // profile yet, so update when we have access
-    static void updateMinidumpLocation();
+    static bool IsDumpEnable();
 
 private:
-
     static osl::Mutex maMutex;
-
     static bool mbInit;
-
-    static std::map<OUString, OUString> maKeyValues; // used to temporarily save entries before the old info has been uploaded
+    typedef  struct _mpair
+    {
+        OUString first;
+        OUString second;
+        _mpair(const OUString& First, const OUString& Second)
+        {
+            first  = First;
+            second = Second;
+        };
+    } mpair;
+
+    typedef std::vector<mpair> vmaKeyValues;
+    static vmaKeyValues maKeyValues; // used to temporarily save entries before the old info has been uploaded
 
     static google_breakpad::ExceptionHandler* mpExceptionHandler;
-};
 
-// Add dummy methods for the non-breakpad case. That allows us to use
-// the code without linking to the lib and without adding HAVE_FEATURE_BREAKPAD
-// everywhere we want to log something to the crash report system.
-#if HAVE_FEATURE_BREAKPAD
-#else
-inline void CrashReporter::AddKeyValue(SAL_UNUSED_PARAMETER const OUString& /*rKey*/, SAL_UNUSED_PARAMETER const OUString& /*rValue*/)
-{
-}
-#endif
+    static std::string getIniFileName();
+    static void writeCommonInfo();
+    static void writeToFile(std::ios_base::openmode Openmode);
+    // when we create the ExceptionHandler we have no access to the user
+    // profile yet, so update when we have access
+    static void updateMinidumpLocation();
 
+#else
+    // Add dummy methods for the non-breakpad case. That allows us to use
+    // // the code without linking to the lib and without adding HAVE_FEATURE_BREAKPAD
+    // // everywhere we want to log something to the crash report system.
+    inline static void addKeyValue(SAL_UNUSED_PARAMETER const OUString& /*rKey*/, SAL_UNUSED_PARAMETER const OUString& /*rValue*/, SAL_UNUSED_PARAMETER tAddKeyHandling /*AddKeyHandling*/) {};
+#endif // HAVE_FEATURE_BREAKPAD
+};
 
-#endif
+#endif // INCLUDED_DESKTOP_CRASHREPORT_HXX
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/desktop/minidump.hxx b/include/desktop/minidump.hxx
index 63336cae5595..6ed0e18277f8 100644
--- a/include/desktop/minidump.hxx
+++ b/include/desktop/minidump.hxx
@@ -16,7 +16,18 @@
 
 namespace crashreport {
 
-CRASHREPORT_DLLPUBLIC bool readConfig(const std::string& iniPath, std::string& response);
+// when response = nullptr only make test
+/** Read+Send, Test and send info from the Dump.ini .
+
+        @param [in] iniPath Path-file to the read/test ini-file
+        @param [in] response=nullptr in this case made the Test only
+        @param [in] response!=nullptr in this case made the Read+Send
+
+        @retval true       Read+Send, Test was okay
+        @retval false      Read+Send, Test is a error
+*/
+
+CRASHREPORT_DLLPUBLIC bool readConfig(const std::string& iniPath, std::string * response);
 
 }
 
diff --git a/instsetoo_native/CustomTarget_setup.mk b/instsetoo_native/CustomTarget_setup.mk
index 97b271638069..16cc6ebaded1 100644
--- a/instsetoo_native/CustomTarget_setup.mk
+++ b/instsetoo_native/CustomTarget_setup.mk
@@ -119,6 +119,7 @@ $(call gb_CustomTarget_get_workdir,instsetoo_native/setup)/$(call gb_Helper_get_
 	( \
 		echo '[Bootstrap]' \
 		&& echo 'CrashDirectory=$${$$BRAND_BASE_DIR/$(LIBO_ETC_FOLDER)/$(call gb_Helper_get_rcfile,bootstrap):UserInstallation}/crash' \
+		&& echo 'CrashDumpEnable=$(DEFAULT_CRASHDUMP_VALUE)' \
 		&& echo 'HideEula=1' \
 		&& echo 'Logo=1' \
 		&& echo 'NativeProgress=false' \
diff --git a/instsetoo_native/util/openoffice.lst.in b/instsetoo_native/util/openoffice.lst.in
index fe3aafbe18d8..e4ac6bca47ee 100644
--- a/instsetoo_native/util/openoffice.lst.in
+++ b/instsetoo_native/util/openoffice.lst.in
@@ -35,6 +35,7 @@ Globals
             OOODOWNLOADNAME 1
             64BITPRODUCT @WINDOWS_X64@
             WINDOWSSDKVERSION @WINDOWS_SDK_VERSION@
+            CRASHDUMPENABLE @DEFAULT_CRASHDUMP_VALUE@
         }
     }
 }
diff --git a/scp2/source/ooo/common_brand.scp b/scp2/source/ooo/common_brand.scp
index 08e3b43df660..e46bd98acd60 100644
--- a/scp2/source/ooo/common_brand.scp
+++ b/scp2/source/ooo/common_brand.scp
@@ -439,6 +439,15 @@ ProfileItem gid_Brand_Profileitem_Soffice_CrashDirectory
     Value = "${$BRAND_BASE_DIR/" LIBO_ETC_FOLDER "/" PROFILENAME(bootstrap) ":UserInstallation}/crash";
 End
 
+ProfileItem gid_Brand_Profileitem_Soffice_CrashDump
+    ProfileID = gid_Brand_Profile_Soffice_Ini;
+    ModuleID = gid_Module_Root_Brand;
+    Section = "Bootstrap";
+    Key = "CrashDumpEnable";
+    Value = "${CRASHDUMPENABLE}";
+End
+
+
 ProfileItem gid_Brand_Profileitem_Soffice_SecureUserConfig
     ProfileID = gid_Brand_Profile_Soffice_Ini;
     ModuleID = gid_Module_Root_Brand;
diff --git a/solenv/gbuild/platform/com_MSC_class.mk b/solenv/gbuild/platform/com_MSC_class.mk
index 5b4a5ed53a6d..4cd84b58bd34 100644
--- a/solenv/gbuild/platform/com_MSC_class.mk
+++ b/solenv/gbuild/platform/com_MSC_class.mk
@@ -123,7 +123,7 @@ gb_LinkTarget_INCLUDE :=\
 # We must name the .pdb like libname.pdb, not libname.\(dll\|exe\|pyd\).pdb,
 # otherwise WinDbg does not find it.
 define gb_LinkTarget__get_pdb_filename
-$(patsubst %.dll,%.pdb,$(patsubst %.exe,%.pdb,$(patsubst %.pyd,%.pdb,$(1))))
+$(patsubst %.dll,%.pdb,$(patsubst %.exe,%.pdb,$(patsubst %.bin,%.bin.pdb,$(patsubst %.pyd,%.pdb,$(1)))))
 endef
 
 gb_LinkTarget_get_pdbfile_in = \
diff --git a/svx/source/dialog/crashreportdlg.cxx b/svx/source/dialog/crashreportdlg.cxx
index 652bc4565ba0..85801277c27c 100644
--- a/svx/source/dialog/crashreportdlg.cxx
+++ b/svx/source/dialog/crashreportdlg.cxx
@@ -14,7 +14,6 @@
 
 #include <rtl/bootstrap.hxx>
 #include <desktop/crashreport.hxx>
-#include <desktop/minidump.hxx>
 #include <sfx2/safemode.hxx>
 #include <comphelper/processfactory.hxx>
 #include <osl/file.hxx>
@@ -67,10 +66,8 @@ IMPL_LINK(CrashReportDialog, BtnHdl, weld::Button&, rBtn, void)
 {
     if (&rBtn == mxBtnSend.get())
     {
-        std::string ini_path = CrashReporter::getIniFileName();
-
         std::string response;
-        bool bSuccess = crashreport::readConfig(ini_path, response);
+        bool bSuccess = CrashReporter::readSendConfig(response);
 
         OUString aCrashID = OUString::createFromAscii(response.c_str());
 
diff --git a/vcl/opengl/win/WinDeviceInfo.cxx b/vcl/opengl/win/WinDeviceInfo.cxx
index 2ebccf9ee6f4..f78481e44fe9 100644
--- a/vcl/opengl/win/WinDeviceInfo.cxx
+++ b/vcl/opengl/win/WinDeviceInfo.cxx
@@ -540,9 +540,9 @@ void writeToLog(SvStream& rStrm, const char* pKey, const OUString & rVal)
 
 bool WinOpenGLDeviceInfo::isDeviceBlocked()
 {
-    CrashReporter::AddKeyValue("OpenGLVendor", maAdapterVendorID);
-    CrashReporter::AddKeyValue("OpenGLDevice", maAdapterDeviceID);
-    CrashReporter::AddKeyValue("OpenGLDriver", maDriverVersion);
+    CrashReporter::addKeyValue("OpenGLVendor", maAdapterVendorID, CrashReporter::AddItem);
+    CrashReporter::addKeyValue("OpenGLDevice", maAdapterDeviceID, CrashReporter::AddItem);
+    CrashReporter::addKeyValue("OpenGLDriver", maDriverVersion, CrashReporter::Write);
 
     SAL_INFO("vcl.opengl", maDriverVersion);
     SAL_INFO("vcl.opengl", maDriverDate);
diff --git a/vcl/opengl/x11/X11DeviceInfo.cxx b/vcl/opengl/x11/X11DeviceInfo.cxx
index 577e2c2ad3b2..b9653eefdc8e 100644
--- a/vcl/opengl/x11/X11DeviceInfo.cxx
+++ b/vcl/opengl/x11/X11DeviceInfo.cxx
@@ -283,8 +283,8 @@ bool X11OpenGLDeviceInfo::isDeviceBlocked()
     if (mnGLMajorVersion == 1)
         return true;
 
-    CrashReporter::AddKeyValue("AdapterVendorId", OStringToOUString(maVendor, RTL_TEXTENCODING_UTF8));
-    CrashReporter::AddKeyValue("AdapterDeviceId", OStringToOUString(maRenderer, RTL_TEXTENCODING_UTF8));
+    CrashReporter::addKeyValue("AdapterVendorId", OStringToOUString(maVendor, RTL_TEXTENCODING_UTF8), CrashReporter::AddItem);
+    CrashReporter::addKeyValue("AdapterDeviceId", OStringToOUString(maRenderer, RTL_TEXTENCODING_UTF8), CrashReporter::Write);
 
     SAL_INFO("vcl.opengl", "Vendor: " << maVendor);
     SAL_INFO("vcl.opengl", "Renderer: " << maRenderer);
diff --git a/vcl/source/app/salplug.cxx b/vcl/source/app/salplug.cxx
index 03c011ab7c75..d5179e71274c 100644
--- a/vcl/source/app/salplug.cxx
+++ b/vcl/source/app/salplug.cxx
@@ -297,7 +297,7 @@ void SalAbort( const OUString& rErrorText, bool bDumpCore )
         std::fprintf( stderr, "Application Error\n" );
     else
     {
-        CrashReporter::AddKeyValue("AbortMessage", rErrorText);
+        CrashReporter::addKeyValue("AbortMessage", rErrorText, CrashReporter::Write);
         std::fprintf( stderr, "%s\n", OUStringToOString(rErrorText, osl_getThreadTextEncoding()).getStr() );
     }
     if( bDumpCore )
diff --git a/vcl/source/opengl/OpenGLHelper.cxx b/vcl/source/opengl/OpenGLHelper.cxx
index 16fb939290b4..338626b1279e 100644
--- a/vcl/source/opengl/OpenGLHelper.cxx
+++ b/vcl/source/opengl/OpenGLHelper.cxx
@@ -1033,7 +1033,7 @@ bool OpenGLHelper::isVCLOpenGLEnabled()
         if (!getenv("SAL_DISABLE_GL_WATCHDOG"))
             OpenGLWatchdogThread::start();
     }
-    CrashReporter::AddKeyValue("UseOpenGL", OUString::boolean(bRet));
+    CrashReporter::addKeyValue("UseOpenGL", OUString::boolean(bRet), CrashReporter::Write);
 
     return bRet;
 }
diff --git a/vcl/source/window/builder.cxx b/vcl/source/window/builder.cxx
index cb37f7f8e7e9..68f4b8c238b0 100644
--- a/vcl/source/window/builder.cxx
+++ b/vcl/source/window/builder.cxx
@@ -430,7 +430,7 @@ VclBuilder::VclBuilder(vcl::Window *pParent, const OUString& sUIDir, const OUStr
     catch (const css::uno::Exception &rExcept)
     {
         DBG_UNHANDLED_EXCEPTION("vcl.layout", "Unable to read .ui file");
-        CrashReporter::AddKeyValue("VclBuilderException", "Unable to read .ui file: " + rExcept.Message);
+        CrashReporter::addKeyValue("VclBuilderException", "Unable to read .ui file: " + rExcept.Message, CrashReporter::Write);
         throw;
     }
 
diff --git a/vcl/win/app/salinst.cxx b/vcl/win/app/salinst.cxx
index c4a290adb092..bce1db45bbbd 100644
--- a/vcl/win/app/salinst.cxx
+++ b/vcl/win/app/salinst.cxx
@@ -80,7 +80,7 @@ void SalAbort( const OUString& rErrorText, bool )
     }
     else
     {
-        CrashReporter::AddKeyValue("AbortMessage", rErrorText);
+        CrashReporter::addKeyValue("AbortMessage", rErrorText, CrashReporter::Write);
         // make sure crash reporter is triggered
         RaiseException( 0, EXCEPTION_NONCONTINUABLE, 0, nullptr );
         FatalAppExitW( 0, o3tl::toW(rErrorText.getStr()) );
commit 1b74dff00f9945ccc02cbc062ab545d3ae0475a2
Author:     Thorsten Behrens <thorsten.behrens at cib.de>
AuthorDate: Tue Jun 11 01:24:26 2019 +0200
Commit:     Thorsten Behrens <Thorsten.Behrens at CIB.de>
CommitDate: Tue Apr 28 00:59:28 2020 +0200

    Some product-name-with-spaces fixes
    
    - use productname var w/o space for config dir
      ..which also saves some duplicated code
    - add hack to make rpmbuild get a proper build root
      -> otherwise rpm BUILDROOT will contain spaces, and things break
         at various places during packaging
    
    Change-Id: I20229ce533913fa000978aa84b1a2a5d998da14d

diff --git a/instsetoo_native/CustomTarget_install.mk b/instsetoo_native/CustomTarget_install.mk
index ab620d5844ed..72a29361c253 100644
--- a/instsetoo_native/CustomTarget_install.mk
+++ b/instsetoo_native/CustomTarget_install.mk
@@ -62,7 +62,7 @@ export LOCAL_COMMON_OUT := $(instsetoo_OUT)
 
 instsetoo_native_WITH_LANG := en-US $(filter-out en-US,$(gb_WITH_LANG))
 
-PRODUCTNAME_no_spaces := $(subst $(WHITESPACE),,$(PRODUCTNAME))
+PRODUCTNAME_no_spaces := $(PRODUCTNAME_WITHOUT_SPACES)
 
 ifeq (WNT,$(OS))
 define instsetoo_native_msitemplates
@@ -152,8 +152,8 @@ $(call gb_CustomTarget_get_workdir,instsetoo_native/install)/msi_main_signing.do
 			$(if $(PFXFILE),-f $(PFXFILE)) \
 			$(if $(PFXPASSWORD),-p $(PFXPASSWORD)) \
 			$(if $(TIMESTAMPURL),-t $(TIMESTAMPURL)) \
-			-d $(PRODUCTNAME)\ $(LIBO_VERSION_MAJOR).$(LIBO_VERSION_MINOR).$(LIBO_VERSION_MICRO).$(LIBO_VERSION_PATCH) \
-			$(WORKDIR)/installation/$(PRODUCTNAME)/msi/install/*/*.msi \
+                       -d $(shell echo $(PRODUCTNAME) | sed -e 's/ /_/g')\ $(LIBO_VERSION_MAJOR).$(LIBO_VERSION_MINOR).$(LIBO_VERSION_MICRO).$(LIBO_VERSION_PATCH) \
+                       $(WORKDIR)/installation/$(PRODUCTNAME_NO_SPACES)/msi/install/*/*.msi \
 	&& touch $@
 
 $(call gb_CustomTarget_get_workdir,instsetoo_native/install)/msi_helppack_signing.done:
@@ -164,8 +164,8 @@ $(call gb_CustomTarget_get_workdir,instsetoo_native/install)/msi_helppack_signin
 			$(if $(PFXFILE),-f $(PFXFILE)) \
 			$(if $(PFXPASSWORD),-p $(PFXPASSWORD)) \
 			$(if $(TIMESTAMPURL),-t $(TIMESTAMPURL)) \
-			-d $(PRODUCTNAME)\ $(LIBO_VERSION_MAJOR).$(LIBO_VERSION_MINOR).$(LIBO_VERSION_MICRO).$(LIBO_VERSION_PATCH)\ Helppack \
-			$(WORKDIR)/installation/$(PRODUCTNAME)_helppack/msi/install/*/*.msi \
+                       -d $(shell echo $(PRODUCTNAME) | sed -e 's/ /_/g')\ $(LIBO_VERSION_MAJOR).$(LIBO_VERSION_MINOR).$(LIBO_VERSION_MICRO).$(LIBO_VERSION_PATCH)\ Helppack \
+                       $(WORKDIR)/installation/$(PRODUCTNAME_NO_SPACES)_helppack/msi/install/*/*.msi \
 	&& touch $@
 
 $(call gb_CustomTarget_get_workdir,instsetoo_native/install)/msi_sdk_signing.done:
@@ -176,8 +176,8 @@ $(call gb_CustomTarget_get_workdir,instsetoo_native/install)/msi_sdk_signing.don
 			$(if $(PFXFILE),-f $(PFXFILE)) \
 			$(if $(PFXPASSWORD),-p $(PFXPASSWORD)) \
 			$(if $(TIMESTAMPURL),-t $(TIMESTAMPURL)) \
-			-d $(PRODUCTNAME)\ $(LIBO_VERSION_MAJOR).$(LIBO_VERSION_MINOR).$(LIBO_VERSION_MICRO).$(LIBO_VERSION_PATCH)\ SDK \
-			$(WORKDIR)/installation/$(PRODUCTNAME)_SDK/msi/install/*/*.msi \
+                       -d $(shell echo $(PRODUCTNAME) | sed -e 's/ /_/g')\ $(LIBO_VERSION_MAJOR).$(LIBO_VERSION_MINOR).$(LIBO_VERSION_MICRO).$(LIBO_VERSION_PATCH)\ SDK \
+                       $(WORKDIR)/installation/$(PRODUCTNAME_NO_SPACES)_SDK/msi/install/*/*.msi \
 	&& touch $@
 
 # vim: set noet sw=4 ts=4:
diff --git a/instsetoo_native/CustomTarget_setup.mk b/instsetoo_native/CustomTarget_setup.mk
index 209404ec0e1b..97b271638069 100644
--- a/instsetoo_native/CustomTarget_setup.mk
+++ b/instsetoo_native/CustomTarget_setup.mk
@@ -40,7 +40,7 @@ $(call gb_CustomTarget_get_workdir,instsetoo_native/setup)/$(call gb_Helper_get_
 		&& echo 'InstallMode=<installmode>' \
 		&& echo 'ProductKey=$(PRODUCTNAME) $(PRODUCTVERSION)' \
 		$(if $(ENABLE_RELEASE_BUILD),\
-			&& echo 'UserInstallation=$$SYSUSERCONFIG/$(if $(filter-out HAIKU MACOSX WNT,$(OS)),$(shell echo $(PRODUCTNAME) | tr "[:upper:]" "[:lower:]"),$(shell echo $(PRODUCTNAME) | sed -e 's/ /%20/g'))/4', \
+			&& echo 'UserInstallation=$$SYSUSERCONFIG/$(if $(filter-out HAIKU MACOSX WNT,$(OS)),$(shell echo $(PRODUCTNAME_WITHOUT_SPACES) | tr "[:upper:]" "[:lower:]"),$(PRODUCTNAME_WITHOUT_SPACES))/4', \
 			&& echo 'UserInstallation=$$ORIGIN/..') \
 	) > $@
 
diff --git a/solenv/bin/modules/installer/download.pm b/solenv/bin/modules/installer/download.pm
index 63103816e89f..c1776053ec1e 100644
--- a/solenv/bin/modules/installer/download.pm
+++ b/solenv/bin/modules/installer/download.pm
@@ -290,7 +290,7 @@ sub get_downloadname_productname
 
     my $start = "";
 
-    $start = $allvariables->{'PRODUCTNAME'};
+    $start = $allvariables->{'PRODUCTNAME'}; $start =~ s/ /_/g;
 
     return $start;
 }
diff --git a/solenv/bin/modules/installer/setupscript.pm b/solenv/bin/modules/installer/setupscript.pm
index 6eefe01f0bd5..4a5a1003cb3e 100644
--- a/solenv/bin/modules/installer/setupscript.pm
+++ b/solenv/bin/modules/installer/setupscript.pm
@@ -166,7 +166,7 @@ sub add_lowercase_productname_setupscriptvariable
                 $newline = "\%MASKEDPRODUCTNAME " . $value . "\n";
                 push(@{$variablesref} ,$newline);
                 $value = $original;
-                $value =~ s/\s/\_/g;
+                $value =~ s/\s//g;
                 $newline = "\%UNIXPRODUCTNAME " . lc($value) . "\n";
                 push(@{$variablesref} ,$newline);
                 $newline = "\%SYSTEMINTUNIXPACKAGENAME " . lc($value) . "\n";


More information about the Libreoffice-commits mailing list