diff --git a/laf b/laf index 3bcdef56b..f006db9ed 160000 --- a/laf +++ b/laf @@ -1 +1 @@ -Subproject commit 3bcdef56b27bec14aac39589e5fb78cf4e36184a +Subproject commit f006db9ed73e3f38610ae7b2fb4cd487e02a5038 diff --git a/src/app/sentry_wrapper.cpp b/src/app/sentry_wrapper.cpp index c9fb9d4c6..b70e07c46 100644 --- a/src/app/sentry_wrapper.cpp +++ b/src/app/sentry_wrapper.cpp @@ -12,6 +12,7 @@ #include "app/resource_finder.h" #include "base/fs.h" +#include "base/log.h" #include "base/string.h" #include "ver/info.h" @@ -110,6 +111,33 @@ bool Sentry::areThereCrashesToReport() return false; } +// static +void Sentry::addBreadcrumb(const std::string& message) +{ + LOG(VERBOSE, "BC: %s\n", message.c_str()); + + sentry_value_t c = sentry_value_new_breadcrumb(nullptr, message.c_str()); + sentry_add_breadcrumb(c); +} + +// static +void Sentry::addBreadcrumb(const std::string& message, + const std::map& data) +{ + LOG(VERBOSE, "BC: %s\n", message.c_str()); + + sentry_value_t c = sentry_value_new_breadcrumb(nullptr, message.c_str()); + sentry_value_t d = sentry_value_new_object(); + for (const auto& kv : data) { + LOG(VERBOSE, " - [%s]=%s\n", kv.first.c_str(), kv.second.c_str()); + sentry_value_set_by_key(d, + kv.first.c_str(), + sentry_value_new_string(kv.second.c_str())); + } + sentry_value_set_by_key(c, "data", d); + sentry_add_breadcrumb(c); +} + void Sentry::setupDirs(sentry_options_t* options) { // The expected handler executable name is aseprite_crashpad_handler (.exe) diff --git a/src/app/sentry_wrapper.h b/src/app/sentry_wrapper.h index c833f9f9d..e9ac6da78 100644 --- a/src/app/sentry_wrapper.h +++ b/src/app/sentry_wrapper.h @@ -1,5 +1,5 @@ // Aseprite -// Copyright (C) 2021 Igara Studio S.A. +// Copyright (C) 2021-2022 Igara Studio S.A. // // This program is distributed under the terms of // the End-User License Agreement for Aseprite. @@ -13,6 +13,7 @@ #include "sentry.h" +#include #include namespace app { @@ -33,6 +34,10 @@ public: // the "give consent" check box for first time. static bool areThereCrashesToReport(); + static void addBreadcrumb(const std::string& message); + static void addBreadcrumb(const std::string& message, + const std::map& data); + private: void setupDirs(sentry_options_t* options); diff --git a/src/main/main.cpp b/src/main/main.cpp index aed36ec02..db2b38c41 100644 --- a/src/main/main.cpp +++ b/src/main/main.cpp @@ -24,6 +24,10 @@ #if ENABLE_SENTRY #include "app/sentry_wrapper.h" + #if LAF_WINDOWS + #define USE_SENTRY_BREADCRUMB_FOR_WINTAB 1 + #include "os/win/wintab.h" + #endif #else #include "base/memory_dump.h" #endif @@ -64,7 +68,31 @@ namespace { CoUninitialize(); } }; -#endif +#endif // LAF_WINDOWS + +#if USE_SENTRY_BREADCRUMB_FOR_WINTAB + // Delegate to write Wintab information as a Sentry breadcrumb (to + // know if there is a specific Wintab driver giving problems) + class WintabApiDelegate : public os::WintabAPI::Delegate { + bool m_done = false; + public: + WintabApiDelegate() { + os::instance()->setWintabDelegate(this); + } + ~WintabApiDelegate() { + os::instance()->setWintabDelegate(nullptr); + } + void onWintabID(const std::string& id) override { + if (!m_done) { + m_done = true; + app::Sentry::addBreadcrumb("Wintab ID=" + id); + } + } + void onWintabFields(const std::map& fields) override { + app::Sentry::addBreadcrumb("Wintab DLL", fields); + } + }; +#endif // USE_SENTRY_BREADCRUMB_FOR_WINTAB } @@ -99,6 +127,9 @@ int app_main(int argc, char* argv[]) #if ENABLE_SENTRY sentry.init(); + #if USE_SENTRY_BREADCRUMB_FOR_WINTAB + WintabApiDelegate wintabDelegate; + #endif #else // Change the memory dump filename to save on disk (.dmp // file). Note: Only useful on Windows.