当我打开套接字连接时,我在套接字打开后立即将socket.Close()逻辑放入defer函数中.但是,如果socket.Close()会导致另一个恐慌怎么办?我应该总是在外部延迟内嵌套另一个延迟/恢复以防止我的程序崩溃吗?像这样:http://play.golang.org/p/GnEMQS-0jj
谢谢,Elgs
我试着让它运转起来,不知道我做错了什么.我已经创建了一个Debian.img(原始格式的磁盘,带有虚拟设备管理器 - 我认为是libvirt)并安装了debian而没有任何麻烦.现在我想用自编译的内核运行它.我从我的工作(虚拟)debian复制了.config文件,并且没有进行任何更改.这就是我做的:
qemu-system-x86_64 -m 1024M -kernel /path/to/bzImage -hda /var/lib/libvirt/images/Debian.img -append "root=/dev/sda1 console=ttyS0" -enable-kvm -nographic
Run Code Online (Sandbox Code Playgroud)
但在启动过程中我总是收到此错误消息.
[ 0.195285] Initializing network drop monitor service
[ 0.196177] List of all partitions:
[ 0.196641] No filesystem could mount root, tried:
[ 0.197292] Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0)
[ 0.198355] Pid: 1, comm: swapper/0 Not tainted 3.2.46 #7
[ 0.199055] Call Trace:
[ 0.199386] [<ffffffff81318c30>] ? panic+0x95/0x19e
[ 0.200049] [<ffffffff81680f7d>] ? mount_block_root+0x245/0x271
[ 0.200834] [<ffffffff8168112f>] ? …Run Code Online (Sandbox Code Playgroud) 内核恐慌消息中的"不同步"是什么意思?
我已经读过,这意味着内核成功地将数据同步到磁盘,但我不确定.
典型的上下文是:"内核恐慌 - 不同步 - 试图杀死init!"
我在Go.my程序中编写CLI接口程序,要求用户输入文件名作为参数.以下是我编写的代码,用于处理用户未输入任何参数的情况.但它恐慌并给出错误"索引超出范围".我怎么处理这个?
package main
import (
"encoding/hex"
"fmt"
"io/ioutil"
"log"
"os"
)
func main() {
if len(os.Args) == 0 {
fmt.Println("usage: gohex <filename>")
os.Exit(1)
} else {
filename := os.Args[1]
data, err := ioutil.ReadFile(filename)
if err != nil {
log.Fatal(err)
}
fmt.Println(hex.Dump(data))
}
}
Run Code Online (Sandbox Code Playgroud) 是否可以在#![no_std]模式下放松恐慌,例如使用定制的#[panic_handler]?
如果使用set_hook,我们可以获得大量信息,尤其是堆栈跟踪 - 这非常有帮助。然而,对于catch_unwind,我只得到 a Result,其中几乎不包含任何有用的信息。因此,我想知道如何使用 Rust 获取恐慌信息(尤其是堆栈跟踪)catch_unwind?
我处于多线程环境中,其中有许多线程同时运行,任何线程都可能出现恐慌。我想我应该set_hook与 一起使用catch_unwind,并且还使用一些线程局部变量,但我不确定它是否可行以及细节。
有什么办法可以做到这一点吗?在终端图形库中,如果发生异常,异常将在显示之前被刷新,这使得使用该库进行编程非常困难。
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);
}
}
Run Code Online (Sandbox Code Playgroud)
如果我要注释掉self.flush().unwrap();异常,则会打印异常,但是即使程序结束后,终端也不会正确刷新屏幕并在终端上留下图形。
是否可以在程序开始时指定用于写入的自定义缓冲区恐慌?或者可能写一个黑客技巧来做到这一点?这样,在刷新之后,我们可以检查该缓冲区内是否有任何内容,如果有,我们就知道发生了异常并可以将其打印出来。
然而,通过注释掉self.flush().unwrap();,我们看到了实际的异常,但现在是一个非常丑陋的终端。该解决方案将不起作用,因为正确执行的程序仍然需要刷新,因为不需要显示错误
在我的overflower_support箱子的测试中,我发现我收到很多关于已经使用的恐慌的虚假报告std::panic::catch_unwind(_).这有点不幸,因为它掩盖了可能发生的真实错误.消息看起来像:
thread 'safe' panicked at 'arithmetic overflow', src/lib.rs:56
Run Code Online (Sandbox Code Playgroud)
为了平息那些dont_panic(..)令人分心的消息,我引入了函数,它劫持了恐慌处理程序,调用了一个闭包并在完成时重置了恐慌处理程序,返回了闭包结果.它看起来像这样:
fn dont_panic<F, A, R>(args: A, f: F) -> R
where F: Fn(A) -> R
{
let p = panic::take_hook();
panic::set_hook(Box::new(|_| ()));
let result = f(args);
panic::set_hook(p);
result
}
Run Code Online (Sandbox Code Playgroud)
但是,在函数中使用此函数来进行检查有点令人惊讶,不仅可以消除所需的消息,还可以快速检查错误输出,这对我来说显然很有价值.即使将测试限制在一个线程中也会发生这种情
#[test]
fn test_some_panic() {
fn check(x: usize) -> bool {
let expected = if x < 256 { Some(x) } else { None };
let actual = dont_panic(|| panic::catch_unwind(|| { assert!(x < 256); x }).ok());
expected …Run Code Online (Sandbox Code Playgroud) 如何隐藏项目信息(如源代码路径)以防止运行发布版本时发生的紧急消息?
假设以下代码作为最小可重现示例
fn main() {
println!("Hello!");
let v = vec![0];
println!("{:?}", v[1]); // panic - index out of bounds
}
Run Code Online (Sandbox Code Playgroud)
> cargo build --release
> target/release/hello-rust
得到:
Hello!
thread 'main' panicked at 'index out of bounds: the len is 1 but the index is 1', src/main.rs:5:22
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Run Code Online (Sandbox Code Playgroud)
泄露“src/main.rs:5:22”是非常不受欢迎的。我什至不想透露使用 Rust 构建的可执行文件。
我想在每种panic情况下都以“1”错误代码退出进程,例如索引越界或.unwrap()出错。
尝试过:
[profile.release]
panic = "abort"
Run Code Online (Sandbox Code Playgroud)
没有帮助。
试图查看“个人资料设置”,但没有找到有用的东西。
在这里看问题 3 。
举个例子,我已经这样编辑了。
fn main() {
never_return();
// println!("Failed!");
}
fn never_return() -> ! {
// Implement this function, don't modify the fn signatures
panic!("stop")
}
Run Code Online (Sandbox Code Playgroud)
从 fn 返回某些内容时的期望是没有尾随的;。在上面的情况下,panic!(_)返回一个类型never并执行我期望的操作。但是,相同的 fn 签名返回!,无论宏;后面panic是否有 a ,都会编译为相同的结果。我假设情况是这样,因为panic?的内在本质。但找不到我理解的技术解释。
为什么会这样呢?