Сначала простые вещи:
0:000> !DumpObj /d 0d8e822c
[...]
Content: ,
Что вы сделали здесь: перечислите значения enumSeperatorCharArray
. Это не относится к вашему определению перечисления. Все перечисления имеют его.
SOS ИМХО не может перечислить определения перечислений. Для этого вам нужно sosex .
Вот сеанс отладки:
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>
На самом деле я ожидал и числовые значения.
Вы также можете использовать !mdt
с адресом объекта, чтобы получить его постоянное и шестнадцатеричное значение (0x41 == 65):
0:006> !mdt 02cf2480
0x41 (EnumVal3) (DebuggingEnumDefinition.YourEnum)
Изменяя память процесса, вы, вероятно, можете сгенерировать отображение значений перечисления.
Следующее генерирует al oop от 0 до 127:
.for (r $t0=0; @$t0<0n128; r $t0 = @$t0+1) { }
Внутри l oop вы можете изменить значение перечисления (я забыл, зависит ли +4 от битности):
ed 03402470+4 @$t0
Далее, вы можете использовать !mdt
для анализа измененного значения
!mdt 03402470
Полная команда:
.for (r $t0=0; @$t0<0n128; r $t0 = @$t0+1) { ed 03402470+4 @$t0; !mdt 03402470}
, и результат будет выглядеть как
0x0 (EnumVal1) (DebuggingEnumDefinition.YourEnum)
0x1 (EnumVal2) (DebuggingEnumDefinition.YourEnum)
0x2 (DebuggingEnumDefinition.YourEnum)
0x3 (DebuggingEnumDefinition.YourEnum)
[...]
0x7f (DebuggingEnumDefinition.YourEnum)
Далее, вы, вероятно, будете фильтровать только допустимые случаи. Обратите внимание, что мы можем отличить guish допустимых записей от недействительных, если в них содержится ) (
.
. Здесь сценарии в WinDbg немного уродливы ...
.echo Just a test
отображает что-то, чтобы показать принцип.
.shell -ci ".echo Just a test" findstr "Just"
использует команду DOS findstr
для фильтрации строк, содержащих определенное c слово.
Затем замените .echo
на полную команду, указанную ранее, и замените «Just» на ) (
. Поскольку findstr
также является странной программой, вам на самом деле нужен ).(
, потому что в противном случае он будет обрабатывать его как два отдельных условия поиска.
.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
}
}