Родная трассировка стека вызовов Windbg не имеет смысла

У меня есть простая тестовая программа, вызывающая бесконечное ожидание блокировки.

public class SyncBlock
{

}

class Program
{
    public static SyncBlock sync = new SyncBlock();

    private static void ThreadProc()
    {
        try
        {
            Monitor.Enter(sync);


       }
        catch (Exception)
        {
            //Monitor.Exit(sync);
            Console.WriteLine("3rd party code threw an exception");
        }
    }
    static void Main(string[] args)
    {
        Thread newThread = new Thread(ThreadProc);
        newThread.Start();


        Console.WriteLine("Acquiring lock");
        Monitor.Enter(sync);

        Console.WriteLine("Releasing lock");
        Monitor.Exit(sync);

    }
}

Таким образом, основной поток в основном блокируется, когда он пытается выполнить Monitor.Enter(синхронизация). Если я посмотрел на! ClrStack в основном потоке, его вывод в основном показывает, что имеет смысл, но когда я пытаюсь увидеть нативную сторону стека, я ожидаю увидеть некоторое ожидание вызова типа "один / несколько объектов", но не вижу Это. Может кто-нибудь объяснить это. Спасибо

0:000> !CLRStack  

Символ PDB для mscorwks.dll не загружен
Идентификатор потока ОС: 0x1e8 (0)
ESP EIP
0012f0a8 77455e74 [GCFrame: 0012f0a8]
0012f178 77455e74 [HelperMethodFrame_1OBJ: 0012f178] System.Threading.Monitor.Enter(System.Object) 0012f1d0 00a40177 ConsoleApplication1.Program.Main (System.String [])
0012f400 70fc1b4c [GCFrame: 0012f400]
0: 000> кб
ChildEBP RetAddr Args to Child
ВНИМАНИЕ: информация о размотке стека недоступна. Следующие кадры могут быть неправильными.
0012eeb4 710afb92 0012ee68 002d6280 00000000 ntdll! KiFastSystemCallRet
0012ef1c 710af7c3 00000001 002d6280 00000000 mscorwks! StrongNameFreeBuffer + 0x1b1f2
0012ef3c 710af8cc 00000001 002d6280 00000000 mscorwks! StrongNameFreeBuffer + 0x1ae23
0012efc0 710af961 00000001 002d6280 00000000 mscorwks! StrongNameFreeBuffer + 0x1af2c
0012f010 710afae1 00000001 002d6280 00000000 mscorwks! StrongNameFreeBuffer + 0x1afc1
0012f06c 70fdc5ae ffffffff 00000001 00000000 mscorwks! StrongNameFreeBuffer + 0x1b141
0012f080 710df68a ffffffff 00000001 00000000 mscorwks! LogHelp_NoGuiOnAssert + 0x10562
0012f10c 710b1154 002aad90 ffffffff 002aad90 mscorwks! StrongNameFreeBuffer + 0x4acea
0012f128 710b10d8 42b8b47d 00000000 002aad90 mscorwks! StrongNameFreeBuffer + 0x1c7b4
0012f1e0 70fc1b4c 0012f1f0 0012f230 0012f270 mscorwks! StrongNameFreeBuffer + 0x1c738
0012f1f0 70fd2219 0012f2c0 00000000 0012f290 mscorwks + 0x1b4c
0012f270 70fe6591 0012f2c0 00000000 0012f290 mscorwks! LogHelp_NoGuiOnAssert + 0x61cd
0012f3ac 70fe65c4 0023c038 0012f478 0012f444 mscorwks! CoUninitializeEE + 0x2ead
0012f3c8 70fe65e2 0023c038 0012f478 0012f444 mscorwks! CoUninitializeEE + 0x2ee0
0012f3e0 7103389d 0012f444 42b8b0f1 00000000 mscorwks! CoUninitializeEE + 0x2efe
0012f544 710337bd 002332e0 00000001 0012f580 mscorwks! GetPrivateContextsPerfCounters + 0xf546
0012f7ac 71033d0d 00000000 42b8b9c9 00000001 mscorwks! GetPrivateContextsPerfCounters + 0xf466
0012fc7c 71033ef7 00ce0000 00000000 42b8979 mscorwks! GetPrivateContextsPerfCounters + 0xf9b6
0012fccc 71033e27 00ce0000 42b8b8a1 00000000 mscorwks! CorExeMain + 0x168
* ОШИБКА: не удалось найти файл символов. По умолчанию экспортируется символы для C: \ Windows \ Microsoft.NET \ Framework \ v4.0.30319 \ mscoreei.dll - 0012fd14 71cf55ab 71033d8f 0012fd30 71f37f16 mscorwks! CorExeMain + 0x98
* ОШИБКА: не удалось найти файл символов. По умолчанию экспортируется символы для C: \ Windows \ system32 \ mscoree.dll -
0012fd20 71f37f16 00000000 71cf0000 0012fd44 mscoreei! CorExeMain + 0x38
0012fd30 71f34de3 00000000 7723d0e9 7ffd8000 mscoree! CreateConfigStream + 0x13f
0012fd44 774319bb 7ffd8000 084952f9 00000000 mscoree! CorExeMain + 0x8
0012fd84 7743198e 71f34ddb 7ffd8000 00000000 ntdll! RtlInitializeExceptionChain + 0x63
0012fd9c 00000000 71f34ddb 7ffd8000 00000000 ntdll! RtlInitializeExceptionChain + 0x36

