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 代码中访问非法地址,也可能是地址对齐出了问题, ...
随机推荐
- idea 设置Terminal为git终端
- Linux文件系统之目录清单
挂载点:挂载:将设备关联到当前文件系统目录 文件系统:rootfs:根文件系统/boot:系统启动相关文件,如内核.initrd.以及grub(bootleader:引导加载器)/dev:设备文件, ...
- 利用python deque的extend特性实现列表元素查重
from collections import deque mydquene = deque() mylist = [0,1,1,2,2,3,3,3,3,4,5,6,7,7,8,8,9,10,10,1 ...
- BZOJ 2013 : [Ceoi2010]A huge tower / Luogu SP6950 CTOI10D3 - A HUGE TOWER
传送门 菜鸡.jpg CODE #include <bits/stdc++.h> using namespace std; const int MAXN = 620005; int n, ...
- hdfs基本使用
基本命令 /usr/local/hadoop/bin/hadoop fs -ls / /usr/local/hadoop/bin/hadoop fs -mkdir /test # 创建目录 /usr/ ...
- learning armbian steps(7) ----- armbian 源码分析(二)
从compile.sh开始入手: SRC="$(dirname "$(realpath "${BASH_SOURCE}")")" # fal ...
- 【CUDA 基础】6.3 重叠内和执行和数据传输
title: [CUDA 基础]6.3 重叠内和执行和数据传输 categories: - CUDA - Freshman tags: - 深度优先 - 广度优先 toc: true date: 20 ...
- windows下mysql 主库从库同步
今天先讲讲数据库的主从同步,两个好处: 一是读写分离可以用上.比如 写操作就写到主数据库,读就再从库读取 二是纯粹给数据库备份,以防硬盘彻底崩了 主从数据库操作准备: 两台电脑,都安装好mysql 5 ...
- .NetCore 读取配置文件
1.创建config.json配置,并设置成始终复制 2.需要安装 nuget 包 Microsoft.Extensions.Configuration .Microsoft.Extensions.C ...
- Windows操作系统中的I/O(读/写 输入/输出)
导言 写一个Windows平台下的应用程序大多时候都是离不开读写文件,网络通信的. 比如一个服务应用程序来说,它可能从网络适配器接受用户的请求,对请求进行处理计算,最终将用户端所需的数据返回,中间可能 ...