这两天有用户反馈,其制作的Windows 11 22H2镜像,启动后事件日志查看器无法打开,在"服务"管理中查看"Windows event log"服务是停止状态,启动"Windows event log"服务提示1067错误,也即"程序意外结束",这真是少有的现象,事件日志服务很重要,对排查计算机软硬件相关问题特别有用,没想到本次碰到了无法通过事件查看器查看事件日志服务无法启动的问题,笑哭!
事件日志服务是由宿主程序svchost.exe启动的,先用黑盒方法观察一下。微软Sysinternals提供了工具Process Monitor,其强大功能之一就是能查看调用堆栈,拿它来看进程崩溃到哪里了。通过在Windows error reporting进程被拉起前的一个进程事件堆栈可见事件日志服务崩溃在了wevtsvc.dll的0x30910处:
崩溃在wevtsvc.dll的0x30910处
由于用户说早前Windows 10上没有此类现象,所以产生了一个暴力的想法,把Windows 10版本的wevtsvc.dll替换到Windows 11上面,经测试,一次成功!
虽然解决,但感觉Windows 11上使用Windows 10的dll还是有点不纯粹。于是打开Windbg,搞起双机调试环境后,原本还想通过一步步设断跟踪到svchost加载wevtsvc.dll,结果一启动事件日志服务,Windbg就捕获到崩溃,很爽,直接kb看堆栈吧:
Windbg显示的事件日志服务崩溃堆栈
可见服务崩溃在wevtsvc.dll的OSEventsWriteTimestamp函数处,看函数名意思是与写OS事件相关的时间戳有关,0x30910崩溃处指令是div ecx。由于是静态分析,看看调用和被调用函数吧,结果发现函数OsEventsTimestampInterval调用到注册表,与时间戳相关:
与时间戳相关的操作
所以又产生一个暴力想法(对,为快速解决问题,用暴力的),直接删除相关的注册表项特别是TimestampEnabled和TimestampInterval是否可以呢?
随即打开注册表,删除HKEY\LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Reliability下注册表,看注册表项名称似乎与关机机制相关:
Reliability注册表内容
删除注册表后,立竿见影,事件日志服务可正常启动了,点击事件日志查看器查看系统日志,也可正常展示。
到此,问题得到相对完美的解决。不过很难说到底是Windows 11的bug还是镜像制作产生的问题,因为据反馈正常硬盘安装的Windows 11没有这个问题。有时间再更进一步深入啦,随手查了一下TimeStampInterval和TimeStampEnabled的相关信息,互联网如此博大,还真有这两个值的解释,它是一个Windows策略,注解放在这里方便大家看:
启用永久性时间戳
使用此策略设置,可根据由Timestamp Interval控制的计划,通过将当前时间写入磁盘来允许系统检测意外关机的时间。
如果启用此策略设置,则可指定"永久性系统时间戳"的刷新频率以及随后写入磁盘的频率。可以指定"时间戳间隔"(以秒为单位)。
如果禁用此策略设置,则会关闭"永久性系统时间戳",且不记录意外关机的时间。
如果未配置此策略设置,则会依照默认设置(从 Windows Server 2003 开始为每 60 秒刷新一次)刷新"永久性系统时间戳"。
注意: 此功能可能与电源配置设置(处于非活动状态一段时间后,关闭硬盘)冲突。可以在"控制面板"的"电源选项"中访问这些电源设置。
TimestampEnabled和TimestampInterval注册表项取值
也有称之为Windows系统的心跳设置,它每隔一个TimestampInterval记录下时间戳,可以用来推测蓝屏或拔电等意外关机的大概时间,准确度依赖设置的TimestampInterval的精度了。