由于我正在运行Go程序作为服务器,我需要一些机制来捕获恐慌日志,如果出现任何问题,以便以后进行分析和调试.是否有任何有效的方法可以轻松地在Unix下获取Go程序的恐慌日志?你们能介绍一下你的经历吗?谢谢 :)
是否存在将错误转换为恐慌的try宏,类似于宏?我需要定义自己的吗?
例如,如果单元测试无法打开文件,我会感到恐慌.我目前的解决方法是:
macro_rules! tryfail {
($expr:expr) => (match $expr {
result::Result::Ok(val) => val,
result::Result::Err(_) => panic!(stringify!($expr))
})
}
#[test]
fn foo() {
let c = tryfail!(File::open(...));
}
Run Code Online (Sandbox Code Playgroud) 我做了一个大型程序,打开和关闭文件和数据库,执行写入和读取等等.由于没有"go中的异常处理"这样的事情,并且由于我并不真正了解"defer"语句和"recover()"函数,所以我在每次文件打开,读写,数据库输入后应用了错误检查等等
_,insert_err := stmt.Run(query)
if insert_err != nil{
mylogs.Error(insert_err.Error())
return db_updation_status
}
Run Code Online (Sandbox Code Playgroud)
为此,我在开头将db_updation_status定义为"false",并且在程序中的所有内容都正确之前不要将其设置为"true".在我认为可能出错的每次操作之后,我在每个功能中都这样做了.
你认为使用延迟 - 恐慌恢复有更好的方法吗?我在这里阅读了这些http://golang.org/doc/articles/defer_panic_recover.html,但无法清楚地了解如何使用它们.这些构造是否提供类似于异常处理的东西?没有这些结构,我会更好吗?如果有人能用一种简单的语言向我解释这个问题,并且/或者为这些结构提供一个用例并将它们与我上面使用的错误处理类型进行比较,我将非常感激.
http://play.golang.org/p/TE02wFCprM
当我尝试从列表中的结构中获取值时,出现错误恐慌。
fmt.Println(A_elem.Value.(Player).year) //3000
Run Code Online (Sandbox Code Playgroud)
我所做的是创建一个列表并将结构添加到列表中。当我从列表中检索元素时,它是接口类型。但如果我打印出整个接口类型值,它仍然包含结构值。所以我试图获取结构的一个值,但出现了恐慌错误。
这条线运作良好。
fmt.Println(A_elem.Value) //&{dddd 3000}
Run Code Online (Sandbox Code Playgroud)
代码在这里
package main
import (
"container/list"
"fmt"
)
func main() {
type Player struct {
name string
year int
}
A := new(Player)
A.name = "aaaa"
A.year = 1990
B := new(Player)
B.name = "eeee"
B.year = 2000
C := new(Player)
C.name = "dddd"
C.year = 3000
play := list.New()
play.PushBack(A)
play.PushBack(B)
play.PushBack(C)
A_elem := play.Back()
//A_elem.Value is type Player struct
fmt.Println(A_elem.Value) //&{dddd 3000}
fmt.Println(A_elem.Value.(Player).year) //3000
}
Run Code Online (Sandbox Code Playgroud)
我想将结构保存在列表中,并能够从列表中保存的结构之一检索特定值。
我怎样才能做到呢?
提前致谢。
我们在基于MIPS的嵌入式设备领域遇到内核恐慌。如何在MTD分区中记录内核恐慌跟踪?我们是否必须仅将跟踪写入MTD还是可以覆盖NFS?谁能解释一下在出现紧急情况之后,如何获得有用的内核跟踪。
从bufio包中读取代码我发现了这样的东西:
// fill reads a new chunk into the buffer.
func (b *Reader) fill() {
...
if b.w >= len(b.buf) {
panic("bufio: tried to fill full buffer")
}
...
}
Run Code Online (Sandbox Code Playgroud)
同时将有效围棋 段约panic含有下一段落:
这只是一个例子,但真正的库函数应该避免恐慌。如果问题可以被掩盖或解决,那么让事情继续运行总是比取消整个程序更好。
所以,我想知道,特定缓冲读取器的问题是否如此重要以至于导致panic标准库代码中的调用?
为什么会出现这种恐慌?
pub fn testbool() -> bool {
vec!['a', 'd', 'i', 'e', 'p', 'r']
.iter()
.enumerate()
.find(|(_i, &c)| c != 'c')
.is_none()
}
#[test]
fn test_testbool() {
assert!(testbool(), true);
}
Run Code Online (Sandbox Code Playgroud)
pub fn testbool() -> bool {
vec!['a', 'd', 'i', 'e', 'p', 'r']
.iter()
.enumerate()
.find(|(_i, &c)| c != 'c')
.is_none()
}
#[test]
fn test_testbool() {
assert!(testbool(), true);
}
Run Code Online (Sandbox Code Playgroud)
这可能很简单,但我不明白。
为什么这段代码会在第 7 行出现恐慌?foo_unwrapped 不应该是第 5 行的 Some(3) 而不是 None?
use std::rc::Rc;
fn main()
{
let foo: Rc<i32> = Rc::new(3);
let mut foo_cloned = Rc::clone(&foo);
let mut foo_unwrapped = Rc::get_mut(&mut foo_cloned).unwrap();
foo_unwrapped = &mut 42;
}
Run Code Online (Sandbox Code Playgroud) 考虑以下故意导致双重恐慌的代码:
use scopeguard::defer; // 1.1.0
fn main() {
defer!{ panic!() };
defer!{ panic!() };
}
Run Code Online (Sandbox Code Playgroud)
我知道当Drop实现在从之前的恐慌中恢复时出现恐慌时,通常会发生这种情况,但为什么它会导致程序发出非法指令呢?听起来代码已损坏或意外跳转到某个地方。我认为这可能与系统或代码生成相关,但我在各种平台上进行了测试,它们都因相同的原因而发出类似的错误:
Linux:
use scopeguard::defer; // 1.1.0
fn main() {
defer!{ panic!() };
defer!{ panic!() };
}
Run Code Online (Sandbox Code Playgroud)
窗口(带有cargo run):
thread panicked while panicking. aborting.
Illegal instruction (core dumped)
Run Code Online (Sandbox Code Playgroud)
铁锈游乐场:
thread panicked while panicking. aborting.
error: process didn't exit successfully: `target\debug\tests.exe` (exit code: 0xc000001d, STATUS_ILLEGAL_INSTRUCTION)
Run Code Online (Sandbox Code Playgroud)
这是怎么回事?这是什么原因造成的?
有人提到了这个问题:从恐慌中恢复的程序不会按预期退出 它工作正常,但它依赖于了解恐慌发生的位置才能放置延迟函数。我的代码如下。
package main
import "fmt"
func main() {
defer recoverPanic()
f1()
f2()
f3()
}
func f1() {
fmt.Println("f1")
}
func f2() {
defer f3() //<--- don't want to defer f3 here because I might not know f2 will panic, panic could occuer elsewhere
fmt.Println("f2")
panic("f2")
}
func f3() {
fmt.Println("f3")
}
func recoverPanic() {
if r := recover(); r != nil {
fmt.Printf("Cause of panic ==>> %q\n", r)
}
}
Run Code Online (Sandbox Code Playgroud)
在恐慌函数中延迟函数调用 f3() 是有效的,输出如下。
f1
f2
f3
Cause of …Run Code Online (Sandbox Code Playgroud)