Debugging Tip: Dump the XML from System.Xml.XmlReader object
In a recent case, I had a difficult time in debugging to find the payload associated with XmlReader. I am sharing what all I have done to get to the correct parameter.
Overall, XmlReader just acts as a pointer.
MSDN definition of System.Xml.XmlReader does not talk much where we can find the full XML associated with it.
I used netext (<netext.codeplex.com/>) extension to debug on this.
0:001> .load netext
0:001> !windex –tree
Now, investigate what this thread is doing. From callstack, it is clear that certain XML read operation is underway. I am not sharing the callstack details out here as it is common to grab callstacks (by using command k or kL).
0:001> !wstack
.
.
021b4fd8 70ba4c90 0 0 12 System.Xml.XmlTextReader
.
.
Now, dump System.Xml.XmlTextReader object
0:001> !wdo 021b4fd8
.
70ba4690 System.Xml.XmlTextReaderImpl +0000 impl 021b508c
Now, dump System.Xml.XmlTextReaderImpl object
0:001> !wdo 021b508c
73db05f4 System.Int64 +0000 maxCharactersInDocument 0 (0n0)
73db05f4 System.Int64 +0008 maxCharactersFromEntities 989680 (0n10000000)
73db05f4 System.Int64 +0010 charactersInDocument 0 (0n0)
73db05f4 System.Int64 +0018 charactersFromEntities 0 (0n0)
70ba4524 System.Xml.XmlTextReaderImpl+LaterInitPa +0020 laterInitParam 00000000
73d60cbc System.Object[] +0024 nodes 021b6828
70ba497c System.Xml.XmlTextReaderImpl+NodeData +0028 curNode 021db6d0
73d60cbc System.Object[] +002c attrDuplSortingArray 00000000
70b862fc System.Xml.XmlNameTable +0030 nameTable 021b4fe4
70b84be0 System.Xml.XmlResolver +0034 xmlResolver 021b67ec
73da3e18 System.String +0038 url 021b2394 ../../../../SavedFiles/Version2NoOrder.xml
73d9d0a8 System.Threading.CompressedStack +003c compressedStack 021b6a88
70ba487c System.Xml.XmlNamespaceManager +0040 namespaceManager 021b690c
73da3e18 System.String +0044 lastPrefix 021db6ac i
70ba49d0 System.Xml.XmlTextReaderImpl+XmlContext +0048 xmlContext 021dba48
7104db58 System.Xml.XmlTextReaderImpl+ParsingStat +004c parsingStatesStack 00000000
73da3e18 System.String +0050 reportedBaseUri 021b7c9c file:///D:/Sample/SavedFiles/Version2NoOrder.xml
73da5e9c System.Text.Encoding +0054 reportedEncoding 021db614
70b8c258 System.Xml.IDtdInfo +0058 dtdInfo 00000000
70b860fc System.Xml.XmlParserContext +005c fragmentParserContext 00000000
70b963e8 System.Xml.IncrementalReadDecoder +0060 incReadDecoder 00000000
70b94d68 System.Xml.BinHexDecoder +0064 binHexDecoder 00000000
70ba2f84 System.Xml.Base64Decoder +0068 base64Decoder 00000000
70b95334 System.Xml.IncrementalReadCharsDecoder +006c readCharsDecoder 00000000
70b92a48 System.Xml.IValidationEventHandling +0070 validationEventHandling 00000000
70b9888c System.Xml.XmlTextReaderImpl+OnDefaultAt +0074 onDefaultAttributeUse 00000000
73da660c System.Text.StringBuilder +0078 stringBuilder 021b68ac
70b99c5c System.Xml.IDtdEntityInfo +007c lastEntity 00000000
73da41b8 System.Object +0080 currentEntities 00000000
70ba4e50 System.Xml.XmlReader +0084 outerReader 021b4fd8
73da3e18 System.String +0088 Xml 021b5200 xml
73da3e18 System.String +008c XmlNs 021b5214 xmlns
70b9746c System.Xml.XmlTextReaderImpl+ParseTextSt +0090 lastParseTextState 00000000
73db0bfc System.Threading.Tasks.Task<System.Tuple +0094 parseText_dummyTask 021b52e0
70b95ddc System.Xml.XmlTextReaderImpl+ParsingFunc +0098 parsingFunction 8 (0n8) PopEmptyElementContext
70b95ddc System.Xml.XmlTextReaderImpl+ParsingFunc +009c nextParsingFunction 0 (0n0) ElementContent
70b95ddc System.Xml.XmlTextReaderImpl+ParsingFunc +00a0 nextNextParsingFunction 0 (0n0) ElementContent
73da560c System.Int32 +00a4 index 1 (0n1)
73da560c System.Int32 +00a8 curAttrIndex ffffffff (0n-1)
73da560c System.Int32 +00ac attrCount 2 (0n2)
73da560c System.Int32 +00b0 attrHashtable 44000 (0n278528)
73da560c System.Int32 +00b4 attrDuplWalkCount 0 (0n0)
70ba45c0 System.Xml.WhitespaceHandling +00b8 whitespaceHandling 0 (0n0) All
70ba43f8 System.Xml.DtdProcessing +00bc dtdProcessing 2 (0n2) Parse
70b8f5a8 System.Xml.EntityHandling +00c0 entityHandling 2 (0n2) ExpandCharEntities
73da560c System.Int32 +00c4 lineNumberOffset 0 (0n0)
73da560c System.Int32 +00c8 linePositionOffset 0 (0n0)
73da560c System.Int32 +00cc parsingStatesStackTop ffffffff (0n-1)
70ba4b10 System.Xml.XmlNodeType +00d0 fragmentType 9 (0n9) Document
70b96f20 System.Xml.XmlTextReaderImpl+Incremental +00d4 incReadState 0 (0n0) Text
73da560c System.Int32 +00d8 incReadDepth 0 (0n0)
73da560c System.Int32 +00dc incReadLeftStartPos 0 (0n0)
73da560c System.Int32 +00e0 incReadLeftEndPos 0 (0n0)
73da560c System.Int32 +00e4 attributeValueBaseEntityId 0 (0n0)
73da560c System.Int32 +00e8 nextEntityId 1 (0n1)
70b9f5e0 System.Xml.XmlTextReaderImpl+ParsingMode +00ec parsingMode 0 (0n0) Full
70b860b8 System.Xml.ReadState +00f0 readState 1 (0n1) Interactive
73da560c System.Int32 +00f4 documentStartBytePos 0 (0n0)
73da560c System.Int32 +00f8 readValueOffset 0 (0n0)
70b99a58 System.Xml.XmlTextReaderImpl+ParseEndEle +00fc parseEndElement_NextFunc 0 (0n0) CheckEndTag
70b91568 System.Xml.XmlTextReaderImpl+ParseTextFu +0100 parseText_NextFunction 0 (0n0) ParseText
73daf91c System.Boolean +0104 useAsync 0 (False)
73daf91c System.Boolean +0105 attrNeedNamespaceLookup 0 (False)
73daf91c System.Boolean +0106 fullAttrCleanup 0 (False)
73daf91c System.Boolean +0107 nameTableFromSettings 0 (False)
73daf91c System.Boolean +0108 normalize 0 (False)
73daf91c System.Boolean +0109 supportNamespaces 1 (True)
73daf91c System.Boolean +010a ignorePIs 0 (False)
73daf91c System.Boolean +010b ignoreComments 0 (False)
73daf91c System.Boolean +010c checkCharacters 0 (False)
73daf91c System.Boolean +010d closeInput 1 (True)
73daf91c System.Boolean +010e v1Compat 1 (True)
73daf91c System.Boolean +010f fragment 0 (False)
73daf91c System.Boolean +0110 emptyEntityInAttributeResolved 0 (False)
73daf91c System.Boolean +0111 validatingReaderCompatFlag 0 (False)
73daf91c System.Boolean +0112 addDefaultAttributesAndNormalize 0 (False)
73daf91c System.Boolean +0113 rootElementParsed 1 (True)
73daf91c System.Boolean +0114 standalone 0 (False)
73daf91c System.Boolean +0115 afterResetState 0 (False)
73daf91c System.Boolean +0116 disableUndeclaredEntityCheck 0 (False)
73daf91c System.Boolean +0117 xmlResolverIsSet 0 (False)
70ba4fe0 System.Xml.XmlCharType +0118 xmlCharType -mt 70BA4FE0 00000000
70ba4ab8 System.Xml.XmlTextReaderImpl+ParsingStat +011c ps -mt 70BA4AB8 00000000
70b9e430 System.Xml.LineInfo +0164 incReadLineInfo -mt 70B9E430 00000000
Now, dump System.Xml.XmlTextReaderImpl+NodeData object
0:001> !wdo 021db6d0
73da3e18 System.String +0000 localName 021eb61c Person
73da3e18 System.String +0004 prefix 021b1228
73da3e18 System.String +0008 ns 021dba0c Tests.FCTests
73da3e18 System.String +000c nameWPrefix 021eb61c Person
73da3e18 System.String +0010 value 021b1228
73da47d8 System.Char[] +0014 chars 021db2c8
70ba497c System.Xml.XmlTextReaderImpl+NodeData +0018 nextAttrValueChunk 00000000
73da41b8 System.Object +001c schemaType 00000000
73da41b8 System.Object +0020 typedValue 00000000
70ba4b10 System.Xml.XmlNodeType +0024 type 1 (0n1) Element
73da560c System.Int32 +0028 valueStartPos ffffffff (0n-1)
73da560c System.Int32 +002c valueLength 4 (0n4)
73da560c System.Int32 +0030 depth 1 (0n1)
73da560c System.Int32 +0034 entityId 0 (0n0)
73da4810 System.Char +0038 quoteChar "
73daf91c System.Boolean +003a isEmptyOrDefault 1 (True)
73daf91c System.Boolean +003b xmlContextPushed 0 (False)
70b9e430 System.Xml.LineInfo +003c lineInfo -mt 70B9E430 00000000
70b9e430 System.Xml.LineInfo +0044 lineInfo2 -mt 70B9E430 00000000
70ba497c Static System.Xml.XmlTextReaderImpl+NodeData +0090 s_None 021d1dfc
Now, dump System.Char[] object
0:001> !wdo 021db2c8
.
Data Start: 021db2d0
<People xmlns:i="www.w3.org/2001/XMLSchema-instance" z:Id="1" xmlns:z="schemas.microsoft.com/2003/10/Serialization/" xmlns="Tests.FCTests">
<AnotherPerson z:Id="2" i:type="AnotherPerson">
<FriendPerson z:Id="3">
<Name z:Id="4">Person</Name>
</FriendPerson>
<Name z:Id="5">AnotherPerson</Name>
</AnotherPerson>
<Person z:Ref="3" i:nil="true" />
</People>
Now, we have found out the XML payload contained in the XmlReader object.
SOS extension can also be used the same way (it is just the commands will be different).
Pre-requisite: Windbg tool must be installed (reference: blogs.msdn.com/b/rodneyviana/archive/2015/03/10/getting-started-with-netext.aspx)
Happy debugging … I hope this helps!
Comments
- Anonymous
February 23, 2016
Hey neat extension tip and link - learned something new and this was helpful today - thanks!