wenmo8 发布的文章

简介

此表旨在帮助将Windows运行时应用程序错误代码交叉引用到Microsoft.NET标准异常,这些异常可以作为应用程序异常处理技术的一部分。

对照表

.NET Exception (Namespace)

HRESULT(s) - symbolic

HRESULT(s) - raw

AccessViolationException

E_POINTER

0x80004003

AmbiguousMatchException (System.Reflection)

COR_E_AMBIGUOUSMATCH

0x8000211d

ApplicationException

COR_E_APPLICATION

0x80131600

AppDomainUnloadedException

COR_E_APPDOMAINUNLOADED

0x80131014

ArithmeticException

COR_E_ARITHMETIC

0x80070216

ArgumentException

COR_E_ARGUMENT

0x80070057

ArgumentNullException

E_POINTER

0x80004003

ArgumentOutOfRangeException

COR_E_ARGUMENTOUTOFRANGE

0x80131502

ERROR_NO_UNICODE_TRANSLATION

0x80070459

ArrayTypeMismatchException

COR_E_ARRAYTYPEMISMATCH

0x80131503

BadImageFormatException

COR_E_BADIMAGEFORMAT

0x8007000b

CLDB_E_FILE_OLDVER

0x80131107

CLDB_E_INDEX_NOTFOUND

0x80131124

CLDB_E_FILE_CORRUPT

0x8013110e

COR_E_NEWER_RUNTIME

0x8013101b

COR_E_ASSEMBLYEXPECTED

0x80131018

ERROR_BAD_EXE_FORMAT

0x800700c1

ERROR_EXE_MARKED_INVALID

0x800700c0

CORSEC_E_INVALID_IMAGE_FORMAT

0x8013141d

ERROR_NOACCESS

0x800703e6

ERROR_INVALID_ORDINAL

0x800700b6

ERROR_INVALID_DLL

0x80070482

ERROR_FILE_CORRUPT

0x80070570

COR_E_LOADING_REFERENCE_ASSEMBLY

0x80131058

META_E_BAD_SIGNATURE

0x80131192

CannotUnloadAppDomainException

COR_E_CANNOTUNLOADAPPDOMAIN

0x80131015

ContractException (System.Diagnostics.Contracts)

COR_E_CODECONTRACTFAILED

0x80131542

ContextMarshalException (System)

COR_E_CONTEXTMARSHAL

0x80131504

CustomAttributeFormatException (System.Reflection)

COR_E_CUSTOMATTRIBUTEFORMAT

0x80131605

CryptographicException (System.Security.Cryptography)

CORSEC_E_CRYPTO

0x80131430

CryptographicUnexpectedOperationException (System.Security.Cryptography)

CORSEC_E_CRYPTO_UNEX_OPER

0x80131431

DataMisalignedException

COR_E_DATAMISALIGNED

0x80131541

DirectoryNotFoundException (System.IO)

COR_E_DIRECTORYNOTFOUND

0x80070003

STG_E_PATHNOTFOUND

0x80030003

CTL_E_PATHNOTFOUND

0x800a004c

DivideByZeroException

COR_E_DIVIDEBYZERO

0x80020012

CTL_E_DIVISIONBYZERO

0x800a000b

DllNotFoundException

COR_E_DLLNOTFOUND

0x80131524

DuplicateWaitObjectException

COR_E_DUPLICATEWAITOBJECT

0x80131529

EndOfStreamException (System.IO)

COR_E_ENDOFSTREAM

0x80070026

EntryPointNotFoundException

COR_E_ENTRYPOINTNOTFOUND

0x80131523

Exception

COR_E_EXCEPTION

0x80131500

ExecutionEngineException

COR_E_EXECUTIONENGINE

0x80131506

FieldAccessException

COR_E_FIELDACCESS

0x80131507

FileLoadException (System.IO)

COR_E_FILELOAD

0x80131621

FUSION_E_INVALID_PRIVATE_ASM_LOCATION

0x80131041

FUSION_E_SIGNATURE_CHECK_FAILED

0x80131045

FUSION_E_LOADFROM_BLOCKED

