在windbg中调试.Net字符串值

我有一个.Net应用程序转储,它捕获到一个异常,我使用windbg进行分析,并对其中一个方法的String参数的值感兴趣。我已经隔离了String对象。我的WinDbg的工作是:在windbg中调试.Net字符串值

0:000> .loadby sos mscorwks 

0:000> !dso

OS Thread Id: 0x16f0 (0)

RSP/REG Object Name

00000000001fe908 000000000f011440 System.AppDomainSetup

00000000001fe918 000000000f0335f8 System.ArgumentException

00000000001fe920 000000000f011b60 System.String

0:000> !do 000000000f011b60

Name: System.String

MethodTable: 000007feef477a80

EEClass: 000007feef07e530

Size: 538(0x21a) bytes

(C:\Windows\assembly\GAC_64\mscorlib\2.0.0.0__b77a5c561934e089\mscorlib.dll)

String: C:\Windows\Installer\MSI2D87.tmp

Fields:

MT Field Offset Type VT Attr Value Name

000007feef47ecf0 4000096 8 System.Int32 1 instance 257 m_arrayLength

000007feef47ecf0 4000097 c System.Int32 1 instance 179 m_stringLength

000007feef4794c8 4000098 10 System.Char 1 instance 43 m_firstChar

000007feef477a80 4000099 20 System.String 0 shared static Empty

>> Domain:Value 00000000029d02d0:000000000f011308 <<

000007feef479378 400009a 28 System.Char[] 0 shared static WhitespaceChars

>> Domain:Value 00000000029d02d0:000000000f0121f8 <<

的m_stringLength成员变量表示字符串是179个字符长,但是它检查似乎只有32个字符长的字符串。查看此字符串的内存似乎是NULL终止。 NULL终止字符后面有更多字符。这可能是重复使用的内存或字符串损坏,但路径显示正确。 抛出的异常是'路径中的非法字符',但在这条路径中没有非法字符。 所以对于此异常调用堆栈是:

0:000> !CLRStack 

OS Thread Id: 0xbac (0)

Child-SP RetAddr Call Site

000000000021e9a0 000007feeea64dec System.IO.Path.CheckInvalidPathChars(System.String)

000000000021e9e0 000007feee9c0e66 System.IO.Path.NormalizePathFast(System.String, Boolean)

000000000021eaa0 000007feee9badf8 System.AppDomainSetup.NormalizePath(System.String, Boolean)

000000000021eb10 000007feeea630ad System.AppDomainSetup.SetupDefaultApplicationBase(System.String)

000000000021eb70 000007feee9bb27b System.AppDomain.SetupFusionStore(System.AppDomainSetup)

000000000021ebc0 000007feef87d4a2 System.AppDomain.SetupDomain(Boolean, System.String, System.String)

是否System.IO.Path.CheckInvalidPathChars方法过程中使用的m_stringLength发现长度字符串,或者它考虑到字符串本身的NULL终止? 我也接受这样一个事实,即如果你能发现我没有的东西,还有其他的错误。

回答:

这里是System.IO.Path.CheckInvalidPathChars做(至少在.NET 2.0):

for (int i = 0; i < path.Length; i++) 

{

int num2 = path[i];

if (((num2 == 0x22) || (num2 == 60)) || (((num2 == 0x3e) || (num2 == 0x7c)) || (num2 < 0x20)))

{

throw new ArgumentException(Environment.GetResourceString("Argument_InvalidPathChars"));

}

}

注意string.length减的有趣的部分,如何字符串实际上暴露了,它的长度财产,丢失:

public int Length { [MethodImpl(MethodImplOptions.InternalCall)] get; } 

我会尝试,如果可能的模拟问题,通过检索准确的字符串(最多存储在m_stringLength长度),并试图重现该问题。

回答:

我会将实际的字符串从内存中转储到文件中以检查内容,而不是仅仅查看windbg中的输出。

这是我写的一个Windbg脚本,用于将字符串转储到文件。

$$ Dumps the managed strings to a file 

$$ Platform x86

$$ Usage $$>a<"c:\temp\dumpstringtofolder.txt" 6544f9ac 5000 c:\temp\stringtest

$$ First argument is the string method table pointer

$$ Second argument is the Min size of the string that needs to be used filter the strings

$$ Third is the path of the file

.foreach ($string {!dumpheap -short -mt ${$arg1} -min ${$arg2}})

{

$$ MT Field Offset Type VT Attr Value Name

$$ 65452978 40000ed 4 System.Int32 1 instance 71117 m_stringLength

$$ 65451dc8 40000ee 8 System.Char 1 instance 3c m_firstChar

$$ 6544f9ac 40000ef 8 System.String 0 shared static Empty

$$ start of string is stored in the 8th offset, which can be inferred from above

$$ Size of the string which is stored in the 4th offset

[email protected]$t0= poi(${$string}+4)*2

.writemem ${$arg3}${$string}.txt ${$string}+8 ${$string}[email protected]$t0

}

的整体思路是使用.writemem命令将内容记录到文件中。

转储的内容将是Unicode格式,并查看其内容使用类似这样

Console.WriteLine(ASCIIEncoding.Unicode.GetString(File.ReadAllBytes(@"c:\temp\stringtest03575270.txt")));

HTH

以上是 在windbg中调试.Net字符串值 的全部内容, 来源链接: utcz.com/qa/260503.html

回到顶部