aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--linux/makepkg/PKGBUILD29
-rw-r--r--meson.build10
-rw-r--r--src/crashhandler.cpp44
-rw-r--r--src/crashhandler.h38
-rw-r--r--src/main.cpp32
-rw-r--r--src/meson.build4
-rw-r--r--tools/src/crashhandler/main.go4
7 files changed, 97 insertions, 64 deletions
diff --git a/linux/makepkg/PKGBUILD b/linux/makepkg/PKGBUILD
index debf2f1..59c7eee 100644
--- a/linux/makepkg/PKGBUILD
+++ b/linux/makepkg/PKGBUILD
@@ -26,11 +26,11 @@ sha512sums=('SKIP'
#validgpgkeys=(BB1C090188E3E32B375C13FD095DE26BC16D2E98) # Aqua-sama <aqua@iserlohn-fortress.net>
-## Build Options
+## not-use flags Options
# Enable plugin signing:
-# meson/ninja will generate the privateKey.pem and publicKey.pem in the $builddir
-# Because this embeds the public key into the executable, enabling this option will break reproducible builds.
_signPlugins=
+# Enable breakpad integraton:
+_enableBreakpad=
prepare() {
cd $srcdir/smolbote
@@ -53,6 +53,7 @@ build() {
mkdir $srcdir/build
fi
cd $srcdir/smolbote
+ KCONFIG_CONFIG=linux/.config alldefconfig
# For a list of configureable options, check smolbote/meson_options.txt, or
# run `meson configure` in $srcdir/build
@@ -65,13 +66,15 @@ build() {
# b_lto: Use link time optimization
meson --buildtype=plain --wrap-mode=nodownload \
--prefix=/usr/local --auto-features=disabled \
- -Db_pie=true -Db_lto=true -Dcpp_link_args="-fuse-ld=gold" \
+ -Db_pie=true -Db_lto=true \
-Dmanpage=enabled \
$srcdir/build
- # uncomment to enable crashhandler
- #meson configure -Dcrashhandler=enabled $srcdir/build
- #KCONFIG_CONFIG=linux/.config setconfig USEBREAKPAD=y
+ if [ -n $_enableBreakpad ]; then
+ msg2 "Enabling crashhandler"
+ meson configure -Ddebug=true -Dcrashhandler=enabled $srcdir/build
+ KCONFIG_CONFIG=linux/.config setconfig USEBREAKPAD=y
+ fi
# Run menuconfig
#KCONFIG_CONFIG=linux/.config menuconfig
@@ -88,10 +91,16 @@ package() {
if [ -n $_signPlugins ]; then
msg "Signing plugins"
for so in $pkgdir/usr/local/lib/smolbote/plugins/*.so; do
+ msg2 "Signed $(basename $so)"
openssl dgst -sha256 -sign $srcdir/build/privateKey.pem -out $so.sig $so
- # If the sigs were in another location, use
- #install -m644 -t $pkgdir/usr/local/lib/smolbote/plugins $so.sig
done
- fi # _signPlugins
+ fi
+
+ if [ -n $_enableBreakpad ]; then
+ msg "Installing debug symbols"
+ ninja -C $srcdir/build linux/poi.sym
+ install -dm644 $pkgdir/usr/local/lib/smolbote/symbols/poi/$(head -n1 linux/poi.sym | awk '{ print $(NF-1) }')
+ install -m644 -t $pkgdir/usr/local/lib/smolbote/symbols/poi/$(head -n1 linux/poi.sym | awk '{ print $(NF-1) }') $srcdir/build/linux/poi.sym
+ fi
}
diff --git a/meson.build b/meson.build
index 6a7518b..009ec91 100644
--- a/meson.build
+++ b/meson.build
@@ -38,6 +38,7 @@ add_project_arguments(cxx.get_supported_arguments([
'-Wdate-time', # Warn when using __TIME__ and __DATE__ macros
'-Wimplicit-fallthrough',
]), language: 'cpp')
+
add_project_link_arguments(cxx.get_supported_link_arguments([
'-fuse-ld=gold'
]), language: 'cpp')
@@ -51,9 +52,14 @@ dep_qt5 = dependency('qt5',
dep_spdlog = dependency('spdlog', fallback: ['spdlog', 'spdlog_dep'], version: '>=1.3.1')
optional_deps = []
+poi_cpp_args = []
dep_breakpad = dependency('breakpad-client', include_type: 'system', required: get_option('crashhandler'))
dep_threads = dependency('threads', include_type: 'system', required: get_option('crashhandler'))
+if dep_breakpad.found()
+ poi_cpp_args += '-DHAVE_BREAKPAD'
+endif
+
dep_gtest = dependency('gtest', required: false, disabler: true)
# Generate config header
@@ -89,10 +95,10 @@ subdir('test/conf')
ssconfig = poi_sourceset.apply(cdata)
poi_exe = executable(get_option('poi'),
- cpp_args: ['-DQAPPLICATION_CLASS=QApplication'],
+ cpp_args: ['-DQAPPLICATION_CLASS=QApplication', poi_cpp_args],
sources: [ssconfig.sources()],
include_directories: [include, include_directories('src')],
- dependencies: [dep_qt5, dep_spdlog, dep_SingleApplication, dep_args, optional_deps, dep_about, dep_bookmarks, dep_configuration, dep_downloads, dep_pluginloader, dep_urlfilter],
+ dependencies: [dep_qt5, dep_spdlog, dep_SingleApplication, dep_args, optional_deps, dep_about, dep_bookmarks, dep_configuration, dep_downloads, dep_pluginloader, dep_urlfilter, ssconfig.dependencies()],
install: true,
)
diff --git a/src/crashhandler.cpp b/src/crashhandler.cpp
index 194d04b..0c2fec7 100644
--- a/src/crashhandler.cpp
+++ b/src/crashhandler.cpp
@@ -8,31 +8,49 @@
#include "crashhandler.h"
#include "version.h"
-
-#ifdef BREAKPAD
-
-//#ifdef Q_OS_LINUX
+#include <QByteArray>
+#include <client/linux/handler/exception_handler.h>
#include <unistd.h>
-//#endif // Q_OS_LINUX
-
-bool CrashHandler::dumpCallback(const google_breakpad::MinidumpDescriptor &descriptor, void *context, bool succeeded)
+// bool filter_callback (void*)
+// --> true: continue processing and write a minidump
+static bool minidumpCb(const google_breakpad::MinidumpDescriptor &descriptor, void *context, bool succeeded)
{
printf("Dump path: %s\n", descriptor.path());
- auto *ctx = static_cast<BreakpadContext *>(context);
+ auto *ctx = static_cast<CrashHandler::Context *>(context);
if(ctx != nullptr) {
- if(ctx->handler != nullptr) {
+ if(!ctx->handler.empty()) {
// fork and run 'handler master:commit path.dmp'
pid_t pid = fork();
if(pid == 0) {
- char buffer[256];
- snprintf(buffer, 256, "%s %s %s", ctx->handler, poi_Version, descriptor.path());
- execlp("/bin/sh", "/bin/sh", "-c", buffer, (char *)nullptr);
+ // pathname program argument ... nullptr
+ execlp(ctx->handler.c_str(),
+ ctx->handler.c_str(), "--crashd", ctx->dumppath.c_str(), "-c", descriptor.path(), poi_Version,
+ (char *)nullptr);
}
}
}
return succeeded;
}
-#endif
+
+bool CrashHandler::install_handler(CrashHandler::Context &ctx)
+{
+ if(ctx.dumppath.empty())
+ return false;
+
+ // Disable Chromium's crash handler so breakpad can capture crashes instead.
+ // This has to be done before QtWebEngine gets initialized.
+ const auto chromiumFlags = qgetenv("QTWEBENGINE_CHROMIUM_FLAGS");
+ if(!chromiumFlags.contains("disable-in-process-stack-traces")) {
+ qputenv("QTWEBENGINE_CHROMIUM_FLAGS", chromiumFlags + " --disable-in-process-stack-traces");
+ }
+
+ google_breakpad::MinidumpDescriptor descriptor(ctx.dumppath.c_str());
+
+ // minidump descriptor, filter callback, minidump callback, callback_context, install handler, server_fd
+ auto *eh = new google_breakpad::ExceptionHandler(descriptor, nullptr, minidumpCb, &ctx, true, -1);
+
+ return true;
+}
diff --git a/src/crashhandler.h b/src/crashhandler.h
index e7f7fa1..9b79ecc 100644
--- a/src/crashhandler.h
+++ b/src/crashhandler.h
@@ -9,26 +9,28 @@
#ifndef SMOLBOTE_CRASHHANDLER_H
#define SMOLBOTE_CRASHHANDLER_H
-#ifdef BREAKPAD
-//#ifdef Q_OS_LINUX
-#include <client/linux/handler/exception_handler.h>
-#endif
+#include <string>
-class CrashHandler
+namespace CrashHandler
{
-
-public:
- struct BreakpadContext {
- char *handler = nullptr;
- };
-
- // bool filter_callback (void*)
- // --> true: continue processing and write a minidump
-
-#ifdef BREAKPAD
- static bool dumpCallback(const google_breakpad::MinidumpDescriptor &descriptor, void *context, bool succeeded);
+struct Context {
+ const std::string dumppath;
+ const std::string handler;
+
+ explicit Context(const std::string &path, const std::string &crashhandler)
+ : dumppath(path)
+ , handler(crashhandler)
+ {
+ }
+};
+
+bool install_handler(Context &ctx)
+#ifndef HAVE_BREAKPAD
+{
+ return false;
+}
#endif
-
-}; // CrashHandler
+;
+};
#endif // SMOLBOTE_CRASHHANDLER_H
diff --git a/src/main.cpp b/src/main.cpp
index f4f2b78..f6a5b17 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -148,26 +148,20 @@ int main(int argc, char **argv)
// set this, otherwise the webview becomes black when using a stylesheet
app.setAttribute(Qt::AA_DontCreateNativeWidgetSiblings, true);
-#ifdef CONFIG_USEBREAKPAD
- const std::string crashpath = config->value<std::string>("browser.crash.path").value_or("/tmp");
- assert(!crashpath.empty());
-
- CrashHandler::BreakpadContext ctx;
- google_breakpad::MinidumpDescriptor descriptor(crashpath.c_str());
-
- const auto crashHandler = config->value<std::string>("browser.crash.handler");
- if(crashHandler) {
- const int length = crashHandler.value().length() + 1;
- ctx.handler = new char[length];
- crashHandler.value().copy(ctx.handler, length - 1);
- ctx.handler[length - 1] = '\0';
- }
-
- // minidump descriptor, filter callback, minidump callback, callback_context, install handler, server_fd
- google_breakpad::ExceptionHandler eh(descriptor, nullptr, CrashHandler::dumpCallback, &ctx, true, -1);
+ {
+ Configuration conf;
+ if(conf.value<bool>("usebreakpad").value()) {
+ CrashHandler::Context ctx(
+ conf.value<std::string>("path.crashdump").value(),
+ conf.value<std::string>("path.crashhandler").value());
- spdlog::debug("Installed breakpad exception handler (path {})", crashpath);
-#endif // CONFIG_USEBREAKPAD
+ if(CrashHandler::install_handler(ctx)) {
+ spdlog::info("Installed breakpad crash handler: {}", ctx.dumppath);
+ } else {
+ spdlog::warn("Failed to install breakpad crash handler: {}", ctx.dumppath);
+ }
+ }
+ }
const auto profile = []() {
Configuration c;
diff --git a/src/meson.build b/src/meson.build
index 25f94f0..956c41b 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -20,7 +20,7 @@ poi_sourceset.add(mod_qt5.preprocess(
))
poi_sourceset.add(files(
- 'main.cpp', 'builtins.cpp', 'crashhandler.cpp',
+ 'main.cpp', 'builtins.cpp',
'browser.cpp',
'util.cpp', 'util.h',
@@ -53,3 +53,5 @@ poi_sourceset.add(files(
interfaces_moc, version_h, poi_settings_h
)
+poi_sourceset.add(when: [dep_breakpad, dep_threads], if_true: files('crashhandler.cpp'))
+
diff --git a/tools/src/crashhandler/main.go b/tools/src/crashhandler/main.go
index 00ce0cd..7b1717f 100644
--- a/tools/src/crashhandler/main.go
+++ b/tools/src/crashhandler/main.go
@@ -67,7 +67,7 @@ func main() {
return
}
- fmt.Printf("[%s]\n", dumpPath)
+ fmt.Printf(" [%s]\n", dumpPath)
c, err := dumps(dumpPath)
if err != nil {
panic(err)
@@ -75,5 +75,7 @@ func main() {
for _, d := range c {
fmt.Printf("\t- %s\n", d.Name)
}
+ fmt.Println(" To analyze a crashdump, use the minidump_stackwalk tool:")
+ fmt.Println("minidump_stackwalk <minidump-file> [symbol-path]")
}