LibreOffice Module desktop (master)  1
crashreport.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  */
9 
10 #include <desktop/crashreport.hxx>
11 #include <rtl/bootstrap.hxx>
12 #include <osl/file.hxx>
15 #include <unotools/bootstrap.hxx>
17 
18 #include <config_version.h>
19 #include <config_folders.h>
20 
21 #include <string>
22 #include <fstream>
23 
24 osl::Mutex CrashReporter::maMutex;
25 
26 #if HAVE_FEATURE_BREAKPAD
27 
28 #if defined( UNX ) && !defined MACOSX && !defined IOS && !defined ANDROID
29 #include <client/linux/handler/exception_handler.h>
30 #elif defined WNT
31 #if defined __clang__
32 #pragma clang diagnostic push
33 #pragma clang diagnostic ignored "-Wmicrosoft-enum-value"
34 #endif
35 #include <client/windows/handler/exception_handler.h>
36 #if defined __clang__
37 #pragma clang diagnostic pop
38 #endif
39 #endif
40 
41 google_breakpad::ExceptionHandler* CrashReporter::mpExceptionHandler = nullptr;
42 bool CrashReporter::mbInit = false;
43 std::map<OUString, OUString> CrashReporter::maKeyValues;
44 
45 namespace {
46 
47 void writeToStream(std::ofstream& strm, const OUString& rKey, const OUString& rValue)
48 {
49  strm << OUStringToOString(rKey, RTL_TEXTENCODING_UTF8).getStr() << "=";
50  strm << OUStringToOString(rValue, RTL_TEXTENCODING_UTF8).getStr() << "\n";
51 }
52 
53 }
54 
55 void CrashReporter::AddKeyValue(const OUString& rKey, const OUString& rValue)
56 {
57  osl::MutexGuard aGuard(maMutex);
58  if (mbInit)
59  {
60  std::string ini_path = getIniFileName();
61  std::ofstream ini_file(ini_path, std::ios_base::app);
62  writeToStream(ini_file, rKey, rValue);
63  }
64  else
65  {
66  maKeyValues.insert(std::pair<OUString, OUString>(rKey, rValue));
67  }
68 }
69 
70 #endif
71 
73 {
74  osl::MutexGuard aGuard(maMutex);
75 
77 
78  const OUString protocol = "https";
79  const OUString url = "crashreport.libreoffice.org";
80  const sal_Int32 port = 443;
81 
82  const ucbhelper::InternetProxyServer proxy_server = proxy_decider.getProxy(protocol, url, port);
83 
84  // limit the amount of code that needs to be executed before the crash reporting
85  std::string ini_path = CrashReporter::getIniFileName();
86  std::ofstream minidump_file(ini_path, std::ios_base::trunc);
87  minidump_file << "ProductName=LibreOffice\n";
88  minidump_file << "Version=" LIBO_VERSION_DOTTED "\n";
89  minidump_file << "BuildID=" << utl::Bootstrap::getBuildIdData("") << "\n";
90  minidump_file << "URL=" << protocol << "://" << url << "/submit/\n";
91 
92  if (proxy_server.aName != OUString())
93  {
94  minidump_file << "Proxy=" << proxy_server.aName << ":" << proxy_server.nPort << "\n";
95  }
96 
97  for (auto& keyValue : maKeyValues)
98  {
99  writeToStream(minidump_file, keyValue.first, keyValue.second);
100  }
101  maKeyValues.clear();
102  minidump_file.close();
103 
104  mbInit = true;
105 
107 }
108 
109 namespace {
110 
111 OUString getCrashDirectory()
112 {
113  OUString aCrashURL;
114  rtl::Bootstrap::get("CrashDirectory", aCrashURL);
115  // Need to convert to URL in case of user-defined path
116  osl::FileBase::getFileURLFromSystemPath(aCrashURL, aCrashURL);
117 
118  if (aCrashURL.isEmpty()) { // Fall back to user profile
119  aCrashURL = "${$BRAND_BASE_DIR/" LIBO_ETC_FOLDER "/" SAL_CONFIGFILE("bootstrap") ":UserInstallation}/crash/";
120  rtl::Bootstrap::expandMacros(aCrashURL);
121  }
122 
123  if (!aCrashURL.endsWith("/"))
124  aCrashURL += "/";
125 
126  osl::Directory::create(aCrashURL);
127  OUString aCrashPath;
128  osl::FileBase::getSystemPathFromFileURL(aCrashURL, aCrashPath);
129  return aCrashPath;
130 }
131 
132 }
133 
135 {
136 #if defined( UNX ) && !defined MACOSX && !defined IOS && !defined ANDROID
137  OUString aURL = getCrashDirectory();
138  OString aOStringUrl = OUStringToOString(aURL, RTL_TEXTENCODING_UTF8);
139  google_breakpad::MinidumpDescriptor descriptor(aOStringUrl.getStr());
140  mpExceptionHandler->set_minidump_descriptor(descriptor);
141 #elif defined WNT
142  OUString aURL = getCrashDirectory();
143  mpExceptionHandler->set_dump_path(o3tl::toW(aURL.getStr()));
144 #endif
145 }
146 
147 void CrashReporter::storeExceptionHandler(google_breakpad::ExceptionHandler* pExceptionHandler)
148 {
149  mpExceptionHandler = pExceptionHandler;
150 }
151 
153 {
154  OUString url = getCrashDirectory() + "dump.ini";
155  OString aUrl = OUStringToOString(url, RTL_TEXTENCODING_UTF8);
156  std::string aRet(aUrl.getStr());
157  return aRet;
158 }
159 
160 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
static bool mbInit
Definition: crashreport.hxx:60
static google_breakpad::ExceptionHandler * mpExceptionHandler
Definition: crashreport.hxx:64
css::uno::Reference< css::deployment::XPackageRegistry > create(css::uno::Reference< css::deployment::XPackageRegistry > const &xRootRegistry, OUString const &context, OUString const &cachePath, css::uno::Reference< css::uno::XComponentContext > const &xComponentContext)
static void storeExceptionHandler(google_breakpad::ExceptionHandler *pExceptionHandler)
static osl::Mutex maMutex
Definition: crashreport.hxx:58
static std::map< OUString, OUString > maKeyValues
Definition: crashreport.hxx:62
#define SAL_CONFIGFILE(name)
static void updateMinidumpLocation()
static void AddKeyValue(const OUString &rKey, const OUString &rValue)
Definition: crashreport.hxx:72
static std::string getIniFileName()
OString OUStringToOString(const OUString &str, ConnectionSettings const *settings)
Reference< XComponentContext > getProcessComponentContext()
static void writeCommonInfo()
Definition: crashreport.cxx:72
InternetProxyServer getProxy(const OUString &rProtocol, const OUString &rHost, sal_Int32 nPort) const
static OUString getBuildIdData(OUString const &_sDefault)