This commit is contained in:
Igor Sirotin 2024-11-04 12:30:57 +00:00
parent cc9b2d99ff
commit 92e94a0f7a
No known key found for this signature in database
GPG Key ID: 425E227CAAB81F95
5 changed files with 155 additions and 8 deletions

View File

@ -186,7 +186,7 @@ ifneq ($(detected_OS),Windows)
endif endif
# some manually installed Qt5 instances have wrong paths in their *.pc files, so we pass the right one to the linker here # some manually installed Qt5 instances have wrong paths in their *.pc files, so we pass the right one to the linker here
ifeq ($(detected_OS),Darwin) ifeq ($(detected_OS),Darwin)
NIM_PARAMS += -L:"-framework Foundation -framework AppKit -framework Security -framework IOKit -framework CoreServices -framework LocalAuthentication" NIM_PARAMS += -L:"-framework Foundation -framework AppKit -framework Security -framework IOKit -framework CoreServices -framework LocalAuthentication -lbsm"
# Fix for failures due to 'can't allocate code signature data for' # Fix for failures due to 'can't allocate code signature data for'
NIM_PARAMS += --passL:"-headerpad_max_install_names" NIM_PARAMS += --passL:"-headerpad_max_install_names"
NIM_PARAMS += --passL:"-F$(QT5_LIBDIR)" NIM_PARAMS += --passL:"-F$(QT5_LIBDIR)"
@ -405,6 +405,7 @@ $(DOTHERSIDE_CMAKE_CACHE): | deps
-DCMAKE_BUILD_TYPE=$(COMMON_CMAKE_BUILD_TYPE) \ -DCMAKE_BUILD_TYPE=$(COMMON_CMAKE_BUILD_TYPE) \
-DENABLE_DOCS=OFF \ -DENABLE_DOCS=OFF \
-DENABLE_TESTS=OFF \ -DENABLE_TESTS=OFF \
-DSENTRY_INTEGRATION_QT=YES \
$(COMMON_CMAKE_CONFIG_PARAMS) \ $(COMMON_CMAKE_CONFIG_PARAMS) \
$(DOTHERSIDE_CMAKE_CONFIG_PARAMS) \ $(DOTHERSIDE_CMAKE_CONFIG_PARAMS) \
-B $(DOTHERSIDE_BUILD_PATH) \ -B $(DOTHERSIDE_BUILD_PATH) \
@ -556,8 +557,35 @@ else
NIM_STATUS_CLIENT := bin/nim_status_client NIM_STATUS_CLIENT := bin/nim_status_client
endif endif
export SENTRY_LIB := vendor/DOtherSide/build/lib/sentry-native/libsentry.$(LIBSTATUS_EXT)
export SENTRY_LIBDIR := "$(shell pwd)/$(shell dirname "$(SENTRY_LIB)")"
export CRASHPAD_CLIENT_LIB := vendor/DOtherSide/build/lib/sentry-native/crashpad_build/client/libcrashpad_client.$(LIBSTATUS_EXT)
export CRASHPAD_CLIENT_LIBDIR := "$(shell pwd)/$(shell dirname "$(CRASHPAD_CLIENT_LIB)")"
export CRASHPAD_HANDLER_LIB := vendor/DOtherSide/build/lib/sentry-native/crashpad_build/handler/libcrashpad_handler_lib.$(LIBSTATUS_EXT)
export CRASHPAD_HANDLER_LIBDIR := "$(shell pwd)/$(shell dirname "$(CRASHPAD_HANDLER_LIB)")"
export CRASHPAD_MINIDUMP_LIB := vendor/DOtherSide/build/lib/sentry-native/crashpad_build/minidump/libcrashpad_minidump.$(LIBSTATUS_EXT)
export CRASHPAD_MINIDUMP_LIBDIR := "$(shell pwd)/$(shell dirname "$(CRASHPAD_MINIDUMP_LIB)")"
export CRASHPAD_SNAPSHOT_LIB := vendor/DOtherSide/build/lib/sentry-native/crashpad_build/snapshot/libcrashpad_snapshot.$(LIBSTATUS_EXT)
export CRASHPAD_SNAPSHOT_LIBDIR := "$(shell pwd)/$(shell dirname "$(CRASHPAD_SNAPSHOT_LIB)")"
export CRASHPAD_TOOLS_LIB := vendor/DOtherSide/build/lib/sentry-native/crashpad_build/tools/libcrashpad_tools.$(LIBSTATUS_EXT)
export CRASHPAD_TOOLS_LIBDIR := "$(shell pwd)/$(shell dirname "$(CRASHPAD_TOOLS_LIB)")"
export CRASHPAD_UTIL_LIB := vendor/DOtherSide/build/lib/sentry-native/crashpad_build/util/libcrashpad_util.$(LIBSTATUS_EXT)
export CRASHPAD_UTIL_LIBDIR := "$(shell pwd)/$(shell dirname "$(CRASHPAD_UTIL_LIB)")"
export CRASHPAD_MINICHROMIUM_LIB := vendor/DOtherSide/build/lib/sentry-native/crashpad_build/third_party/mini_chromium/libmini_chromium.$(LIBSTATUS_EXT)
export CRASHPAD_MINICHROMIUM_LIBDIR := "$(shell pwd)/$(shell dirname "$(CRASHPAD_MINICHROMIUM_LIB)")"
bin/crashpad_handler:
cp vendor/DOtherSide/build/lib/sentry-native/crashpad_build/handler/crashpad_handler bin/
$(NIM_STATUS_CLIENT): NIM_PARAMS += $(RESOURCES_LAYOUT) $(NIM_STATUS_CLIENT): NIM_PARAMS += $(RESOURCES_LAYOUT)
$(NIM_STATUS_CLIENT): $(NIM_SOURCES) | statusq dotherside check-qt-dir $(STATUSGO) $(STATUSKEYCARDGO) $(QRCODEGEN) $(FLEETS) rcc compile-translations deps $(NIM_STATUS_CLIENT): $(NIM_SOURCES) | statusq dotherside check-qt-dir $(STATUSGO) $(STATUSKEYCARDGO) $(QRCODEGEN) $(FLEETS) rcc compile-translations deps bin/crashpad_handler
echo -e $(BUILD_MSG) "$@" echo -e $(BUILD_MSG) "$@"
$(ENV_SCRIPT) nim c $(NIM_PARAMS) \ $(ENV_SCRIPT) nim c $(NIM_PARAMS) \
--passL:"-L$(STATUSGO_LIBDIR)" \ --passL:"-L$(STATUSGO_LIBDIR)" \
@ -566,8 +594,25 @@ $(NIM_STATUS_CLIENT): $(NIM_SOURCES) | statusq dotherside check-qt-dir $(STATUSG
--passL:"-lStatusQ" \ --passL:"-lStatusQ" \
--passL:"-L$(STATUSKEYCARDGO_LIBDIR)" \ --passL:"-L$(STATUSKEYCARDGO_LIBDIR)" \
--passL:"-lkeycard" \ --passL:"-lkeycard" \
--passL:"-L$(SENTRY_LIBDIR)" \
--passL:"-lsentry" \
--passL:"-L$(CRASHPAD_CLIENT_LIBDIR)" \
--passL:"-lcrashpad_client" \
--passL:"-L$(CRASHPAD_HANDLER_LIBDIR)" \
--passL:"-lcrashpad_handler_lib" \
--passL:"-L$(CRASHPAD_MINIDUMP_LIBDIR)" \
--passL:"-lcrashpad_minidump" \
--passL:"-L$(CRASHPAD_SNAPSHOT_LIBDIR)" \
--passL:"-lcrashpad_snapshot" \
--passL:"-L$(CRASHPAD_TOOLS_LIBDIR)" \
--passL:"-lcrashpad_tools" \
--passL:"-L$(CRASHPAD_UTIL_LIBDIR)" \
--passL:"-lcrashpad_util" \
--passL:"-L$(CRASHPAD_MINICHROMIUM_LIBDIR)" \
--passL:"-lmini_chromium" \
--passL:"$(QRCODEGEN)" \ --passL:"$(QRCODEGEN)" \
--passL:"-lm" \ --passL:"-lm" \
--passL:"-lcurl" \
$(NIM_EXTRA_PARAMS) src/nim_status_client.nim $(NIM_EXTRA_PARAMS) src/nim_status_client.nim
ifeq ($(detected_OS),Darwin) ifeq ($(detected_OS),Darwin)
install_name_tool -change \ install_name_tool -change \
@ -686,6 +731,7 @@ $(STATUS_CLIENT_DMG): nim_status_client $(DMG_TOOL)
mkdir -p $(MACOS_OUTER_BUNDLE)/Contents/Resources mkdir -p $(MACOS_OUTER_BUNDLE)/Contents/Resources
cp Info.plist $(MACOS_OUTER_BUNDLE)/Contents/ cp Info.plist $(MACOS_OUTER_BUNDLE)/Contents/
cp bin/nim_status_client $(MACOS_OUTER_BUNDLE)/Contents/MacOS/ cp bin/nim_status_client $(MACOS_OUTER_BUNDLE)/Contents/MacOS/
cp bin/crashpad_handler $(MACOS_OUTER_BUNDLE)/Contents/MacOS/
cp status.icns $(MACOS_OUTER_BUNDLE)/Contents/Resources/ cp status.icns $(MACOS_OUTER_BUNDLE)/Contents/Resources/
cp status-macos.svg $(MACOS_OUTER_BUNDLE)/Contents/ cp status-macos.svg $(MACOS_OUTER_BUNDLE)/Contents/
cp -R resources.rcc $(MACOS_OUTER_BUNDLE)/Contents/ cp -R resources.rcc $(MACOS_OUTER_BUNDLE)/Contents/

View File

@ -79,7 +79,24 @@ proc initKeystore*(keystoreDir: string): RpcResponse[JsonNode] =
error "error", methodName = "initKeystore", exception=e.msg error "error", methodName = "initKeystore", exception=e.msg
raise newException(RpcException, e.msg) raise newException(RpcException, e.msg)
type
Node = ref object
value: int
proc backupData*(): RpcResponse[JsonNode] = proc backupData*(): RpcResponse[JsonNode] =
echo "<<< ABOUT TO CRASH"
# FIXME: Force a crash to test the crash reporting
var n: Node = nil
echo n.value
let p = cast[ptr int](0x1) # Point to an invalid address
echo p[] # Attempt to access it
# var arr = cast[ptr array[1, int]](nil) # Array pointer with no valid memory
# echo arr[1] # Out-of-bounds access
let payload = %* [] let payload = %* []
result = callPrivateRPC("backupData".prefix, payload) result = callPrivateRPC("backupData".prefix, payload)

View File

@ -35,7 +35,6 @@ endif()
add_subdirectory(../../vendor/SortFilterProxyModel SortFilterProxyModel) add_subdirectory(../../vendor/SortFilterProxyModel SortFilterProxyModel)
add_subdirectory(../../vendor/qzxing/src qzxing) add_subdirectory(../../vendor/qzxing/src qzxing)
add_subdirectory(../../vendor/sentry-native sentry-native)
target_compile_options(qzxing PRIVATE -w) target_compile_options(qzxing PRIVATE -w)
target_compile_options(SortFilterProxyModel PRIVATE -w) target_compile_options(SortFilterProxyModel PRIVATE -w)
@ -187,7 +186,6 @@ target_link_libraries(StatusQ PRIVATE
Qt5::QuickControls2 Qt5::QuickControls2
SortFilterProxyModel SortFilterProxyModel
qzxing qzxing
sentry::sentry
) )
if (CMAKE_BUILD_TYPE STREQUAL "Debug") if (CMAKE_BUILD_TYPE STREQUAL "Debug")

View File

@ -9,6 +9,8 @@ if(MONITORING)
include(../../../ui/MonitoringSources.cmake) include(../../../ui/MonitoringSources.cmake)
endif() endif()
add_subdirectory(../../sentry-native sentry-native)
# Macro for merging common code between static and shared # Macro for merging common code between static and shared
macro(add_target name type) macro(add_target name type)
find_package(Qt5 COMPONENTS Core Qml Gui Quick QuickControls2 Widgets Network Multimedia WebView REQUIRED) find_package(Qt5 COMPONENTS Core Qml Gui Quick QuickControls2 Widgets Network Multimedia WebView REQUIRED)
@ -68,6 +70,8 @@ macro(add_target name type)
target_link_libraries(${name} PRIVATE Qt5::QuickControls2) target_link_libraries(${name} PRIVATE Qt5::QuickControls2)
set(PC_REQUIRES "${PC_REQUIRES}, Qt5QuickControls2") set(PC_REQUIRES "${PC_REQUIRES}, Qt5QuickControls2")
endif() endif()
target_link_libraries(${name} PUBLIC sentry::sentry)
endmacro() endmacro()
set(major 0) set(major 0)

View File

@ -81,6 +81,8 @@
#include "StatusDesktop/Monitoring/Monitor.h" #include "StatusDesktop/Monitoring/Monitor.h"
#endif #endif
#include <sentry.h>
namespace { namespace {
void register_meta_types() void register_meta_types()
@ -189,6 +191,24 @@ void dos_qguiapplication_try_enable_threaded_renderer()
static MessageHandlerCallback messageHandlerCallback = nullptr; static MessageHandlerCallback messageHandlerCallback = nullptr;
sentry_level_t qtLevelToSentry(int type)
{
switch (type) {
case QtDebugMsg:
return SENTRY_LEVEL_DEBUG;
case QtInfoMsg:
return SENTRY_LEVEL_INFO;
case QtWarningMsg:
return SENTRY_LEVEL_WARNING;
case QtCriticalMsg:
return SENTRY_LEVEL_ERROR;
case QtFatalMsg:
return SENTRY_LEVEL_FATAL;
default:
return SENTRY_LEVEL_INFO;
}
}
// This catches the QT and QML logs and outputs them. // This catches the QT and QML logs and outputs them.
// This is necessary on Windows, because otherwise we do not get any logs at all // This is necessary on Windows, because otherwise we do not get any logs at all
void myMessageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg) void myMessageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg)
@ -205,6 +225,16 @@ void myMessageOutput(QtMsgType type, const QMessageLogContext &context, const QS
int messageType = int(type); int messageType = int(type);
messageHandlerCallback(messageType, message, category, file, function, context.line); messageHandlerCallback(messageType, message, category, file, function, context.line);
// if (type == QtDebugMsg || type == QtInfoMsg) {
// return;
// }
// sentry_capture_event(sentry_value_new_message_event(
// /* level */ convertToSentryLevel(type),
// /* logger */ "",
// /* message */ message
// ));
} }
void dos_installMessageHandler(MessageHandlerCallback messageHandler) void dos_installMessageHandler(MessageHandlerCallback messageHandler)
@ -213,19 +243,39 @@ void dos_installMessageHandler(MessageHandlerCallback messageHandler)
qInstallMessageHandler(myMessageOutput); qInstallMessageHandler(myMessageOutput);
} }
static sentry_value_t on_crash_callback(
const sentry_ucontext_t *uctx, // provides the user-space context of the crash
sentry_value_t event, // used the same way as in `before_send`
void *closure // user-data that you can provide at configuration time
)
{
// Do contextual clean-up before the crash is sent to sentry's backend infrastructure
qInfo() << "on_crash_callback";
/* ... */
// tell the backend to retain the event (+ dump)
// or to discard it, you could free the event and return a `null`:
// sentry_value_decref(event);
// return sentry_value_new_null();
return event;
}
void dos_qguiapplication_create() void dos_qguiapplication_create()
{ {
qInfo() << "dos_qguiapplication_create";
sentry_options_t *options = sentry_options_new(); sentry_options_t *options = sentry_options_new();
// sentry_options_set_dsn(options, "https://fecdd38f76baa59481dd8b643bd54022@sentry.infra.status.im/8");
// This is also the default-path. For further information and recommendations: // This is also the default-path. For further information and recommendations:
// https://docs.sentry.io/platforms/native/configuration/options/#database-path // https://docs.sentry.io/platforms/native/configuration/options/#database-path
sentry_options_set_database_path(options, ".sentry-native"); sentry_options_set_database_path(options, ".sentry-native");
sentry_options_set_release(options, "status-desktop@x.y.z"); sentry_options_set_release(options, "status-desktop@test-1");
sentry_options_set_debug(options, 1); sentry_options_set_debug(options, 1);
sentry_options_set_on_crash(options, on_crash_callback, NULL);
sentry_init(options); sentry_init(options);
// Make sure everything flushes qInfo() << "sentry initialized" << sentry_options_get_dsn(options);
auto sentryClose = qScopeGuard([] { sentry_close(); });
// The parameters argc and argv and the strings pointed to by the argv array shall be modifiable by the program, // The parameters argc and argv and the strings pointed to by the argv array shall be modifiable by the program,
// and retain their last-stored values between program startup and program termination. // and retain their last-stored values between program startup and program termination.
@ -362,6 +412,9 @@ void dos_qguiapplication_download_imageByUrl(const char *url, const char *filePa
void dos_qguiapplication_delete() void dos_qguiapplication_delete()
{ {
delete qGuiApp; delete qGuiApp;
// Make sure everything flushes
sentry_close();
} }
void dos_qguiapplication_exec() void dos_qguiapplication_exec()
@ -1887,3 +1940,32 @@ void dos_app_make_it_active(::DosQQmlApplicationEngine* vptr)
} }
} }
} }
// sentry_level_t chroniclesLevelToSentry(const char* type)
// {
// switch (type) {
// case "DEBUG":
// return SENTRY_LEVEL_DEBUG;
// case "INFO":
// return SENTRY_LEVEL_INFO;
// case "WARN":
// return SENTRY_LEVEL_WARNING;
// case "ERROR":
// return SENTRY_LEVEL_ERROR;
// default:
// return SENTRY_LEVEL_INFO;
// }
// }
// void report_sentry_event(const char* type, const char* message) {
// const int sentryLevel = convertToSentryLevel(type);
// if (sentryLevel == SENTRY_LEVEL_DEBUG || type == SENTRY_LEVEL_INFO) {
// return;
// }
// sentry_capture_event(sentry_value_new_message_event(
// /* level */ sentryLevel,
// /* logger */ "",
// /* message */ message
// ));
// }