Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net 如何使用SOS和Windbg列出内存转储中的枚举值?_.net_Enums_Windbg_Sos_Sosex - Fatal编程技术网

.net 如何使用SOS和Windbg列出内存转储中的枚举值?

.net 如何使用SOS和Windbg列出内存转储中的枚举值?,.net,enums,windbg,sos,sosex,.net,Enums,Windbg,Sos,Sosex,我有一个小型转储,我已经附加了windbg。迷你转储来自在IIS上运行的.NET 4.6.1 ASP.NET站点。我想得到枚举的定义,但每当我得到类的MethodTable时,我只得到以下内容 0:000> !DumpMT /d 256db60c EEClass: 256c773c Module: 201fcfb0 Name: MyDll.eDefaultRelatedObjects mdToken: 02000029

我有一个小型转储,我已经附加了windbg。迷你转储来自在IIS上运行的.NET 4.6.1 ASP.NET站点。我想得到枚举的定义,但每当我得到类的MethodTable时,我只得到以下内容

0:000> !DumpMT /d 256db60c
EEClass:         256c773c
Module:          201fcfb0
Name:            MyDll.eDefaultRelatedObjects
mdToken:         02000029
File:            C:\Windows\Microsoft.NET\Framework\v4.0.30319\Temporary ASP.NET Files\root\303e164d\216bec4f\assembly\dl3\bdb2a421\004bd941_fee1d501\MyDll.dll
BaseSize:        0xc
ComponentSize:   0x0
Slots in VTable: 23
Number of IFaces in IFaceMap: 3


0:000> !DumpClass /d 256c773c 
Class Name:      MyDll.eDefaultRelatedObjects 
mdToken:         02000029 
File:            C:\Windows\Microsoft.NET\Framework\v4.0.30319\Temporary ASP.NET Files\root\303e164d\216bec4f\assembly\dl3\bdb2a421\004bd941_fee1d501\MyDll.dll 
Parent Class:    717f17cc 
Module:          201fcfb0 
Method Table:    256db60c 
Vtable Slots:    17 
Total Method Slots:  17 
Class Attributes: 101   
Transparency:        Critical 
NumInstanceFields:   1 
NumStaticFields:     0
      MT    Field   Offset                 Type VT     Attr    Value Name 
71c9f54c  400055f      124        System.Char[]  0   shared   static enumSeperatorCharArray
     >> Domain:Value  09671520:NotInit  306d85b0:0d8e822c 306da248:NotInit  306d98c0:NotInit  306dc868:138690b0 << 
71ca0994  400007d        4         System.Int32  1 instance           value__
如何从堆上的对象定义枚举,我需要做什么

编辑1: 如果有什么不同,我可以访问PDB。

先简单点:

0:000> !DumpObj /d 0d8e822c
[...]
Content:     ,    
您在这里所做的是:列出
EnumSeparatorCharray
的值。它与枚举定义无关。所有的枚举都有

SOS IMHO无法列出枚举定义。你需要这样做

以下是调试会话:

0:006> .loadby sos clr
0:006> .load D:\mylongpath\sosex.dll

0:006> !dumpheap -type YourEnum
 Address       MT     Size
02cf2480 01154dc4       12     

Statistics:
      MT    Count    TotalSize Class Name
01154dc4        1           12 DebuggingEnumDefinition.YourEnum
Total 1 objects
所以有一个物体,可以像你那样看它。在输出的最后,您可以看到它的十进制值,即65,这不是很有帮助

0:006> !DumpObj /d 02cf2480
Name:        DebuggingEnumDefinition.YourEnum
[...]
61bf42a8  4000001        4         System.Int32  1 instance       65 value__
用SOSEX“
!mdt
,您可以列出枚举常量:

0:006> !mdt DebuggingEnumDefinition.YourEnum
DebuggingEnumDefinition.YourEnum
    [s]enumSeperatorCharArray: char[]
        AppDomain 'DebuggingEnumDefinition.exe' (00c8dc18): <uninitialized>
    [s]enumSeperator: string
        AppDomain 'DebuggingEnumDefinition.exe' (00c8dc18): <Field def not loaded>
    value__: int
    [s]EnumVal1: DebuggingEnumDefinition.YourEnum
        AppDomain 'DebuggingEnumDefinition.exe' (00c8dc18): <Field def not loaded>
    [s]EnumVal2: DebuggingEnumDefinition.YourEnum
        AppDomain 'DebuggingEnumDefinition.exe' (00c8dc18): <Field def not loaded>
    [s]EnumVal3: DebuggingEnumDefinition.YourEnum
        AppDomain 'DebuggingEnumDefinition.exe' (00c8dc18): <Field def not loaded>

通过更改进程内存,您可能会生成枚举值的映射

以下内容将生成从0到127的循环:

.for (r $t0=0; @$t0<0n128; r $t0 = @$t0+1) { }
接下来,您可以使用
!mdt
分析修改后的值

!mdt 03402470
完整的命令是

.for (r $t0=0; @$t0<0n128; r $t0 = @$t0+1) { ed 03402470+4 @$t0; !mdt 03402470}
接下来,您可能需要仅过滤有效案例。注意,我们可以通过包含
)(
)来区分有效条目和无效条目

这就是WinDbg中的脚本有点难看的地方

.echo Just a test
显示一些东西来显示原理

.shell -ci ".echo Just a test" findstr "Just"
使用DOS命令
findstr
筛选包含特定单词的行

接下来,使用前面的完整命令替换
.echo
,并将“Just”替换为
)(
。因为
findstr
也是一个奇怪的程序,所以您实际上需要
)。(
因为它会将其视为两个单独的搜索词

.shell -ci ".for (r $t0=0; @$t0<0n128; r $t0 = @$t0+1) { ed 03402470+4 @$t0; !mdt 03402470}" findstr ").("
真是一次冒险


我使用的源代码,以防万一

using System;
using System.Collections;

namespace DebuggingEnumDefinition
{
    class Program
    {
        static void Main()
        {
            var somwehere = new ArrayList() { YourEnum.EnumVal3 };
            Console.WriteLine("There should be an enum on the heap now.");
            Console.ReadLine();
            Console.WriteLine(somwehere[0]); // Just fix the unused variable issue
        }
    }

    enum YourEnum
    {
        EnumVal1,
        EnumVal2,
        EnumVal3=65
    }
}
.echo Just a test
.shell -ci ".echo Just a test" findstr "Just"
.shell -ci ".for (r $t0=0; @$t0<0n128; r $t0 = @$t0+1) { ed 03402470+4 @$t0; !mdt 03402470}" findstr ").("
0x0 (EnumVal1) (DebuggingEnumDefinition.YourEnum)
0x1 (EnumVal2) (DebuggingEnumDefinition.YourEnum)
0x41 (EnumVal3) (DebuggingEnumDefinition.YourEnum)
.shell: Process exited
using System;
using System.Collections;

namespace DebuggingEnumDefinition
{
    class Program
    {
        static void Main()
        {
            var somwehere = new ArrayList() { YourEnum.EnumVal3 };
            Console.WriteLine("There should be an enum on the heap now.");
            Console.ReadLine();
            Console.WriteLine(somwehere[0]); // Just fix the unused variable issue
        }
    }

    enum YourEnum
    {
        EnumVal1,
        EnumVal2,
        EnumVal3=65
    }
}