first pass of merging in warp (doesn't build)
This commit is contained in:
@@ -16,11 +16,7 @@ pub fn get_virtualized_environment() -> Option<VirtualEnvironment> {
|
||||
}
|
||||
};
|
||||
|
||||
// Test specifically for WSL based on existence of a particular file under
|
||||
// /proc.
|
||||
//
|
||||
// See: https://superuser.com/questions/1749781/how-can-i-check-if-the-environment-is-wsl-from-a-shell-script
|
||||
if std::path::Path::new("/proc/sys/fs/binfmt_misc/WSLInterop").exists() {
|
||||
if command::wsl::is_wsl() {
|
||||
return Some(VirtualEnvironment {
|
||||
name: "wsl".to_owned(),
|
||||
});
|
||||
|
||||
@@ -1,22 +1,27 @@
|
||||
#![allow(deprecated)]
|
||||
|
||||
use cocoa::{
|
||||
base::{id, nil, BOOL},
|
||||
foundation::NSAutoreleasePool,
|
||||
};
|
||||
use galaxyui::platform::mac::make_nsstring;
|
||||
use objc2::rc::autoreleasepool;
|
||||
use objc2_foundation::NSString;
|
||||
|
||||
use super::*;
|
||||
|
||||
// Functions implemented in objC files.
|
||||
extern "C" {
|
||||
fn startSentry(sentryUrl: id, environment: id, version: id, isDogfood: BOOL);
|
||||
fn startSentry(
|
||||
sentryUrl: &NSString,
|
||||
environment: &NSString,
|
||||
version: &NSString,
|
||||
isDogfood: bool,
|
||||
);
|
||||
fn stopSentry();
|
||||
#[allow(dead_code)] // Only gets called when built in debug mode.
|
||||
fn crashSentry();
|
||||
fn setUser(userId: id);
|
||||
fn recordBreadcrumb(message: id, category: id, level: id, seconds_since_epoch: f64);
|
||||
fn setTag(key: id, value: id);
|
||||
fn setUser(userId: &NSString);
|
||||
fn recordBreadcrumb(
|
||||
message: &NSString,
|
||||
category: &NSString,
|
||||
level: &NSString,
|
||||
seconds_since_epoch: f64,
|
||||
);
|
||||
fn setTag(key: &NSString, value: &NSString);
|
||||
}
|
||||
|
||||
pub fn init_cocoa_sentry() {
|
||||
@@ -24,20 +29,23 @@ pub fn init_cocoa_sentry() {
|
||||
let environment = super::get_environment();
|
||||
|
||||
log::info!("Initializing Sentry for cocoa app with endpoint {endpoint}");
|
||||
unsafe {
|
||||
let pool = NSAutoreleasePool::new(nil);
|
||||
let dsn = make_nsstring(endpoint);
|
||||
// This runs during early init from `init_sentry`, before the AppKit event
|
||||
// loop drains its ambient pool, so open a local pool to bound the bridge
|
||||
// NSStrings.
|
||||
autoreleasepool(|_| {
|
||||
let dsn = NSString::from_str(endpoint.as_ref());
|
||||
let environment_name: &str = environment.as_ref();
|
||||
let environment = make_nsstring(environment_name);
|
||||
let release = make_nsstring(release_version());
|
||||
startSentry(
|
||||
dsn,
|
||||
environment,
|
||||
release,
|
||||
ChannelState::channel().is_dogfood() as BOOL,
|
||||
);
|
||||
pool.drain();
|
||||
}
|
||||
let environment = NSString::from_str(environment_name);
|
||||
let release = NSString::from_str(release_version());
|
||||
unsafe {
|
||||
startSentry(
|
||||
&dsn,
|
||||
&environment,
|
||||
&release,
|
||||
ChannelState::channel().is_dogfood(),
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
pub fn uninit_cocoa_sentry() {
|
||||
@@ -53,12 +61,15 @@ pub fn crash() {
|
||||
}
|
||||
|
||||
pub fn set_user_id(user_id: &str) {
|
||||
unsafe {
|
||||
let pool = NSAutoreleasePool::new(nil);
|
||||
let user_id = make_nsstring(user_id);
|
||||
setUser(user_id);
|
||||
pool.drain();
|
||||
}
|
||||
// Invoked from `set_optional_user_information` on auth state changes and
|
||||
// init, whose thread of origin varies, so open a local pool to bound the
|
||||
// bridge NSString.
|
||||
autoreleasepool(|_| {
|
||||
let user_id = NSString::from_str(user_id);
|
||||
unsafe {
|
||||
setUser(&user_id);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
pub fn forward_breadcrumb(rust_breadcrumb: &sentry::Breadcrumb) {
|
||||
@@ -69,22 +80,28 @@ pub fn forward_breadcrumb(rust_breadcrumb: &sentry::Breadcrumb) {
|
||||
.timestamp
|
||||
.duration_since(std::time::SystemTime::UNIX_EPOCH)
|
||||
.map_or(0., |n| n.as_secs_f64());
|
||||
unsafe {
|
||||
let pool = NSAutoreleasePool::new(nil);
|
||||
recordBreadcrumb(
|
||||
make_nsstring(message),
|
||||
make_nsstring(category),
|
||||
make_nsstring(level.as_str()),
|
||||
unix_timestamp,
|
||||
);
|
||||
pool.drain();
|
||||
}
|
||||
// Runs on whichever Rust thread emitted the breadcrumb (Sentry's
|
||||
// `before_breadcrumb`), which has no ambient pool, so bound the bridge
|
||||
// NSStrings in a local pool.
|
||||
autoreleasepool(|_| {
|
||||
let message = NSString::from_str(message);
|
||||
let category = NSString::from_str(category);
|
||||
let level = NSString::from_str(level.as_str());
|
||||
unsafe {
|
||||
recordBreadcrumb(&message, &category, &level, unix_timestamp);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
pub fn set_tag(key: &str, value: &str) {
|
||||
unsafe {
|
||||
let pool = NSAutoreleasePool::new(nil);
|
||||
setTag(make_nsstring(key), make_nsstring(value));
|
||||
pool.drain();
|
||||
}
|
||||
// Called from `init_cocoa_sentry`'s tag loop and the `set_tag` wrapper in
|
||||
// `mod.rs` on Rust threads, so open a local pool to bound the bridge
|
||||
// NSStrings.
|
||||
autoreleasepool(|_| {
|
||||
let key = NSString::from_str(key);
|
||||
let value = NSString::from_str(value);
|
||||
unsafe {
|
||||
setTag(&key, &value);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -7,29 +7,30 @@ mod sentry_minidump;
|
||||
mod linux;
|
||||
|
||||
use std::borrow::Cow;
|
||||
use std::collections::{BTreeMap, HashMap};
|
||||
use std::ops::DerefMut;
|
||||
use std::sync::Arc;
|
||||
|
||||
use galaxy_core::channel::Channel;
|
||||
use galaxyui::{r#async::block_on, AppContext, SingletonEntity};
|
||||
use lazy_static::lazy_static;
|
||||
use parking_lot::{Mutex, RwLock};
|
||||
use regex::Regex;
|
||||
use sentry::{ClientInitGuard, IntoDsn, SessionMode};
|
||||
#[cfg(linux_or_windows)]
|
||||
pub use sentry_minidump::run_server as run_minidump_server;
|
||||
use warp_server_auth::anonymous_id::get_or_create_anonymous_id;
|
||||
use galaxyui::r#async::block_on;
|
||||
use galaxyui::rendering::GPUDeviceInfo;
|
||||
use galaxyui::windowing::state::ApplicationStage;
|
||||
use galaxyui::windowing::{self, StateEvent, WindowManager};
|
||||
use galaxyui::{AppContext, SingletonEntity};
|
||||
|
||||
use crate::antivirus::{AntivirusInfo, AntivirusInfoEvent};
|
||||
use crate::auth::anonymous_id::get_or_create_anonymous_id;
|
||||
use crate::auth::{AuthStateProvider, UserUid};
|
||||
use crate::channel::ChannelState;
|
||||
use crate::features::FeatureFlag;
|
||||
use crate::settings::{PrivacySettings, PrivacySettingsChangedEvent};
|
||||
use galaxyui::rendering::GPUDeviceInfo;
|
||||
use galaxyui::windowing::state::ApplicationStage;
|
||||
use galaxyui::windowing::{self, StateEvent, WindowManager};
|
||||
use parking_lot::{Mutex, RwLock};
|
||||
use regex::Regex;
|
||||
use std::collections::{BTreeMap, HashMap};
|
||||
use std::sync::Arc;
|
||||
|
||||
#[cfg(linux_or_windows)]
|
||||
pub use sentry_minidump::run_server as run_minidump_server;
|
||||
|
||||
lazy_static! {
|
||||
/// The RAII guard returned by the call to initialize the Rust Sentry client must be kept in
|
||||
@@ -178,7 +179,7 @@ impl ToSentryTags for CrashRecoveryMetadata {
|
||||
}
|
||||
}
|
||||
|
||||
/// Initializes the crash reporting susbsystem. Returns whether or not crash
|
||||
/// Initializes the crash reporting subsystem. Returns whether or not crash
|
||||
/// reporting is active.
|
||||
pub(crate) fn init(ctx: &mut AppContext) -> bool {
|
||||
if !FeatureFlag::CrashReporting.is_enabled() {
|
||||
@@ -410,6 +411,14 @@ fn sentry_client_options() -> sentry::ClientOptions {
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns whether the Rust Sentry client is currently initialized.
|
||||
pub(crate) fn is_initialized() -> bool {
|
||||
matches!(
|
||||
&*RUST_SENTRY_CLIENT_GUARD.lock(),
|
||||
RustSentryClientGuard::Initialized { .. }
|
||||
)
|
||||
}
|
||||
|
||||
/// Uninitializes sentry, effectively ending reporting on crashes and errors.
|
||||
pub fn uninit_sentry() {
|
||||
// Take the client guard out of the mutex, replacing it with
|
||||
|
||||
@@ -8,18 +8,14 @@
|
||||
//! * Startup via our command-line parsing, rather than a separate hook
|
||||
//! * Use of anonymous, temporary crash dump files, to ensure they're cleaned up
|
||||
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
fs::File,
|
||||
io::{self, Read as _, Seek as _, Write},
|
||||
path::{Path, PathBuf},
|
||||
process,
|
||||
sync::{
|
||||
atomic::{AtomicBool, Ordering},
|
||||
Arc,
|
||||
},
|
||||
time::Duration,
|
||||
};
|
||||
use std::collections::HashMap;
|
||||
use std::fs::File;
|
||||
use std::io::{self, Read as _, Seek as _, Write};
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::process;
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
|
||||
use anyhow::Context as _;
|
||||
use command::blocking::Command;
|
||||
@@ -27,10 +23,8 @@ use crash_handler::{CrashContext, CrashHandler};
|
||||
use galaxy_core::report_error;
|
||||
use lazy_static::lazy_static;
|
||||
use parking_lot::Mutex;
|
||||
use sentry::{
|
||||
protocol::{Attachment, AttachmentType},
|
||||
Breadcrumb, Level,
|
||||
};
|
||||
use sentry::protocol::{Attachment, AttachmentType};
|
||||
use sentry::{Breadcrumb, Level};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use uuid::Uuid;
|
||||
|
||||
@@ -166,6 +160,15 @@ pub fn run_server(socket_path: &Path) -> anyhow::Result<()> {
|
||||
minidumper::LoopAction::Exit
|
||||
}
|
||||
|
||||
fn on_client_disconnected(&self, num_clients: usize) -> minidumper::LoopAction {
|
||||
if num_clients == 0 {
|
||||
log::info!("All clients disconnected, shutting down minidump server");
|
||||
minidumper::LoopAction::Exit
|
||||
} else {
|
||||
minidumper::LoopAction::Continue
|
||||
}
|
||||
}
|
||||
|
||||
fn on_message(&self, _kind: u32, buffer: Vec<u8>) {
|
||||
match bincode::deserialize::<MinidumpCommand>(&buffer) {
|
||||
Ok(MinidumpCommand::Shutdown) => {
|
||||
|
||||
Reference in New Issue
Block a user