首页 文章

将恐慌重定向到指定的缓冲区

提问于
浏览
3

生锈有什么办法吗?在终端图形库中,如果当前发生异常,则异常将在显示之前被清除;使用这个库很难调试编程 .

impl Drop for Terminal {
    fn drop(&mut self) {
        self.outbuffer.write_all(&self.driver.get(DevFn::ShowCursor)).unwrap();
        self.outbuffer.write_all(&self.driver.get(DevFn::Reset)).unwrap();
        self.outbuffer.write_all(&self.driver.get(DevFn::Clear)).unwrap();
        self.outbuffer.write_all(&self.driver.get(DevFn::ExitCa)).unwrap();
        self.flush().unwrap(); // If an exception occurs, this will reclear the screen and remove the output
        self.termctl.reset().unwrap();
        SIGWINCH_STATUS.store(false, Ordering::SeqCst);
        RUSTTY_STATUS.store(false, Ordering::SeqCst);
    }
}

如果我要注释 self.flush().unwrap(); 将打印异常,但是即使程序结束,终端也无法正确刷新屏幕并在终端上保留图形 .

是否有可能在程序开始时指定用于写入的自定义缓冲区恐慌?或者可能写一个hacky技巧来做到这一点?这样,在刷新之后我们可以检查是否有任何东西在这个缓冲区内,如果是这样我们知道发生了异常并且可以打印出来 .


运行一个故意与算术溢出崩溃的程序,目前输出只是
enter image description here

然而,通过评论 self.flush().unwrap(); ,我们受到实际例外的欢迎,但现在是一个非常难看的终端 . 此解决方案将无法正常执行仍需要刷新的程序,因为不需要显示错误

enter image description here

1 回答

  • 2

    恐慌消息当前写入stderr,因此执行此操作的hacky方法是将stderr重定向到文件( cargo run 2>/path/to/panic.log ) .

    或者,您可以使用gag(免责声明,我编写此库)在您的程序中执行此操作 . 不幸的是,它在Windows上不起作用 .

    以下将重定向stderr,直到 stderr_redirect 被删除:

    use std::fs::OpenOptions;
    use gag::Redirect;
    
    let log = OpenOptions::new()
        .truncate(true)
        .read(true)
        .create(true)
        .write(true)
        .open("/path/to/panic.log")
        .unwrap();
    
    let stderr_redirect = Redirect::stderr(log).unwrap();
    // Your code here...
    

    您还可以通过执行以下操作来缓冲临时文件中的stderr:

    use gag::BufferRedirect;
    
    let mut stderr_buffer = BufferRedirect::stderr().unwrap();
    

相关问题