panic 捕获及 throw 崩溃
一,go 语言 panic 报错捕获
使用 go 语言的同学在真实项目中应该经常出现空指针使用等 panic 报错,这类报错与 C++ 中的 try-catch 模块不同,go 语言会一直将当前 panic 一直从报错栈传至最外层的栈,所以很多 go 语言的架构都会在架构中 handler 的入口添加一串代码
defer func() {
if x := recover(); x != nil {
// TODO fix panic
}
}()
这里讲几个关键字
defer:注册一个回调函数,在当前栈退出时,按注册入栈的顺序,从最后注册的 defer 函数开始执行,函数内部发生 panic,属于可修复型崩溃,所以 go 语言会有序的退出栈,并执行 defer 函数
recover:捕捉 panic 异常,并打断当前的 panic,进行处理修复,保证不会让单个 handler 影响到整个程序
上述的异常捕获方法想必熟悉 go 语言的同学基本都能了解。但下面我们了解一些 go 语言中无法崩溃和修复的 throw 崩溃
二,go 语言 throw 奔溃
其实 go 语言源码中一些地方有一些 throw 调用,这个函数会打印相应的 fatal msg,并退出整个程序,因为这类报错被 go 语言认为无法动态修复的崩溃。所以这类奔溃与 panic 不同,属于无法通过 defer 和 recover 捕获的崩溃(因为无法修复),简单举两个栗子
lock:当使用一个初始化的锁,并未加锁就在代码中就解锁,就会发生 throw 崩溃
var lock sync.Mutex
lock.Unlock() // fatal: sync: unlock of unlocked mutex // from go 1.91
new := atomic.AddInt32(&m.state, -mutexLocked)
if (new+mutexLocked)&mutexLocked == {
throw("sync: unlock of unlocked mutex") // post a throw
}
map:熟悉 go 语言的开发者都知道,在 go 多携程架构使用便利的情况下,往往存在很多线程不安全的变量,map 就是其中最经典的栗子,当在并发下,在没有添加读写锁的情况下对 map 进行写、读写操作时,也会抛出 throw 崩溃
testmap := make([int],)
for i := ; i < ; i++ {
go func() {
for true{
testmap[] = // fatal: sync: curcurent map writes
}
}()
}
需要注意的是,这类崩溃是直接 down 掉整个进程的,所以我们线上使用 go 语言进行应用开发时,一定要记得使用 supervisor 之类的进程管理工具,确保进行崩溃后先拉起来,再进行修复。否则会产生大面积机器完全宕机的情况。
再需要注意的一点是,go 语言中一个进程往往有很多 goroutinue 在同时进行,如果发生 throw 奔溃时,整个进程都会被关掉,如果通过日志,会发现打印了无数堆栈信息的日志(所有 goroutinue 的日志),这时候千万不要在堆栈日志上下功夫了,因为打印出来的都是正常日志,只需要查看日志中的 fatal 关键字即可找出真正的问题所在。
panic 捕获及 throw 崩溃的更多相关文章
- iOS - 捕获应用程序崩溃日志
作为一名iOS移动应用开发者,为了确保你的应用程序正确无误,在将应用程序提交到应用商店之前,你必定会进行大量的测试工作:而且在你测试的过程中应用程序运行的很好,但是在应用商店上线之后,还是有用户抱怨应 ...
- C# 中异常抛出捕获机制--throw / try,catch,finally
try { messagebox.show("true"); } catch { messagebox.show("false"); } finally { m ...
- go中panic源码解读
panic源码解读 前言 panic的作用 panic使用场景 看下实现 gopanic gorecover fatalpanic 总结 参考 panic源码解读 前言 本文是在go version ...
- Android 对程序异常崩溃的捕捉
转载博客:http://blog.csdn.net/i_lovefish/article/details/17719081 以下为异常捕捉处理代码: import java.io.BufferedRe ...
- Go语言异常处理defer\panic\recover
Go语言追求简洁优雅,所以,Go语言不支持传统的 try…catch…finally 这种异常,因为Go语言的设计者们认为,将异常与控制结构混在一起会很容易使得代码变得混乱.因为开发者很容易滥用异常, ...
- 捕android程序崩溃日志
主要类别: package com.example.callstatus; import java.io.File; import java.io.FileOutputStream; import j ...
- go语言之进阶篇数组越界导致panic
1.数组越界导致panic 示例: package main import "fmt" func testa() { fmt.Println("aaaaaaaaaaaaa ...
- Windows 程序 dump 崩溃调试
Windows 程序捕获崩溃异常 生成dump 概述 事情的起因是,有个同事开发的程序,交付的版本程序,会偶尔随机崩溃了. 悲催的是没有输出log,也没有输出dump文件. 我建议他给程序代码加个异常 ...
- Android开发高手课笔记 - 01 崩溃优化(上):关于“崩溃”那点事
Android 的两种崩溃 Java 崩溃就是在 Java 代码中,出现了未捕获的异常,导致程序异常退出 Native 崩溃一般都是因为在 Native 代码中访问非法地址,也可能是地址对齐出了问题, ...
随机推荐
- 2019 Petrozavodsk Winter Camp, Yandex Cup C. Diverse Singing 上下界网络流
建图一共建四层 第一层为N个歌手 第二层为{pi,li} 第三层为{si,li} 第四层为M首歌 除了S和第一层与第三层与T之间的边为[1,INF] 其他边均为[0,1] #include<bi ...
- 【Amaple教程】4. 组件
在Amaple单页应用中,一个页面其实存在两种模块化单位,分别是 模块 (am.Module类),它是以web单页应用跳转更新为最小单位所拆分的独立块: 组件 (am.Component类),它的定位 ...
- GET与POST方法和用curl命令执行
1.超文本传输协议 超文本传输协议(HTTP)的设计目的是保证客户机与服务器之间的通信,web 浏览器可能是客户端,而计算机上的网络应用程序也可能作为服务器端. HTTP的工作方式是客户机与服务器之间 ...
- mysql 密码重置或忘记密码相关命令
方法1: 用SET PASSWORD命令 首先登录MySQL. 格式:mysql> set password for 用户名@localhost = password('新密码'); 例子:my ...
- Java8-Stream-No.05
import java.util.Arrays; import java.util.List; import java.util.function.Supplier; import java.util ...
- BZOJ 1027: [JSOI2007]合金 (计算几何+Floyd求最小环)
题解就看这位仁兄的吧-不过代码还是别看他的了- 同样的方法-我200ms,他2000ms. 常数的幽怨- CODE #include <bits/stdc++.h> using names ...
- Codeforces Round #590 (Div. 3) D. Distinct Characters Queries(线段树, 位运算)
链接: https://codeforces.com/contest/1234/problem/D 题意: You are given a string s consisting of lowerca ...
- 根据xml文件生成javaBean
原 根据xml文件生成javaBean 2017年08月15日 18:32:26 吃完喝完嚼益达 阅读数 1727 版权声明:本文为博主原创文章,遵循CC 4.0 by-sa版权协议,转载请附上原文出 ...
- bbs项目---表关系
表关系 用户表个人博客表点赞表文章表文章描述表文章和标签多对多关系表评论表分类表标签表 表关系设计示例收集: 1 https://bbs.csdn.net/topics/390260474 2 上图博 ...
- 《30天自制操作系统》学习笔记--Mac下工具的使用
现在来介绍官网上下的工具怎么用首先是官网地址,书上有个注释上有:hrb.osask.jp 翻译成中文大概是这个样子滴. 上面有两个文件可以下载,一个是工具,一个是工具的源代码,很好的学习资料 下面把工 ...