У меня есть 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, и, если он находит один, он копирует атрибуты в новый пост. В этом случае это происходит, и происходит сбой с персональным кодом. Я посмотрел в Active Directory под OU = Limbo и там существует пост с атрибутом personalprescriptioncode = 31243.
Вопрос 1: Почему он не отображает данные для некоторых ПАРАМЕТРОВ и МЕСТНЫХ? Это GC очистил до того, как был создан дамп памяти.
Вопрос 2: Могу ли я еще что-нибудь сделать, чтобы найти решение этой проблемы?