.net - 在windbg 中调试.Net 字符串值

标签 .net debugging windbg postmortem-debugging

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

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 终止?
如果你能发现我没有发现的东西,我也愿意接受这样一个事实。

最佳答案

我会将内存中的实际字符串转储到文件中以检查内容,而不仅仅是查看 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
  r@$t0=  poi(${$string}+4)*2
  .writemem ${$arg3}${$string}.txt ${$string}+8 ${$string}+8+@$t0
}

整个想法是使用 .writemem命令将内容转储到文件中。

转储的内容将采用 Unicode 格式,并使用类似这样的内容查看其内容
Console.WriteLine(ASCIIEncoding.Unicode.GetString(File.ReadAllBytes(@"c:\temp\stringtest03575270.txt")));
HTH

关于.net - 在windbg 中调试.Net 字符串值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6263563/

相关文章:

c# - 使用windbg中的Logger.exe打印方法调用

.net - 有没有一种简单的方法可以使用 sos 查看字典中的键值对?

c# - 如何隐藏控制台窗口?

c# - .NET MVC5 session 未结束

c# - OWIN 干扰 log4net

java - 为什么我不能在 SAXParser 中打开这个 XML?

javascript - 调试器使用源映射显示错误信息

.net - 为什么-ErrorVariable在PS ISE中运行时可以工作,但通过cmd行运行时却不能工作?

c# - 单独的枚举类?

python - 如何避免将 DbgCommand 命令写入日志文件