将紧急情况重定向到指定的缓冲区 [英] Redirect panics to a specified buffer

查看:357
本文介绍了将紧急情况重定向到指定的缓冲区的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有办法做到这一点?在终端图形库中,如果发生异常,则会在显示异常之前将其清除,从而使使用此库进行调试变得非常困难.

Is there any way to do this? In a terminal graphics library, if an exception occurs, the exception will be flushed away before being displayed, making programming very hard to debug using this library.

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();,则会打印异常,但是即使程序结束,终端也无法正确刷新屏幕,并在终端上保留图形.

If I were to comment out self.flush().unwrap(); the exception would print, however the terminal would not correctly flush the screen and leave graphics present on the terminal even after the program has ended.

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

Is it possible to, at the beginning of the program, specify a custom buffer panic will use for writing to? Or possibly write a hacky trick to do this? That way, after the flush we can check to see if anything is inside this buffer, if so we know an exception occurred and can print it out.

运行有意因算术溢出而崩溃的程序,当前输出仅

Running a program that purposely crashes with an arithmetic overflow, currently the output is only

通过注释self.flush().unwrap();,我们迎来了实际的例外,但是现在终端非常丑陋.由于不需要显示任何错误,因此该解决方案将无法正常运行,因为仍需要刷新正确执行的程序

By commenting out self.flush().unwrap(); however, we're greeted with the actual exception, but a very ugly terminal now. This solution will not work as program that execute correctly still need to be flushed since no error is needed to be displayed

推荐答案

Panics消息当前已写入stderr,因此,这样做的怪异方法是将stderr重定向到文件(cargo run 2>/path/to/panic.log).

Panics messages are currently written to stderr so the hacky way to do this is to redirect stderr to a file (cargo run 2>/path/to/panic.log).

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

Alternatively, you can do this in your program itself by using gag (disclaimer, I wrote this library). Unfortunately, it doesn't work on Windows.

以下内容将重定向stderr直到删除stderr_redirect:

The following will redirect stderr until stderr_redirect is dropped:

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缓冲在一个临时文件中:

You can also buffer stderr in a temporary file by doing:

use gag::BufferRedirect;

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

这篇关于将紧急情况重定向到指定的缓冲区的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