0x80131051

FUSION_E_CACHEFILE_FAILED

0x80131052

FUSION_E_ASM_MODULE_MISSING

0x80131042

FUSION_E_INVALID_NAME

0x80131047

FUSION_E_PRIVATE_ASM_DISALLOWED

0x80131044

FUSION_E_HOST_GAC_ASM_MISMATCH

0x80131050

COR_E_MODULE_HASH_CHECK_FAILED

0x80131039

FUSION_E_REF_DEF_MISMATCH

0x80131040

SECURITY_E_INCOMPATIBLE_SHARE

0x80131401

SECURITY_E_INCOMPATIBLE_EVIDENCE

0x80131403

SECURITY_E_UNVERIFIABLE

0x80131402

COR_E_FIXUPSINEXE

0x80131019

ERROR_TOO_MANY_OPEN_FILES

0x80070004

ERROR_SHARING_VIOLATION

0x80070020

ERROR_LOCK_VIOLATION

0x80070021

ERROR_OPEN_FAILED

0x8007006e

ERROR_DISK_CORRUPT

0x80070571

ERROR_UNRECOGNIZED_VOLUME

0x800703ed

ERROR_DLL_INIT_FAILED

0x8007045a

FUSION_E_CODE_DOWNLOAD_DISABLED

0x80131048

CORSEC_E_MISSING_STRONGNAME

0x8013141b

MSEE_E_ASSEMBLYLOADINPROGRESS

0x80131016

ERROR_FILE_INVALID

0x800703ee

FileNotFoundException (System.IO)

ERROR_FILE_NOT_FOUND

0x80070002

ERROR_MOD_NOT_FOUND

0x8007007e

ERROR_INVALID_NAME

0x8007007b

CTL_E_FILENOTFOUND

0x800a0035

ERROR_PATH_NOT_FOUND

0x80070003

ERROR_BAD_NET_NAME

0x80070043

ERROR_BAD_NETPATH

0x80070035

ERROR_NOT_READY

0x80070015

ERROR_WRONG_TARGET_NAME

0x80070574

INET_E_UNKNOWN_PROTOCOL

0x800c000d

INET_E_CONNECTION_TIMEOUT

0x800c000b

INET_E_CANNOT_CONNECT

0x800c0004

INET_E_RESOURCE_NOT_FOUND

0x800c0005

INET_E_OBJECT_NOT_FOUND

0x800c0006

INET_E_DOWNLOAD_FAILURE

0x800c0008

INET_E_DATA_NOT_AVAILABLE

0x800c0007

ERROR_DLL_NOT_FOUND

0x80070485

CLR_E_BIND_ASSEMBLY_VERSION_TOO_LOW

0x80132000

CLR_E_BIND_ASSEMBLY_PUBLIC_KEY_MISMATCH

0x80132001

CLR_E_BIND_ASSEMBLY_NOT_FOUND

0x80132004

FormatException

COR_E_FORMAT

0x80131537

IndexOutOfRangeException

COR_E_INDEXOUTOFRANGE

0x80131508

InsufficientExecutionStackException

COR_E_INSUFFICIENTEXECUTIONSTACK

0x80131578

InvalidCastException

COR_E_INVALIDCAST

0x80004002

InvalidComObjectException (System.Runtime.InteropServices)

COR_E_INVALIDCOMOBJECT

0x80131527

InvalidFilterCriteriaException (System.Reflection)

COR_E_INVALIDFILTERCRITERIA

0x80131601

InvalidOleVariantTypeException (System.Runtime.InteropServices)

COR_E_INVALIDOLEVARIANTTYPE

0x80131531

InvalidOperationException

COR_E_INVALIDOPERATION

0x80131509

InvalidProgramException

COR_E_INVALIDPROGRAM

0x8013153a

IOException (System.IO)

COR_E_IO

0x80131620

CTL_E_DEVICEIOERROR

0x800a0039

IsolatedStorageException (System.IO.IsolatedStorage)

ISS_E_ISOSTORE

0x80131450

ISS_E_OPEN_STORE_FILE

0x80131460

