Вопрос
Я новый для Windbg и пытаюсь понять несколько вещей о целевых и реферативных типах .NET. Вот код, который я использую
class Program
{
struct MyStruct
{
int x;
int y;
}
class MyClass
{
int x;
int y;
}
static void Main(string[] args)
{
MyStruct s ;
MyClass c = new MyClass();
Thread.Sleep(5 * 60 * 1000);
}
}
Единственная причина, по которой я вставил сон здесь, - дать мне время прикрепить WINDBG с процессом работы. Я знаю лучший способ сделать это, возможно, поставить точку останова, но в любом случае вот мои вопросы.
- Когда WINDBG привязан к процессу, он ломается в эту тему № 3, но, как я могу видеть, нет нитей с управляемым THEAD ID 3. Является ли этот поток только для отладчика? Есть ли другие потоки, которые могут не отображаться! Threads Command? Если так, есть ли какая-либо команда, которая может дать мне все темы?
0: 003>! Темы --ssecial
ThreadCount: 2.
Unsttttedthread: 0.
Backgrounddread: 1.
PendendedThread: 0.
Deadthread: 0.
Хостел время выполнения: нет
Упреждающий идентификатор блокировки Osid Threadobj State GC GC Alloc Contex Domain Count APT исключение
0 1 BBC 0000000000190C50 200A020 включен 00000000027F3CA8: 00000000027F3FD0 0000000000187E40 0 MTA
2 2 106C 0000000000198430 B220 включен 000000000000000000: 000000000000000000000000000000000000000000000000187E40 0 MTA (финаризатор)
Osid Специальный тип резьбы
1 E98 DBGHELPER
2 106C финализатор
0: 003>! ClrStack
ID Thread OS: 0XE6C (3)
Невозможно пройти управляемый стек. Текущий нить скорее всего не
Управляемая тема. Вы можете запустить! Темы, чтобы получить список управляемых потоков в
процесс
0: 003> КБ
RetAddr: args к ребенку: сайт звонка
0000000077978778 : 00000000
00000000 0000000000000000 00000000
00000000 0000000000000000 : ntdll!DbgBreakPoint
776d466d: 00000000.
0000000000000000 00000000
00000000 0000000000000000 00000000
00000000: ntdll! Dbguiremotebreakin + 0x38
00000000778d8791 : 00000000
00000000 0000000000000000 00000000
00000000 0000000000000000 : KERNEL32!BaseThreadInitThunk+0xd
00000000 : 00000000
0000000000000000 00000000
00000000 0000000000000000 00000000
00000000: ntdll! Rtluserthreadstart + 0x1d
- Тема 0 кажется, что поток работает мой основной метод. Когда я получаю свалку стека объекта, его не показывая mystruct и по какой-то причине, показывая MyClass дважды. Любые идеи почему?
0: 000>! ClrStack
ID поток ОС: 0xbbc (0)
Child-Sp RetAddr звонок сайта
000000000031Edb0 000007fef6b32012 Консолиаположение2.program.main (System.String [])
0: 000>! DumpstackObjects
ID поток ОС: 0xbbc (0)
Имя объекта RSP / REG
000000000031edd8 00000000027F3C90 Консолиаположение2.program + MyClass
000000000031DEE8 00000000027F3C90 Конкресопливание2.program + MyClass
000000000031EE00 00000000027F3C70 System.Object [] (System.String [])
000000000031EF88 00000000027F3C70 System.Object [] (System.String [])
000000000031F170 00000000027F3C70 System.Object [] (System.String [])
000000000031F198 00000000027F3C70 System.Object [] (System.String [])
TIA
Решение
То
!Threads
Команда отображает только управляемые потоки (она будет отказаться от чисто местных потоков).
Чтобы увидеть все ваши темы (оба управляются неуправляемыми), вы могли бы использовать~
. Отказ (Вы можете бросить родные стеки с помощью команды, такой как~*kb
куда*
означает «для каждого потока»]).То
!dso
Команда отображает только ссылочные типы, а иногда он может отображать «ложные срабатывания» или просто неправильные данные (вы обнаружите, что у SOS есть немного Багги природа).
От помощи SOS (!help
):
! Dumpstackobjects. -Подно] [верхний стек [нижний стек]
Эта команда отобразит любые управляемые объекты, которые он находит в пределах текущих стеков. В сочетании с командами трассировки стека, такие как k и! Clrstack, это хорошая помощь для определения значений местных жителей и параметров.
Если вы используете опцию-подтверждение, каждый нестатический класс поле кандидата объекта подтвержден. Это помогает устранить ложные позитивы. Это не по умолчанию, потому что очень часто в сценарии отладки вы заинтересованы в объектах с неверными полями.
Аббревиатура! DSO может быть использован для краткости.
Другие советы
При приложении к запущенному процессу отладчик вводит нить в процесс, и это выбрано как текущий поток. Как лиран указывает на команду SOS !threads
только списки управляемых потоков.
Для простого приложения консоли вы должны ожидать, чтобы увидеть два управляемых потока; Основная поток работает приложение и нить финализатора, который запускается CLR. По моему опыту они всегда пронуты 0 и 2 соответственно.
То !dso
Команда показывает ссылки на стеке. Это не перечисляет типы значений. Для этого вы можете использовать !clrstack
команда с -l
для местных жителей. Имейте в виду, что они будут редко быть размещены на стеке для оптимизированного кода, а на X64 Конвенция о вызовах делает его еще сложнее отслеживать их.