1 ответ

Решение

Вы должны указать windbg на сервер символов Microsoft Windows, чтобы получить хорошую трассировку стека.

введите в своем окне команды windbg следующее:

.sympath srv * c: \ websymbols * http: //msdl.microsoft.com/download/symbols

Также посмотрите это:

Использование сервера символов Microsoft для получения символов

Кроме того, чтобы ответить на ваш оригинальный вопрос о том, как отладить это, вот поваренная книга:

0: 000>! Clrstack
Идентификатор потока ОС: 0x1358 (0)
ESP       EIP     
0012f328 7c90e514 [GCFrame: 0012f328] 
0012f3f8 7c90e514 [HelperMethodFrame_1OBJ: 0012f3f8] System.Threading.Monitor.Enter(System.Object)
0012f450 00d10177 Program.Main(System.String[])
0012f688 79e71b4c [GCFrame: 0012f688] 

В вашей оригинальной программе фоновый поток был запущен первым. Итак, он приобрел замок. Однако он вышел без снятия блокировки. После этого ваш основной поток попытался получить блокировку, и он застрял, потому что блокировка уже принадлежит.

Как вы узнаете, кому это принадлежит? Сначала сделайте! Темы, а затем! Syncblk.

0: 000>! Темы
ThreadCount: 3
UnstartedThread: 0
BackgroundThread: 1
PendingThread: 0
DeadThread: 1
Хостинг Runtime: нет
                                      PreEmptive   GC Alloc           Lock
       ID OSID ThreadOBJ Состояние GC Контекст Домен Число Исключение APT
   0    1 1358 0014bb00   200a020 включено 00000000:00000000 001540d0     0 MTA
   2    2 1360 0015e320      b220 включено 00000000:00000000 001540d0     0 MTA (финализатор)
XXXX    3    0 00175a98      9820 Включено 00000000:00000000 001540d0     1 Ukn
0:000>! Syncblk
Индекс SyncBlock MonitorHeld Владелец рекурсии Информация о потоке Владелец SyncBlock
    2 0017903c            3         1 00175a98     0 XXX   013503cc SyncBlock
-----------------------------
Всего 2
Против часовой стрелки 0
RCW             0
ComClassFactory 0
Бесплатно 0

Как видите,! Syncblk говорит, что объект связывающего потока - 00175a98. Из вывода! Threads вы можете видеть, что объект потока 00175a98 является мертвым потоком, который завершил работу, владея блокировкой.

Надеюсь это поможет.

Другие вопросы по тегам