ISS_E_OPEN_FILE_MAPPING

0x80131461

ISS_E_MAP_VIEW_OF_FILE

0x80131462

ISS_E_GET_FILE_SIZE

0x80131463

ISS_E_CREATE_MUTEX

0x80131464

ISS_E_LOCK_FAILED

0x80131465

ISS_E_FILE_WRITE

0x80131466

ISS_E_SET_FILE_POINTER

0x80131467

ISS_E_CREATE_DIR

0x80131468

ISS_E_CORRUPTED_STORE_FILE

0x80131480

ISS_E_STORE_VERSION

0x80131481

ISS_E_FILE_NOT_MAPPED

0x80131482

ISS_E_BLOCK_SIZE_TOO_SMALL

0x80131483

ISS_E_ALLOC_TOO_LARGE

0x80131484

ISS_E_USAGE_WILL_EXCEED_QUOTA

0x80131485

ISS_E_TABLE_ROW_NOT_FOUND

0x80131486

ISS_E_DEPRECATE

0x801314a0

ISS_E_CALLER

0x801314a1

ISS_E_PATH_LENGTH

0x801314a2

ISS_E_MACHINE

0x801314a3

ISS_E_STORE_NOT_OPEN

0x80131469

ISS_E_MACHINE_DACL

0x801314a4

MarshalDirectiveException (System.Runtime.InteropServices)

COR_E_MARSHALDIRECTIVE

0x80131535

MethodAccessException

COR_E_METHODACCESS

0x80131510

META_E_CA_FRIENDS_SN_REQUIRED

0x801311e6

MemberAccessException

COR_E_MEMBERACCESS

0x8013151a

MissingFieldException

COR_E_MISSINGFIELD

0x80131511

MissingManifestResourceException (System.Resources)

COR_E_MISSINGMANIFESTRESOURCE

0x80131532

MissingMemberException

COR_E_MISSINGMEMBER

0x80131512

MissingMethodException

COR_E_MISSINGMETHOD

0x80131513

MulticastNotSupportedException

COR_E_MULTICASTNOTSUPPORTED

0x80131514

NotFiniteNumberException

COR_E_NOTFINITENUMBER

0x80131528

NotImplementedException

E_NOTIMPL

0x80004001

NotSupportedException

COR_E_NOTSUPPORTED

0x80131515

NullReferenceException

COR_E_NULLREFERENCE

0x80004003

ObjectDisposedException

COR_E_OBJECTDISPOSED

0x80131622

RO_E_CLOSED

0x80000013

OperationCanceledException

COR_E_OPERATIONCANCELED

0x8013153b

OutOfMemoryException

E_OUTOFMEMORY

0x8007000e

CTL_E_OUTOFMEMORY

0x800a0007

OverflowException

COR_E_OVERFLOW

0x80131516

CTL_E_OVERFLOW

0x800a0006

PathTooLongException (System.IO)

COR_E_PATHTOOLONG

0x800700ce

PlatformNotSupportedException

COR_E_PLATFORMNOTSUPPORTED

0x80131539

System.RankException

COR_E_RANK

0x80131517

ReflectionTypeLoadException (System.Reflection)

COR_E_REFLECTIONTYPELOAD

0x80131602

RemotingException (System.Runtime.Remoting)

COR_E_REMOTING

0x8013150b

RuntimeWrappedException (System.Runtime.CompilerServices)

COR_E_RUNTIMEWRAPPED

0x8013153e

ServerException (System.Runtime.Remoting)

COR_E_SERVER

0x8013150e

SecurityException (System.Security)

COR_E_SECURITY

0x8013150a

CORSEC_E_INVALID_STRONGNAME

0x8013141a

CTL_E_PERMISSIONDENIED

0x800a0046

CORSEC_E_INVALID_PUBLICKEY

0x8013141e

CORSEC_E_SIGNATURE_MISMATCH

0x80131420

SafeArrayRankMismatchException System.Runtime.InteropServices)

COR_E_SAFEARRAYRANKMISMATCH

0x80131538

SafeArrayTypeMismatchException (System.Runtime.InteropServices)

