在最近一期的庐山软件调试研习班中,有格友报告无法加载NTDLL的符号文件。老雷上前查看,发现他的NTDLL很新,是2017年7月份的,执行!sym noisy打开符号的“吵杂”模式,可以看到WinDBG确实无法下载PDB。
NTDLL是Windows操作系统中一个很特殊的模块,是NT内核派驻到用户空间中的'嫡系',映射到每个进程中,与内核呼应,有着特别重要的地位。
因为NTDLL的身份不一般,它的符号文件也比其它符号文件更重要。普通DLL的符号文件找不到可能只影响这个DLL的信息,而NTDLL的符号文件缺少的话,那么WinDBG的很多命令都无法执行,比如!peb, !teb, !heap等。原因是这些命令依赖NTDLL的符号文件来识别系统的数据结构。
回到上海后,某一天使用WinDBG时,我也遇到了同样的问题,应该是我的Windows 10系统自动升级了NTDLL。
再次确认微软的公共符号器遗漏了NTDLL的符号后,我首先尝试给windbg的官方支持邮箱(windbgfb@microsoft.com)发邮件。
但是没有回应。接下来想到的是联系微软中认识的朋友,请他们帮忙转发邮件报告这个问题。但在这时,突然想到了微博,既然是公事,那就公办吧,省得麻烦朋友,于是在微博中@了一下微软Windows的官方账号。
微博发出后,得到了很多同行的热烈讨论,有的抱怨“微软质量”大不如前,还有同行@苹果的CEO,想让苹果像微软一样提供调试符号,互联网真是激发灵感的好地方。可是,微软官方并没有给予任何回应。
本着不放弃的精神,又想起了第三种方法,那就是在OSR的WinDBG邮件BBS上发消息报告问题。
这回很快就收到了回应,一位微软同行回复邮件。
邮件确认了问题,并主动认错,承认是微软的问题,“为上个月的更新发布调试符号时出了问题”,他们正在努力,尽快把缺少的符号传上去。
今天又使用WinDBG时,发现问题解决了,原本缺少的PDB出现了,受影响的命令也开始工作了。
0:000> !heap
Heap Address NT/Segment Heap
1f336ea0000 Segment Heap
1f336d10000 NT Heap
1f337080000 Segment Heap
1f338d80000 Segment Heap
1f339050000 Segment Heap
1fb390d0000 Segment Heap
1f3003f0000 NT Heap
顺便说一下,大约最近一年里,微软应该是对PDB格式做了某些调整,这个调整会让较低版本的WinDBG把公开的PDB当作是私有PDB。比如以下是6.12版本的WinDBG显示的模块信息:
0:000> lm vm ntdll
start end module name
00007ffc`dcd00000 00007ffc`dced2000 ntdll (private pdb symbols) c:\symbols\ntdll.pdb\4A71B509A35941A796F5B86F1AD38F531\ntdll.pdb
其中的PDB类型为private pdb symbols,但其实这是不对的,文件只有1.5MB,怎么是私有PDB呢?
Windows 10版本的WinDBG就不会上这个当,显示为:
start end module name
00007ffc`dcd00000 00007ffc`dced2000 ntdll (pdb symbols) c:\symbols\ntdll.pdb\4A71B509A35941A796F5B86F1AD38F531\ntdll.pdb
无论是个人还是公司,都可能有疏忽和犯错误,有了问题后,“勇于承认是自己的问题并且积极改正”就是好的。