c# - 使用 WinDBG 进行事后调试

标签 c# active-directory windbg postmortem-debugging

我有一个在服务器上运行的 WCF 服务,偶尔(每个月 1-2 次)它会抛出一个 COMException 并显示信息性消息“未知错误 (0x8005008)”。当我用谷歌搜索这个特定错误时,我只得到有关在 IIS 中创建虚拟目录时出现问题的线程。并且源代码中没有任何关于在IIS中创建虚拟目录的内容。

DirectoryServiceLib.LdapProvider.Directory - CreatePost - Could not create employee for 195001010000,000000000000: System.Runtime.InteropServices.COMException (0x80005008): Unknown error (0x80005008) at System.DirectoryServices.PropertyValueCollection.PopulateList

当我捕获异常以在 WinDBG 中进行进一步分析时,我进行了内存转储。切换到正确的线程后,我执行了 !CLRStack 命令:

000000001b8ab6d8 000000007708671a [NDirectMethodFrameStandalone: 000000001b8ab6d8] Common.MemoryDump.MiniDumpWriteDump(IntPtr, Int32, IntPtr, MINIDUMP_TYPE, IntPtr, IntPtr, IntPtr)
000000001b8ab680 000007ff002808d8 DomainBoundILStubClass.IL_STUB_PInvoke(IntPtr, Int32, IntPtr, MINIDUMP_TYPE, IntPtr, IntPtr, IntPtr)
000000001b8ab780 000007ff00280812 Common.MemoryDump.CreateMiniDump(System.String)
000000001b8ab7e0 000007ff0027b218 DirectoryServiceLib.LdapProvider.Directory.CreatePost(System.String, DirectoryServiceLib.Model.Post, DirectoryServiceLib.Model.Presumptions, Services.Common.SourceEnum, System.String)
000000001b8ad6d8 000007fef8816869 [HelperMethodFrame: 000000001b8ad6d8] 
000000001b8ad820 000007feec2b6c6f System.DirectoryServices.PropertyValueCollection.PopulateList()
000000001b8ad860 000007feec225f0f System.DirectoryServices.PropertyValueCollection..ctor(System.DirectoryServices.DirectoryEntry, System.String)
000000001b8ad8a0 000007feec22d023 System.DirectoryServices.PropertyCollection.get_Item(System.String)
000000001b8ad8f0 000007ff00274d34 Common.DirectoryEntryExtension.GetStringAttribute(System.String)
000000001b8ad940 000007ff0027f507 DirectoryServiceLib.LdapProvider.DirectoryPost.Copy(DirectoryServiceLib.LdapProvider.DirectoryPost)
000000001b8ad980 000007ff0027a7cf DirectoryServiceLib.LdapProvider.Directory.CreatePost(System.String, DirectoryServiceLib.Model.Post, DirectoryServiceLib.Model.Presumptions, Services.Common.SourceEnum, System.String)
000000001b8adbe0 000007ff00279532 DirectoryServiceLib.WCFDirectory.CreatePost(System.String, DirectoryServiceLib.Model.Post, DirectoryServiceLib.Model.Presumptions, Services.Common.SourceEnum, System.String)
000000001b8adc60 000007ff001f47bd DynamicClass.SyncInvokeCreatePost(System.Object, System.Object[], System.Object[])

我的结论是代码调用的时候失败了 System.DirectoryServices.PropertyCollection.get_Item(System.String)。

所以在发出 !CLRStack -a 之后我得到了这个结果:

000000001b8ad8a0 000007feec22d023 System.DirectoryServices.PropertyCollection.get_Item(System.String)
   PARAMETERS:
      this = <no data>
      propertyName = <no data>
   LOCALS:
      <CLR reg> = 0x0000000001dcef78
      <no data>

我的第一个问题是为什么它不显示有关属性名称的任何数据?我是 Windbg 的新手。但是我在 = 0x0000000001dcef78 上执行了一个转储对象:

0:013> !do 0x0000000001dcef78
Name:        System.String
MethodTable: 000007fef66d6960
EEClass:     000007fef625eec8
Size:        74(0x4a) bytes
File:        C:\Windows\Microsoft.Net\assembly\GAC_64\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll
String:      personalprescriptioncode
Fields:
                  MT    Field   Offset                 Type VT     Attr            Value Name
000007fef66dc848  40000ed        8         System.Int32  1 instance               24 m_stringLength
000007fef66db388  40000ee        c          System.Char  1 instance               70 m_firstChar
000007fef66d6960  40000ef       10        System.String  0   shared           static Empty
                                 >> Domain:Value  0000000000174e10:00000000019d1420 000000001a886f50:00000000019d1420 <<

因此,当源代码想要从 Active Directory(用于持久层的)获取个人处方代码时,它会失败。回头看看发出 Copy 方法时的堆栈。 DirectoryServiceLib.LdapProvider.DirectoryPost.Copy(DirectoryServiceLib.LdapProvider.DirectoryPost)

查看源码:

DirectoryPost postInLimbo = DirectoryPostFactory.Instance().GetDirectoryPost(LdapConfigReader.Instance().GetConfigValue("LimboDN"), idGenPerson.ID.UserId);
if (postInLimbo != null)
   newPost.Copy(postInLimbo);

此代码正在 OU=limbo 中寻找具有相同 UserId 的另一篇文章,如果找到,它会将属性复制到新文章中。在这种情况下它确实如此,但它因个人处方代码而失败。我在 OU=Limbo 下的 Active Directory 中查看过,帖子存在于那里,属性为 personalprescriptioncode=31243。

问题一:为什么有些PARAMETERS和LOCALS没有显示数据?是否在创建 memorydump 之前清理了 GC。

问题 2:我还能做些什么来解决这个问题?

最佳答案

//
// MessageId: E_ADS_BAD_PARAMETER
//
// MessageText:
//
//  One or more input parameters are invalid
//
#define E_ADS_BAD_PARAMETER              _HRESULT_TYPEDEF_(0x80005008L)

您看不到参数/局部变量值,因为代码已优化。它们在调用时存储在 CPU 寄存器中,而不是堆栈帧中。你再也找不到大海捞针了。

关于c# - 使用 WinDBG 进行事后调试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4561577/

相关文章:

c# - Excel 无法计算状态栏中 C# 生成的文件的总和

c# Forms - MVC 框架?

c# - Active Directory LDAP 搜索过滤器或运算符语法

c++ - 从内存转储中找出线程消息队列中的消息计数

c# - 单声道 Linux Shell 命令

c# - 如果没有 TLS 1.0,WCF .NET 4.0 将无法工作

active-directory - 开发集成的用户管理、身份验证

c# - 获取 OU 的完全限定名称

windows - Windbg:中断定时器/调度程序中断并打印 EIP

c# - 使用 WinDbg 和 SOS 调试挂起的 .net 应用程序、死锁或失控线程?