COR_E_SAFEARRAYTYPEMISMATCH

0x80131533

SerializationException (System.Runtime.Serialization)

COR_E_SERIALIZATION

0x8013150c

StackOverflowException

COR_E_STACKOVERFLOW

0x800703e9

CTL_E_OUTOFSTACKSPACE

0x800a001c

SynchronizationLockException (System.Threading)

COR_E_SYNCHRONIZATIONLOCK

0x80131518

SystemException

COR_E_SYSTEM

0x80131501

TargetException (System.Reflection)

COR_E_TARGET

0x80131603

TargetInvocationException (System.Reflection)

COR_E_TARGETINVOCATION

0x80131604

TargetParameterCountException (System.Reflection)

COR_E_TARGETPARAMCOUNT

0x8002000e

ThreadAbortException (System.Threading)

COR_E_THREADABORTED

0x80131530

ThreadInterruptedException (System.Threading)

COR_E_THREADINTERRUPTED

0x80131519

ThreadStateException (System.Threading)

COR_E_THREADSTATE

0x80131520

ThreadStartException (System.Threading)

COR_E_THREADSTART

0x80131525

TypeAccessException

COR_E_TYPEACCESS

0x80131543

TypeInitializationException

COR_E_TYPEINITIALIZATION

0x80131534

TypeLoadException

COR_E_TYPELOAD

0x80131522

RO_E_METADATA_NAME_NOT_FOUND

0x8000000f

CLR_E_BIND_TYPE_NOT_FOUND

0x80132005

TypeUnloadedException

COR_E_TYPEUNLOADED

0x80131013

UnauthorizedAccessException

COR_E_UNAUTHORIZEDACCESS

0x80070005

CTL_E_PATHFILEACCESSERROR

0x800a004b

VerificationException (System.Security)

COR_E_VERIFICATION

0x8013150d

PolicyException (System.Security.Policy)

CORSEC_E_POLICY_EXCEPTION

0x80131416

CORSEC_E_NO_EXEC_PERM

0x80131418

CORSEC_E_MIN_GRANT_FAIL

0x80131417

XmlSyntaxException (System.Security)

CORSEC_E_XMLSYNTAX

0x80131419

COMException (System.Runtime.InteropServices)

E_FAIL

0x80004005

ExternalException (System.Runtime.InteropServices)

E_FAIL

0x80004005

SEHException (System.Runtime.InteropServices)

E_FAIL

0x80004005

ElementNotAvailableException (Windows.UI.Xaml.Automation)

(none)

0x802b001f

ElementNotEnabledException (Windows.UI.Xaml.Automation)

(none)

0x802b001e

LayoutCycleException (Windows.UI.Xaml)

(none)

0x802b0014

XamlParseException (Windows.UI.Xaml.Markup)

(none)

0x802b000a

说明

在上表的“.NET异常”列中,如果链接了异常名称,则该异常是.NET for Windows运行时应用程序类的一部分。这意味着您可以在自己的代码中引发该类型的新异常。或者您可以捕获这些异常,特别是作为try-catch或UnhandledException异常处理的一部分。如果未链接异常名称,则该异常不属于.NET for Windows运行时类的一部分。不属于.NET for Windows运行时集的异常可能在某些互操作方案中遇到,也可能来自系统或Windows运行时内部。您将无法使用该特定异常类型为它们编写捕获块,因为您为Windows运行时应用程序运行的.NET库不知道该类型。但是您仍然可以读取一个HRESULT代码,从“HRESULT(s)-raw:”列中查找它,并注意到有一个对应的.NET异常。或者你可以把它当作一般的例外。然后,您可以阅读.NET文档,或许可以了解有关该异常的意图以及原始代码引发该异常的原因的更多信息,即使该异常未在.NET for Windows运行时类型中表示。如果没有为.NET异常列出命名空间,则它来自系统命名空间。

