这篇文(wen)章旨在帮助大家快速找到让电(dian)脑不能正常工作(zuo)的罪魁祸首。
即使现在(zai)的系统相比 20 年前已(yi)经稳定了很多了,使(shi)用电脑时也难免会遇到蓝屏、意外(wai)重启、甚至是意外关机的情(qing)况。尽管这种问题可能只是偶然(ran)发生,可以说是不太(tai)走运;但更多的时候放着不管,反而(er)会让电脑的问题出(chu)现得越来越频繁。
一个蓝屏小「贴(tie)士」
所以,这篇文章就旨在帮(bang)助大家快速找到让电脑不能正常工(gong)作的罪魁祸首,虽然不一定能「药到病除」,但也能(neng)让你离正确答案更近一步。
▍macOS尽(jin)管 macOS 是 Apple 为 Mac 产品线定制(zhi)的操作系统,但实际上(shang)出现问题的机会还是很多的。虽(sui)然在 macOS 中(zhong)我们可以通过控(kong)制台获取日志信息,但从(cong) macOS Sierra 及更高版本开始,考虑(lu)到安全和隐私问题,控制(zhi)台只允许访问最近的日志条目,而不是整个日志文(wen)件。
所以想要分析日志中所有和(he)关机有关的事件,就需要通过「终端」和相应的指令进行分(fen)析。如果你的 Mac 近期出(chu)现了意外重启等问题,不妨跟着下(xia)面的步骤试一试,打开「终端」,并输(shu)入如下指令:
log show --predicate 'eventMessage contains "Previous shutdown cause"' --last 24h
上面这一串(chuan)指令会使用 log show 检索系统日志(zhi),predicate 可以进一步筛选日志,在本文中(zhong)我们筛选的日志类型是 eventMessage 中包含 Previous shutdown cause(此前关机的原因(yin))的信息,而筛选的时间范围 --last 24h 则是过(guo)去 24 小时(shi),如果有必要的话可以扩展到 36 小时甚至更长。
来自作者群的一个(ge)朋友
静静等(deng)待一段,你就能看到如上图一样的(de)、将日志筛选后到结(jie)果,我们需要注意的信(xin)息就是Previous shutdown cause后(hou)续跟随的数字,这个数字(zi)代表着 Mac 电脑上次是因为什么原因而关(guan)闭的。
总的来说,负数(shu)的代码通常是因硬件而关机的,该信息由系统管(guan)理控制器(SMC)或处理器本(ben)身报告;而正数因(yin)软件而关机的。以下是(shi)每个代码所包含的含(han)义:
如果你的 Mac 出现大量(liang)因为 0(断电)导致的意外关闭,那(na)么就需要进行一定的排查。对于(yu)没有电池的台式 Mac 而(er)言,主要检查的就是电源线有没(mei)有牢牢插入到电(dian)源接口中;如果依然出现这样的问题(ti)则很有可能是计算机(ji)内的电源出现了问(wen)题,需要进行维修。
对于有电池的笔记本(ben)型 Mac 而言,需要同时检查(cha)电源线和电池;笔记本(ben)型 Mac 通常会(hui)在电池耗尽之前进入休眠状态;出现(xian)断电而导致的关机很有可能是电(dian)池或读取电量的电池控制器有硬件问题(ti),对于 Intel 款(kuan) Mac 而言(yan)需要根据官方文档重置 smc,而 M 系列(lie) Mac 需要手动重启一次。如果上述步骤依然不起作用的话(hua),也需要进行维修。
长时间未响(xiang)应可能会让整个系统崩溃,严重(zhong)时还会导致相关数据(ju)丢失。定时器超时作为 macOS 中一项功能,它可以有效防(fang)止未响应的程序导致(zhi)的内核崩溃。
偶然发生的 -61/-62 错误可能没什么问(wen)题,但短时间内出现大量的类似错误就(jiu)要对电脑进行排查(cha)了;-61 表示系统认为不能自(zi)动恢复的情况只能进行关机,而 -62 用于系统确(que)定重启后可能解决(jue)的情况并进行重启(qi)。
排查(cha)的办法很简单,在 macOS 启(qi)动时进入安全模式(shi),在安全模式下启动项(xiang)目和守护程序都被禁用(yong);如果没有再次意外(wai)关机则是最近安装或更新的程序(xu)出现了问题,如果再次意外关(guan)机则和系统本身有关。
以上就是(shi) macOS 的(de)部分了,相信这(zhe)个指令可以简单帮(bang)你定位问题,并为你后(hou)续的问题解决打(da)下一个不错的基础。
▍Windows除了 macOS,Windows 系统日志同样可以在(zai)时间查看器中查看并进行(xing)筛选,但考虑界面相对「复古」且用于筛选的 UI 选项更为(wei)复杂,因此我也更推(tui)荐大家使用命令行工具获取(qu)和筛选日志。
有的时候用 UI 界面反而会让一件(jian)事情变得更复杂
如果(guo)你的 PC 电脑近期出现了意外(wai)重启等问题,不妨跟着下面的(de)步骤试一试:
# 命令 1Get-Eventlog -LogName System -Source "User32" | group EventID# 命(ming)令 2Get-EventLog -LogName System -Source "Microsoft-Windows-Kernel-Power" | Where-Object { $_.EventID -eq 41 }
Get-EventLog 是 Windows 中(zhong)获取日志的命令,-LogName System 则限定了查找由系统(tong)生成的命令。-Source 则是来源,User32 和 Microsoft-Windows-Kernel-Power 则是两个不同的来源。
从(cong)用户或程序层面进行分析(xi)User32 是一个 Windows 系统应用程(cheng)序源,它包含了许多(duo)与用户界面相关的函数,如(ru)窗口创建、消息处(chu)理、控件操作等等;它(ta)还会负责处理用(yong)户交互方面的任务,例(li)如鼠标、键盘输入和窗口管理等。
因此由用户或是程序发(fa)起的事件,如登录、注销、锁定或(huo)解锁计算机等,都(dou)可以通过 User32 来源来定位。而后 | 用于进一步处(chu)理 Get-EventLog 得到的数据,这里按照 EventID 事件 ID 来(lai)group 成组。
目前(qian)我电脑中只有 1074 这个事件,这个 1074 事件(jian)是计算机的正常关机的主要表现形式。如果 User32 有其他的(de) EventID 那么(me)用下面的命令进一步分析:
# 本例中依然用 1074 做分析 Get-Eventlog -LogName System -Source "User32"-Newest 1 | Where-Object { $_.EventID -eq 1074} | fl *
前面的命令就不再赘述了(le),-Newest 1 表示选(xuan)取最近的一个日志, | 用于进一步(bu)筛选 Get-EventLog 得到的数据。Where-Object 表示筛选一个(ge)对象数组,$_ 表示当前处理的(de)对象(也就是 | 传递过来的数据 ),.EventID 表示对象的 EventID 属性,-eq 是一个比较运算符,表示等于(yu),这里等于的 1074 这个事件。| 依然是用于进一步处理(li) Where-Object 得到的数据,由 fl(也(ye)可以用完整写法 Format-List 替代)格式化(hua)输出对象的 * 所有属性。
找到其中的Reason Code: 0x80020010可以得知这是一个(ge)计划内的关机请求,如果(guo)不是服务器的话,这(zhe)一般由 Windows Update 自动更新发起;而由用户发起的(de)关机则会被标识为 0x0。以下是(shi)常见的 Reason Code 所表示的含(han)义:
蓝屏问题导致关机或重启(qi),还可以进一步(bu)下方的命令进行分析。
从(cong)电源管理相关的事件入手进行分析不过很多意(yi)外关机的事件,比如蓝(lan)屏导致的,无法被 User32 捕(bu)获,因此从Microsoft-Windows-Kernel-Power 获取电(dian)源状态、电源事件以及与电(dian)源管理相关的错误和警告信息得到(dao)更多的信息。
Get-EventLog -LogName System -Source "Microsoft-Windows-Kernel-Power" | Where-Object { $_.EventID -eq 41 }
代(dai)码中相似的内容不再赘述,在Microsoft-Windows-Kernel-Power和意外关机有(you)关的 EventID 是 41,这个事件通常是在意外关(guan)机后重启的阶段中生成(cheng)的。输入上面的命令以后,Powershell 会输出一段包含十进制 BugcheckCode 的内容,首先需要将它转换为十六进制,以做(zuo)进一步分析。
如 159 等同于 0x0000009f,209 等同于 0x000000d1 等等,转(zhuan)换后的十六进制就可以(yi)得到最终的含义了。BugcheckCode 内容也和蓝屏时输出(chu)的错误码是相同的内(nei)容,有的时候蓝屏代(dai)码一跳而过,所以这也是找(zhao)到问题的好办法(fa)。以下是常见的错误的代码(ma)以及含义 :
由于错误码的种类繁多(duo),因此这里不太(tai)可能一一列举。另外还需要(yao)注意的是,同一(yi)个错误可能会有不同的原因而导致,排查时可以从近期(qi)的软件改动入手去寻找电脑意外关机的(de)原因,排查完软件(jian)以后才是排查硬件的(de)真正时机。
关于 Powershell 7 使用中的一些(xie)细节值得(de)注意的是,Get-EventLog 只能使用 Windows 内的 Powershell 运行(xing);Powershell 7 中因为相关 API 已被弃用,会提示无效指令,因此需要换用Get-WinEvent命令:
#命令 1Get-WinEvent -ProviderName 'User32' | group EventID#命令 2Get-WinEvent -ProviderName "Microsoft-Windows-Kernel-Power" | Where-Object { $_.EventID -eq 41}#命令 2 改进版Get-WinEvent -FilterHashtable @{ProviderName = "Microsoft-Windows-Kernel-Power"; Id = 41}
Get-WinEvent 是 Powershell 7 中获取 Windows 日志的新(xin)命令,不同于此前的 Get-EventLog 能(neng)同时筛选具体的事件(jian)日志 -LogName 和事件源 -Source;Get-WinEvent在使用时只能在筛选事(shi)件日志 -Logname 和事件源 -ProviderName 中二选一。Get-WinEvent 还 可以使用一个(ge)新的写法 -FilterHashtable,降低命(ming)令长度的同时提高索引效率。