c# - Depuración postmortem con WinDBG
active-directory postmortem-debugging (1)
//
// MessageId: E_ADS_BAD_PARAMETER
//
// MessageText:
//
// One or more input parameters are invalid
//
#define E_ADS_BAD_PARAMETER _HRESULT_TYPEDEF_(0x80005008L)
No puede ver los valores de argumento / variable local porque el código está optimizado. Se almacenan en los registros de la CPU en el momento de la llamada, no en el marco de la pila. Ya no puedes encontrar la aguja en el pajar.
Tengo un servicio WCF que se ejecuta en un servidor y ocasionalmente (1 o 2 veces al mes) arroja una COMException con el mensaje informativo "Error desconocido (0x8005008)". Cuando busqué en Google este error en particular, solo recibí hilos sobre problemas al crear directorios virtuales en IIS. Y el código fuente no tiene nada que ver con crear un directorio virtual en 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
Tomé un volcado de memoria cuando capté la Excepción para un análisis posterior en WinDBG. Después de cambiar al hilo correcto, ejecuté el comando! 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[])
Mi conclusión es que falla cuando el código llama a System.DirectoryServices.PropertyCollection.get_Item (System.String).
Entonces, después de emitir un! CLRStack -a obtengo este resultado:
000000001b8ad8a0 000007feec22d023 System.DirectoryServices.PropertyCollection.get_Item(System.String)
PARAMETERS:
this = <no data>
propertyName = <no data>
LOCALS:
<CLR reg> = 0x0000000001dcef78
<no data>
Mi primera pregunta es ¿por qué no muestra datos en el nombre de propiedad? Soy un poco nuevo en Windbg. Sin embargo, ejecuté un dumpobject en = 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 <<
Entonces, cuando el código fuente quiere obtener el código de prescripción personal de Active Directory (lo que se usa para la capa de persistencia) falla. Mirando hacia atrás en la pila es cuando se emite el método Copiar. DirectoryServiceLib.LdapProvider.DirectoryPost.Copy (DirectoryServiceLib.LdapProvider.DirectoryPost)
Entonces mirando en el código fuente:
DirectoryPost postInLimbo = DirectoryPostFactory.Instance().GetDirectoryPost(LdapConfigReader.Instance().GetConfigValue("LimboDN"), idGenPerson.ID.UserId);
if (postInLimbo != null)
newPost.Copy(postInLimbo);
Este código está buscando otra publicación en OU = limbo con el mismo UserId y si encuentra uno copia los atributos a la nueva publicación. En este caso, lo hace y falla con el código de prescripción personal. He buscado en Active Directory en OU = Limbo y la publicación existe allí con el atributo personalprescriptioncode = 31243.
Pregunta 1: ¿Por qué no muestra datos para algunos de los PARÁMETROS y LOCALES? ¿Es el GC quien se ha limpiado antes de que se haya creado el salto de memoria?
Pregunta 2: ¿Hay algo más que pueda hacer para llegar a la solución de este problema?