“HRESULT(s)-symbolic”列中列出的常量来自多种来源。有些是在winerror.h中定义的,有些是在特定于组件对象模型(COM)编程的头文件中定义的,有些是在属于Windows特定子系统的头文件中定义的。有些需要HRESULT_From_Win32宏用法,其中包含来自更早的常量集的代码(前面是ERROR_)。对于使用.NET语言时的典型Windows运行时编程,这些头文件不是作为项目的一部分提供的。如果您正在获取系统无法映射到标准异常的情况下的错误代码信息,则可能会将其视为原始整数或十六进制值,并且不会自动支持将数字代码别名为Windows命名的常量值。尽管如此,在以前的Windows错误报告系统的基础上,仍然存在按其命名常量而不是原始代码引用错误代码的历史。您可以使用表中的命名常量进一步研究其他文档源(如论坛或支持文档)中的错误,特别是该错误对桌面编程、Microsoft Win32和COM等意味着什么。

SystemException:在原始的.NET异常层次结构中,许多异常是从系统异常派生的。例如,从SystemException派生的System.ArgumentException。从SystemException继承表明.NET核心定义了异常。Windows运行时的.NET类集合中未包含系统异常。所有在完整框架下从SystemException派生的异常都是从System.Exception派生的。
COMException:NET文档建议对任何无法识别的HRESULT抛出COMException,但这不是Windows运行时应用的行为。相反,COMException通常是用于源于组件的未映射异常的标准异常。来自您自己的应用程序代码或系统的未映射异常报告为基本异常,其HResult值不标准。
ExternalException:不包含在.NET for Windows运行时中。对于确实存在的异常(如SEHException),在层次结构中看不到这一点。

 

 

今天,当我们继续学习.NET异常处理系列时,我们将查看System.BadImageFormatException。System.BadImageFormatException与GIF或JPG无关,而是在.NET应用程序尝试加载与当前公共语言运行库(CLR)所需的正确格式不匹配的动态链接库(.dll)或可执行文件(.exe)时发生。
在本文中,我们将看到System.BadImageFormatException在.NET异常层次结构中的确切位置,并查看System.BadImageFormatException的一些潜在原因,让我们开始讨论它!

如前所述,System.BadImageFormatException发生在非常特殊的情况下:当.NET试图使用.dll或.exe时,即以某种方式与当前公共语言运行库不兼容。“不兼容的公共语言运行时”的定义可能有所不同,但通常这意味着.NET版本(1.1、2.0等)或各种编译程序集的CPU类型(32位与64位)不匹配。
最后,System.BadImageFormatExceptions表示版本控制不兼容。对于许多现代软件应用程序,的主要版本通常包括打破兼容性问题,防止与以前版本的某些方面向后兼容。.NET程序集(.dll或.exe)基本相同,尝试使用包含不兼容项的两种不同类型的程序集通常会生成System.BadImageFormatException。
为了说明这一点,我们将通过几个不同的例子。我已经包含了下面的完整代码示例以供参考,之后我们将更详细地探讨细节:

