2023年1月

符号服务器访问是对比调试器。能够自动下载与当前系统匹配的所有程序(或者最终用户系统,如果我们想调试崩溃转储)的符号是非常方便的。但是有一个小问题:有些模块的符号在公共符号服务器上没有。但是调试器并不知道,因此每次我们启动调试会话时,调试器都会连接符号服务器并尝试下载模块的符号,但没有成功。因此,调试会话的启动时间会显著增加,特别是对于使用大量第三方组件的应用程序,这些组件的符号无法定义在Microsoft symbol server上。
幸运的是,有一个解决方案-我们可以告诉调试器,一些模块应该从符号服务器搜索中排除。

以下是操作方法:

1、升级symsrv.dll.
这个小DLL负责符号服务器的访问。净我们应该将它升级到一个更新的版本,这个版本是随Windows调试工具提供的。在我们下载并安装调试工具之后,symsrv.dll应该从其安装目录复制到<VSInstallDir>\Common7\IDE目录。
2、在symsrv.ini文件中指定排除列表。

此文件应创建在<VSInstallDir>\Common7\IDE目录(其中symsrv.dll位置)。

此文件的[exclusions]部分应包含要从符号服务器搜索中排除的文件列表。支持通配符,我更喜欢用*通配符替换所有文件扩展名,以确保排除所有可能的调试信息文件格式。
这是一个样品symsrv.ini要求调试器排除msxml4.dll和shlwapi.dll从搜索服务器符号:

;start of symsrv.ini
[exclusions]
msxml4.*
shlwapi.*
;end of symsrv.ini

在windbg中,可以使用Ctrl+Alt+D查看调试器的内部信息流。在KD中,使用Ctrl+D和ENTER来切换输出。启用这个输出,我可以看到调试器无法从调试端口读取数据,而且它正在超时。错误“SYNCTARGET:Timeout.”清楚地表明调试主机无法与调试目标通信,尤其是在“Send Break-in”消息之后出现此错误时。

 

因为我在Hyper-V虚拟机上使用命名管道,所以我知道我没有坏电缆,尽管这是导致内核调试失败的常见原因。我还知道虚拟机的配置是正确的,我可以将调试器用于这台服务器上的其他虚拟机。问题很可能是在虚拟机中运行的操作系统。
通过检查设备管理器,我能够确认在虚拟机中运行的操作系统的配置有问题。bcdedit设置被配置为使用COM1,这将使COM1在操作系统中不可用,但是,COM1出现在设备管理器中。由于某些原因,调试器在启动时没有像配置的那样捕获COM1。

 

检查此服务器的bcd配置时,我发现bcd配置不正确。在普通Windows 7或Windows Server 2008 R2操作系统的bcd存储中,bcdedit的Windows引导加载程序部分具有继承设置。您可以使用命令“bcdedit/enum all”从提升的命令提示符查看系统上的此信息。通常,Windows引导加载程序继承{bootloadersettings},{bootloadersettings}继承{globalsettings},{globalsettings}继承{dbgsettings}。如果没有继承设置,则引导加载程序将无法读取调试器配置。
下面是损坏的虚拟机的bcd设置。您可以看到所有正常继承的设置都丢失了。

C:\Windows\system32>bcdedit /enum all



Windows Boot Manager
--------------------identifier {bootmgr}

device partition
=C:

path \bootmgr

description Windows Boot Manager

locale en
-US

default {current}

displayorder {current}

timeout
30Windows Boot Loader-------------------identifier {current}

device partition
=C:

path \Windows\system32\winload.exe

description Windows Server
2008R2 Standard (recovered)

locale en
-US

osdevice partition
=C:

systemroot \Windows

resumeobject {2ec5363f
-2a92-11e1-bbe4-806e6f6e6963}

usefirmwarepcisettings No

debug Yes



Resume from Hibernate
---------------------identifier {2ec5363f-2a92-11e1-bbe4-806e6f6e6963}

device partition
=C:

path \Windows\system32\winresume.exe

description Windows Server
2008R2 Standard (recovered)

locale en
-US

inherit {resumeloadersettings}

filedevice partition
=C:

filepath \hiberfil.sys

debugoptionenabled Yes



Windows Memory Tester
---------------------identifier {memdiag}

device partition
=C:

path \boot\memtest.exe

description Windows Memory Diagnostic

locale en
-US



Debugger Settings
-----------------identifier {dbgsettings}

debugtype Serial

debugport
1baudrate115200

什么是bad_cast异常?

当对引用类型的动态转换未通过运行时检查(例如,因为类型与继承无关)时,将引发此类型的异常。

继承关系

class bad_cast : public exception

例子:

//expre_bad_cast_Exception.cpp//compile with: /EHsc /GR
#include <typeinfo>#include<iostream>

classShape {public:virtual void virtualfunc() const{}
};
class Circle: publicShape {public:virtual void virtualfunc() const{}
};
using namespacestd;intmain() {
Shape shape_instance;
Shape
& ref_shape =shape_instance;try{
Circle
& ref_circle = dynamic_cast<Circle&>(ref_shape);
}
catch(bad_cast b) {
cout
<< "Caught:" <<b.what();
}
}

什么是bad_typeid异常?

当typeid运算符应用于多态类型的已取消引用的空指针值时,将引发此类型的异常。

继承关系:

class bad_typeid : public exception

例子:

//expre_bad_typeid.cpp//compile with: /EHsc /GR
#include <typeinfo>#include<iostream>

classA{public://object for class needs vtable//for RTTI
   virtual ~A();
};
using namespacestd;intmain() {
A
* a =NULL;try{
cout
<< typeid(*a).name() << endl; //Error condition }catch(bad_typeid){
cout
<< "Object is NULL" <<endl;
}
}

十、已卸载模块列表流(UnloadedModuleListStream)

UnloadedModuleListStream流包含卸载模块的模块信息。跟随在ModuleListStream的后面。ModuleListStream相关信息如下:

0x29c0+0n26680=0x91f8

UnloadedModuleListStream相关信息如下:

可知,UnloadedModuleListStream的RVA为0x91f8,所以它紧随在ModuleListStream的后面,大小为324字节。数据如下:

这些数据按如下结构组织:

首先是相当于头结构的_MINIDUMP_UNLOADED_MODULE_LIST,包含流的一些数据量

typedef struct_MINIDUMP_UNLOADED_MODULE_LIST {
ULONG32 SizeOfHeader;
ULONG32 SizeOfEntry;
ULONG32 NumberOfEntries;
} MINIDUMP_UNLOADED_MODULE_LIST,
*PMINIDUMP_UNLOADED_MODULE_LIST;