Почему минидампы только иногда имеют стеки вызовов для одного и того же процесса?
Недавно у нас было зависание в производстве. Я использовал ProcessExplorer для его отладки, сохранил мини-дамп в cdb и проанализировал его в VS2015. Я мог видеть стек вызовов clr в главном потоке с символами из нашего кода.
Желая узнать немного больше, я создал простую программу, которая зависает (с небольшим количеством стеков вызовов) следующим образом (встроенный в Release, с исходным кодом, перемещенным после сборки):
public class Program
{
public static void Main(string[] args)
{
new Program().Run();
}
public void Run()
{
DoThing();
}
public void DoThing()
{
Task t = new Task(() =>
{
while (true)
{
}
}
);
t.RunSynchronously();
}
}
Впоследствии я создал файлы дампа тремя способами:
- через диспетчер задач
- присоединение с помощью cdb и.dump /ma
- присоединение к VS2015, взлом и сохранение файла дампа
Все свалки очень похожи по размеру. Когда я открываю их в новом сеансе VS2015, только последний метод показывает мне стек вызовов clr для основного потока. Почему это? Я не вижу стек вызовов в тот момент, когда я сохраняю дамп в VS, но я вижу, когда я заново открываю файл дампа.
Как я могу гарантировать, что я вижу стек вызовов clr при создании дампа в производстве (когда VS недоступен). Кроме того, почему я получил стек вызовов clr, когда впервые создал файл дампа в рабочей среде, используя ProcessExplorer и cdb?
ОБНОВИТЬ:
Я проверил строки в файлах дампа, и все они содержат следующие значения:
DoThing
DoThing> b__2_0
Моя проблема заключается в том, что мини-дампы, созданные диспетчером задач или cdb, имеют стеки основных потоков, такие как:
ntdll.dll!778214d1()
[Frames below may be incorrect and/or missing, no symbols loaded for ntdll.dll]
mscorlib.ni.dll!7279bbc0()
Принимая во внимание, что созданные Visual Studio имеют стеки основных потоков, такие как:
DumpDiag.exe!DumpDiag.Program.DoThing.AnonymousMethod__2_0()
mscorlib.dll!System.Threading.Tasks.Task.InnerInvoke()
mscorlib.dll!System.Threading.Tasks.Task.Execute()
1 ответ
Это произошло потому, что мой процесс.net был 32-разрядным, но мини-дампы, которые я записал с помощью cdb и диспетчера задач, были 64-разрядными. Я неправильно использовал x64-версию cdb и (по умолчанию) 64-битный диспетчер задач, который захватывает 64-битный дамп.
Я создал отдельные 32- и 64-битные версии процесса тестирования, описанного выше, и записал мини-дампы с соответствующей версией cdb, соответствующей версией диспетчера задач и путем подключения к Visual Studio. После этого все дампы правильно отображали стек вызовов clr.
Подробнее здесь: https://blogs.msdn.microsoft.com/tess/2010/09/29/capturing-memory-dumps-for-32-bit-processes-on-an-x64-machine/