usingSystem;usingSystem.Reflection;usingUtility;namespaceAirbrake.BadImageFormatException
{
classProgram
{
static void Main(string[] args)
{
LoadingNonDotNetLibraryExample();
Logging.Log(
"-----------------");
DifferingCPUExample();
Logging.Log(
"-----------------");
OldDotNetExample();
}
private static voidLoadingNonDotNetLibraryExample()
{
try{//Generate path to notepad.exe. string filePath = Environment.ExpandEnvironmentVariables("%windir%") + @"\System32\notepad.exe";
Assembly assem
=Assembly.LoadFile(filePath);
}
catch(System.BadImageFormatException exception)
{
Logging.Log(exception);
}
}
private static voidDifferingCPUExample()
{
try{//Load Utility.dll, a 64-bit assembly. Assembly assem = Assembly.LoadFrom(@".\Utility.dll");
Logging.Log(assem.ToString());
}
catch(System.BadImageFormatException exception)
{
Logging.Log(exception);
}
}
private static voidOldDotNetExample()
{
try{//Load Author-1.1.dll (compiled in .NET 1.1). Assembly assem = Assembly.LoadFrom(@".\Author-1.1.dll");
Logging.Log(assem.ToString());
}
catch(System.BadImageFormatException exception)
{
Logging.Log(exception);
}
}
}
}
usingSystem;usingSystem.Diagnostics;namespaceUtility
{
/// <summary> ///Houses all logging methods for various debug outputs./// </summary> public static classLogging
{
/// <summary> ///Outputs to<see cref="System.Diagnostics.Debug.WriteLine"/>if DEBUG mode is enabled,///otherwise uses standard<see cref="Console.WriteLine"/>./// </summary> /// <param name="value">Value to be output to log.</param> public static void Log(objectvalue)
{
#if DEBUGDebug.WriteLine(value);#elseConsole.WriteLine(value);#endif}/// <summary> ///When<see cref="Exception"/>parameter is passed, modifies the output to indicate///if<see cref="Exception"/>was expected, based on passed in `expected` parameter./// <para>Outputs the full<see cref="Exception"/>type and message.</para> /// </summary> /// <param name="exception">The<see cref="Exception"/>to output.</param> /// <param name="expected">Boolean indicating if<see cref="Exception"/>was expected.</param> public static void Log(Exception exception, bool expected = true)
{
string value = $"[{(expected ?"EXPECTED":"UNEXPECTED")}] {exception.ToString()}: {exception.Message}";#if DEBUGDebug.WriteLine(value);#elseConsole.WriteLine(value);#endif}
}
}

如果您调试了一段时间的崩溃转储,那么您可能遇到了这样的情况:调试器提供的初始转储上下文对应于在处理初始异常时发生的第二个异常,该异常可能更接近您正在调查的问题中的原始基础问题。
这可能很烦人,因为“.ecxr”命令将指向次要故障异常的位置,而不是原始异常上下文本身。然而,在大多数情况下,原始的、主要的异常上下文仍然在堆栈上;人们只需要知道如何找到它。

有两种方法可以解决这个问题:

  1. 对于硬件生成的异常(access violations),可以查找堆栈上的ntdll!KiUserExceptionDispatcher,它以PCONTEXT和PEXCEPTION_RECORD作为参数。
  2. 对于软件生成的异常(如C++异常),情况会变得更糟。你可以找在堆栈上调用ntdll!RtlDispatchException,然后从那里获取PCONTEXT参数。

当你调试一个程序时,你最不想处理的是调试器不能正常工作。当你试图集中精力跟踪一个bug时,总是会因为次要的问题而被忽略,尤其是当调试器的问题导致你失去一个重新编程或者浪费了大量的时间等待调试器完成它,而调试器知道这需要永远做些什么的时候。
这是我时常会遇到的大量问题,所以我整理了一些常见问题的简短列表,人们很容易就会被这些问题绊倒(以及如何避免或解决它们)。

  1. 我正在使用ntsd,无法加载符号或大多数调试器扩展命令(!command)不工作。这通常意味着您启动了操作系统附带的ntsd(在Windows Vista之前),这比调试器包附带的ntsd要老得多。因为它在系统目录中,所以它将在您的可执行搜索路径中。要解决此问题,请使用调试器安装目录中的ntsd可执行文件。
  2. WinDbg处理模块加载事件需要很长的时间,它在一个CPU上使用最大处理器时间(旋转)。如果工作区中保存了许多跟踪模块加载事件(通过bu创建)的非限定断点,则通常会发生这种情况。当您处理的程序中有大量的修饰C++符号时,这个问题尤其明显,例如大量使用STL或其他模板类的程序的调试构建。由于强制立即加载所有模块的符号,非限定断点通常很昂贵,但它们还强制调试器对正在加载的模块中的每个符号(对于每个未解析的断点)取消修饰并执行模式匹配。
    如果允许在默认工作区中保存大量不合格的断点,则无论调试的是哪个程序,都可能使调试器看起来非常慢。
    为了避免被这个问题困扰,不要使用不合格的断点(没有modulename的断点!除非绝对必要。此外,如果您不需要在下次与调试器工作区的调试会话中保存所有断点(默认情况下,bu断点将保留在调试器工作区中,而bp断点在每次调试会话后都会消失),则在保存工作区之前清除所有断点通常是一个好主意。如果您习惯于每次附加到正在运行的进程时都保存工作区,并且您经常使用bu断点,则这会使用户默认工作区变得杂乱无章,如果不小心,可能会很快导致调试器性能非常差。
    您可以使用bc命令删除断点(bc*删除所有断点),但您需要保存工作区以保留更改。如果问题已经到了甚至无法在合理的时间内完成模块加载,以便使用bc*清除保存的断点的程度,则可以删除HKCU\Software\Microsoft\Windbg\Workspaces注册表项和子项的内容,以使Windbg返回原始状态。这将清除已保存的调试器窗口位置和其他已保存的调试器设置,因此请将其作为最后手段使用。
  3. WinDbg处理模块加载事件需要很长的时间,但它不占用很多处理器时间。这通常意味着符号路径包括断开的HTTP符号存储链接或断开的UNC符号存储路径。符号路径中的非响应路径将导致任何尝试加载模块符号的操作需要很长时间才能完成,因为网络超时将反复发生。
    使用!sym noise,后跟.reload/f以确定符号路径的哪个部分工作不正常。然后,修复或移除符号路径的冲突部分。
    当调试位于数据包路径中的程序时,也可能会出现此问题,这些程序将数据包发送到符号路径上的某个位置。在这种情况下,我建议的典型解决方法是设置一个空符号路径,附加到有问题的进程,编写一个转储文件,然后从进程分离。然后,恢复正常符号路径并在调试器中打开转储文件,并发出.reload/f命令以强制提前预缓存所有符号。在下游存储缓存中预缓存所有符号后,将符号路径更改为仅引用下游存储缓存位置,而不引用任何UNC或HTTP符号服务器路径,并将调试器附加到包路径中的进程以进行符号服务器访问。
  4. WinDbg拒绝为我知道符号服务器有符号的模块加载符号。如果WinDbg以前尝试(但失败)下载模块的符号,则可能会出现此问题。dbghelp的symbol服务器支持中似乎存在一个bug,有时会导致部分下载的PDB文件留在下游存储缓存中。如果发生这种情况,以后访问模块符号的尝试将失败,并出现错误,说明找不到模块符号。
    如果打开嘈杂符号加载(!sym noise),通常会给出一个更具描述性的错误。如果您看到有关E_PDB_CORRUPT的投诉,那么您可能是此问题的受害者。指示此问题的调试器输出如下所示:
    DBGHELP: c:\symbols­\ntdll.pdb­\2744327E50A64B24A87BDDCFC7D435A02­\ntdll.pdb – E_PDB_CORRUPT
    如果遇到此问题,只需删除错误消息中命名的.pdb,然后通过.reload/f<modulename>命令重试加载符号。
  5. 当我附加到特定进程(如svchost实例)时,WinDbg将挂起并且永远不会返回。如果确信工作区中保存的符号路径已断开或模块加载跟踪断点不合格,并且调试器在附加到某个进程时从未返回(或附加到该进程时几乎总是在第一个命令之后挂起),则调试可能位于负责符号加载的代码路径中。
    在调试svchost实例时,此问题尤其常见,因为在各种svchost实例中运行了许多重要但不相关的代码片段,其中一些代码对于网络符号服务器支持的工作至关重要。如果正在调试网络符号服务器支持的关键路径中的进程,并且有一个设置了网络组件的符号路径,则可能导致调试器在第一次尝试加载符号时死锁(永久挂起)。
    一个可能导致这种情况的例子是,如果您正在调试与DNS缓存服务位于同一svchost实例中的代码。在这种情况下,当您尝试加载符号并且符号路径中有HTTP符号服务器链接时,调试器将死锁,因为当它尝试解析符号路径中引用的服务器的主机名时,它将尝试对DNS缓存服务进行RPC调用。因为在调试器恢复进程之前,DNS缓存服务不会响应,并且调试器在从RPC请求获得对DNS缓存服务的响应之前,也不会恢复进程,所以调试会话将无限期挂起。
    请注意,如果只是调试符号服务器存储区的数据包路径中的某些内容,则通常会看到调试器在很长一段时间内变得无响应,但不会完全挂起。这是因为调试器可以处理网络超时(如果有点慢的话)并最终使对网络符号路径的请求失败。但是,如果调试器试图向正在调试的进程发出某种IPC请求,并且IPC请求没有任何内置超时(大多数本地IPC机制没有),那么调试器会话将永远丢失。
    这个问题的解决方法类似于我通常建议用户如何处理模块加载缓慢或符号服务器访问失败的问题,该问题是使用符号路径中引用的符号服务器的数据包路径中的程序解决的。具体来说,可以通过从具有空符号路径的调试器实例中创建进程转储,然后分离并打开具有完整符号路径的转储,并强制下载所有符号,来预缓存进程的所有符号。然后,使用符号路径在实时进程上启动调试会话,该符号路径仅引用符号下载到的本地下游存储,以防止发生任何危险的网络访问。
    另一个让你陷入这种调试器死锁问题的常见方法是,当你调试一个已经将某些东西放入剪贴板的程序时,使用剪贴板粘贴到WinDbg中。这会导致类似的死锁,因为WinDbg可能会在对剪贴板所有者的DDE请求中被阻止,而剪贴板所有者将永远不会由于被调试而响应。在这种情况下,解决方法只是在将文本复制或粘贴到WinDbg中或从WinDbg中复制或粘贴文本时要小心。
  6. 使用-remote或.server进行的远程调试不稳定,或在一段时间后停止正常工作。如果会话中的所有调试器运行的调试器版本不同,则可能会发生这种情况。
    确保远程调试方案中的所有对等方都使用(相同的)最新调试器版本。如果将调试器版本与-remote混合并匹配,在我的经验中,事情往往会以奇怪且难以诊断的方式出现(对于调试器远程处理协议的向后或向前兼容性,似乎没有太多得体的支持)。
    另外,在Windows2000上,调试器包的几个最新版本在远程调试模式下根本不起作用。据我所知,这是在最新版本中修复的。

一旦你知道要寻找什么,这些问题中的大多数都很容易解决或避免(尽管如果你被发现不知道的话,这些问题肯定会耗费很多时间,因为我自己在学习这些“陷阱”的过程中也做了这些事情)。

WinDbg、ntsd、cdb、kd和其他任何使用DbgEng打开转储文件的工具都有一个鲜为人知的特性。
事实证明,使用DbgEng提供的任何功能,在任何可以打开转储文件(用户转储、内核转储等)的地方,都可以打开PE映像(.exe/.dll/.sys/etc),并让调试器将其视为只包含所选PE映像内容的转储。
这实际上是一个相对有用的特性。当您将PE映像作为转储文件打开时,调试器将其映射为映像,就好像它是作为可执行代码加载到内存中一样(尽管它实际上不运行任何代码,但只是将其映射为可执行文件而不是数据文件)。这将获得exe/dll/sys/other PE文件的内存表示形式,就好像您正在调试加载有问题图像的实时进程(或转储)。
与转储调试会话一样,这本质上是一个只读会话;您不能真正修改任何内容,因为没有要控制的目标。此外,也没有真正的寄存器上下文(或堆栈或堆),尽管初始化和零填充的全局变量以及属于该模块的可执行代码将在内存中。(在这种情况下,模块的首选映像库用于将请求的PE模块建立在为调试会话构造的虚拟地址空间中。)
加载完目标后,您可以执行通常对转储执行的大部分操作,只要检查符号并分解目标即可。如果您需要一个具有符号支持的反汇编程序,并且不能启动一个进程或什么不包含PE映像,那么这个特殊的技巧是一个功能更全面的反汇编程序的quick-n-dirty替换。
注意,在转储模式下打开PE映像的一个副作用是符号服务器用于检索二进制文件(这可能看起来有点奇怪,直到您考虑到对于转储文件,通常情况是您没有将整个二进制文件保存在内存中;只有足够的头信息从符号服务器检索二进制文件)。因此,在尝试此特殊技巧之前,请确保您的符号路径设置正确。