update panic handler with system information
This commit is contained in:
parent
ad4cef9739
commit
bff7aff98c
4 changed files with 47 additions and 78 deletions
|
@ -46,7 +46,7 @@ fn process_panic(info: &std::panic::PanicHookInfo<'_>) -> Result<(), Box<dyn Err
|
|||
};
|
||||
|
||||
writeln!(file, "{}", payload_str)?;
|
||||
writeln!(file, "{}", render_backtrace().sanitize_path())?;
|
||||
writeln!(file, "{}", capture_backtrace().sanitize_path())?;
|
||||
|
||||
let panic_msg = format!(
|
||||
r#"Zenyx had a problem and crashed. To help us diagnose the problem you can send us a crash report.
|
||||
|
@ -54,8 +54,7 @@ fn process_panic(info: &std::panic::PanicHookInfo<'_>) -> Result<(), Box<dyn Err
|
|||
We have generated a report file at '{}'. Submit an issue or email with the subject of 'Zenyx Crash Report' and include the report as an attachment.
|
||||
|
||||
To submit the crash report:
|
||||
https://github.com/Zenyx-Engine/Zenyx/issues
|
||||
|
||||
https://codeberg.org/Caznix/Zenyx/issues
|
||||
We take privacy seriously, and do not perform any automated error collection. In order to improve the software, we rely on people to submit reports.
|
||||
|
||||
Thank you kindly!"#,
|
||||
|
@ -72,66 +71,28 @@ For future reference, the error summary is as follows:
|
|||
|
||||
println!("{}", final_msg.red().bold());
|
||||
|
||||
MessageDialog::new()
|
||||
if let Err(e) = MessageDialog::new()
|
||||
.set_type(MessageType::Error)
|
||||
.set_title("A fatal error in Zenyx has occurred")
|
||||
.set_text(&final_msg)
|
||||
.show_alert()
|
||||
.map_err(|e| {
|
||||
error!("Failed to show error dialog: {}", e);
|
||||
e.into()
|
||||
})
|
||||
}
|
||||
fn render_backtrace() -> String {
|
||||
const HEX_WIDTH: usize = mem::size_of::<usize>() * 2 + 2;
|
||||
const NEXT_SYMBOL_PADDING: usize = HEX_WIDTH + 6;
|
||||
|
||||
let mut backtrace = String::new();
|
||||
let bt = Backtrace::new();
|
||||
let symbols = bt
|
||||
.frames()
|
||||
.iter()
|
||||
.flat_map(|frame| {
|
||||
let symbols = frame.symbols();
|
||||
if symbols.is_empty() {
|
||||
vec![(frame, None, "<unresolved>".to_owned())]
|
||||
} else {
|
||||
symbols
|
||||
.iter()
|
||||
.map(|s| {
|
||||
(
|
||||
frame,
|
||||
Some(s),
|
||||
s.name()
|
||||
.map(|n| n.to_string())
|
||||
.unwrap_or_else(|| "<unknown>".to_owned()),
|
||||
)
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
}
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
let begin_unwind = "rust_begin_unwind";
|
||||
let begin_unwind_start = symbols
|
||||
.iter()
|
||||
.position(|(_, _, n)| n == begin_unwind)
|
||||
.unwrap_or(0);
|
||||
for (entry_idx, (frame, symbol, name)) in symbols.iter().skip(begin_unwind_start).enumerate() {
|
||||
let ip = frame.ip();
|
||||
let _ = writeln!(backtrace, "{entry_idx:4}: {ip:HEX_WIDTH$?} - {name}");
|
||||
if let Some(symbol) = symbol {
|
||||
if let (Some(file), Some(line)) = (symbol.filename(), symbol.lineno()) {
|
||||
let _ = writeln!(
|
||||
backtrace,
|
||||
"{:3$}at {}:{}",
|
||||
"",
|
||||
file.display(),
|
||||
line,
|
||||
NEXT_SYMBOL_PADDING
|
||||
);
|
||||
}
|
||||
.show_confirm() {
|
||||
error!("Failed to show message dialog: {e}")
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
fn capture_backtrace() -> String {
|
||||
let mut backtrace = String::new();
|
||||
let sysinfo = crate::metadata::SystemMetadata::current();
|
||||
backtrace.push_str(&sysinfo.verbose_summary());
|
||||
|
||||
let trace = backtrace::Backtrace::new();
|
||||
let message = format!("\nBacktrace:\n\n");
|
||||
backtrace.push_str(&message);
|
||||
backtrace.push_str(&format!("{trace:?}"));
|
||||
|
||||
|
||||
|
||||
backtrace
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,6 @@ use std::time::Instant;
|
|||
|
||||
use cgmath::{Deg, Matrix4, Point3, Rad, SquareMatrix, Vector3, perspective};
|
||||
use futures::executor::block_on;
|
||||
use thiserror::Error;
|
||||
use tracing::{debug, error, info, trace};
|
||||
use wgpu::TextureUsages;
|
||||
use wgpu::{Backends, InstanceDescriptor, util::DeviceExt};
|
||||
|
@ -370,13 +369,12 @@ impl<'window> Renderer<'window> {
|
|||
surface.configure(&device, &surface_config);
|
||||
let (depth_texture, depth_texture_view) =
|
||||
create_depth_texture(&device, surface_config.width, surface_config.height);
|
||||
let (depth_texture, depth_texture_view) =
|
||||
create_depth_texture(&device, surface_config.width, surface_config.height);
|
||||
|
||||
let font_bytes = include_bytes!("DejaVuSans.ttf");
|
||||
let font = FontRef::try_from_slice(font_bytes).map_err(|e| {
|
||||
ZenyxError::builder(ZenyxErrorKind::DeviceRequest)
|
||||
ZenyxError::builder(ZenyxErrorKind::FontLoading)
|
||||
.with_message("Font loading failed")
|
||||
.with_source(e)
|
||||
.build()
|
||||
})?;
|
||||
|
||||
|
|
|
@ -8,7 +8,6 @@ use std::sync::Arc;
|
|||
use ctx::{Renderer, Vertex};
|
||||
use image::ImageDecoder;
|
||||
use image::ImageFormat;
|
||||
use tobj::Mesh;
|
||||
use tobj::{LoadOptions, Model};
|
||||
use tracing::{debug, error, info, trace, warn};
|
||||
use wgpu::rwh::HasWindowHandle;
|
||||
|
@ -17,7 +16,6 @@ use winit::dpi::LogicalSize;
|
|||
use winit::dpi::Size;
|
||||
use winit::event::{KeyEvent, WindowEvent};
|
||||
use winit::event_loop::{ActiveEventLoop, ControlFlow, EventLoop};
|
||||
use winit::monitor::MonitorHandle;
|
||||
use winit::platform::windows::WindowAttributesExtWindows;
|
||||
use winit::window::Fullscreen;
|
||||
use winit::window::Icon;
|
||||
|
@ -94,15 +92,18 @@ f 6/11/6 5/10/6 1/1/6 2/13/6
|
|||
";
|
||||
|
||||
impl App<'_> {
|
||||
const ICON: &'static [u8] =
|
||||
include_bytes!(concat!(env!("CARGO_MANIFEST_DIR"), "/../assets/Badge.png"));
|
||||
|
||||
fn create_main_window(&mut self, event_loop: &ActiveEventLoop) {
|
||||
let icon = self.load_icon_from_bytes(Self::ICON).unwrap();
|
||||
|
||||
let win_attr = Window::default_attributes()
|
||||
.with_title("Zenyx")
|
||||
.with_min_inner_size(Size::Logical(LogicalSize::new(100.0, 100.0)))
|
||||
.with_window_icon(icon.clone())
|
||||
.with_taskbar_icon(icon);
|
||||
|
||||
.with_title("Zenyx")
|
||||
.with_min_inner_size(Size::Logical(LogicalSize::new(100.0, 100.0)))
|
||||
.with_window_icon(icon.clone())
|
||||
.with_taskbar_icon(icon);
|
||||
|
||||
match event_loop.create_window(win_attr) {
|
||||
Ok(window) => {
|
||||
let window = Arc::new(window);
|
||||
|
@ -236,14 +237,17 @@ impl App<'_> {
|
|||
warn!("No window found for fullscreen toggle: {:?}", window_id);
|
||||
}
|
||||
}
|
||||
|
||||
fn load_icon_from_bytes(&self, bytes: &[u8]) -> Result<Option<Icon>, String> {
|
||||
const IMAGE_DIR: &str = env!("CARGO_MANIFEST_DIR");
|
||||
let cursor = Cursor::new(bytes);
|
||||
let format = image::guess_format(bytes).map_err(|_| "Failed to guess image format")?;
|
||||
let decoder = match format {
|
||||
ImageFormat::Png => image::codecs::png::PngDecoder::new(cursor).map_err(|e| format!("Failed to decode PNG: {}", e))?,
|
||||
ImageFormat::Png => image::codecs::png::PngDecoder::new(cursor)
|
||||
.map_err(|e| format!("Failed to decode PNG: {}", e))?,
|
||||
_ => {
|
||||
let img = image::load_from_memory(bytes).map_err(|e| format!("Failed to load image: {}", e))?.into_rgba8();
|
||||
let img = image::load_from_memory(bytes)
|
||||
.map_err(|e| format!("Failed to load image: {}", e))?
|
||||
.into_rgba8();
|
||||
let (width, height) = img.dimensions();
|
||||
return Icon::from_rgba(img.into_raw(), width, height)
|
||||
.map(Some)
|
||||
|
@ -253,14 +257,15 @@ impl App<'_> {
|
|||
|
||||
let (width, height) = decoder.dimensions();
|
||||
let mut image_data = vec![0; decoder.total_bytes() as usize];
|
||||
decoder.read_image(&mut image_data).map_err(|e| format!("Failed to read image data: {}", e))?;
|
||||
decoder
|
||||
.read_image(&mut image_data)
|
||||
.map_err(|e| format!("Failed to read image data: {}", e))?;
|
||||
|
||||
Icon::from_rgba(image_data, width, height)
|
||||
.map(Some)
|
||||
.map_err(|e| format!("Failed to create icon from bytes: {}", e))
|
||||
}
|
||||
|
||||
const ICON: &'static [u8] = include_bytes!(concat!(env!("CARGO_MANIFEST_DIR"), "/../assets/Badge.png"));
|
||||
fn spawn_child_window(&mut self, event_loop: &ActiveEventLoop) {
|
||||
if let Some(main_ctx) = self.windows.values().find(|ctx| ctx.is_main_window()) {
|
||||
let title = format!("Zenyx - New Window {}", self.windows.len());
|
||||
|
@ -272,7 +277,7 @@ impl App<'_> {
|
|||
.with_min_inner_size(Size::Logical(LogicalSize::new(100.0, 100.0)))
|
||||
.with_window_icon(icon.clone())
|
||||
.with_taskbar_icon(icon);
|
||||
|
||||
|
||||
match main_ctx.window_handle() {
|
||||
Ok(handle) => {
|
||||
if !cfg!(target_os = "windows") {
|
||||
|
@ -352,6 +357,11 @@ impl App<'_> {
|
|||
|
||||
fn handle_resize(&mut self, window_id: WindowId, new_size: winit::dpi::PhysicalSize<u32>) {
|
||||
if let Some(window_context) = self.windows.get_mut(&window_id) {
|
||||
// if we dont ignore size 0 this WILL cause a crash. DO NOT REMOVE
|
||||
if new_size.height == 0 || new_size.width == 0 {
|
||||
error!("Attempted to resize a window to 0x0!");
|
||||
return;
|
||||
}
|
||||
window_context.ctx.resize(new_size.into());
|
||||
window_context.window.request_redraw();
|
||||
debug!(
|
||||
|
@ -442,7 +452,7 @@ impl ApplicationHandler for App<'_> {
|
|||
}
|
||||
|
||||
pub fn init_renderer(event_loop: EventLoop<()>) {
|
||||
event_loop.set_control_flow(ControlFlow::Wait);
|
||||
event_loop.set_control_flow(ControlFlow::Poll);
|
||||
let mut app = App::default();
|
||||
if let Err(e) = event_loop.run_app(&mut app) {
|
||||
error!("Failed to run application: {}", e);
|
||||
|
|
|
@ -556,7 +556,7 @@ impl SystemMetadata {
|
|||
};
|
||||
|
||||
format!(
|
||||
"System Metadata:\n\n{}\n\n{}\n\n{}\n\n{}\n\n{}",
|
||||
"System Information:\n\n{}\n\n{}\n\n{}\n\n{}\n\n{}",
|
||||
self.cpu.verbose_info(),
|
||||
main_gpu_info,
|
||||
other_gpu_list,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue