Подтвердить что ты не робот

Могу ли я получить трассировку стека всех потоков в моем приложении С#?

Я отлаживаю очевидную проблему concurrency в довольно большом приложении, которое я запускаю на работе. Ошибка, о которой идет речь, проявляется только на некоторых более низких машинах после запуска в течение многих (12+) часов, и я никогда не воспроизводил ее в отладчике. Из-за этого мои инструменты отладки в основном ограничены анализом файлов журнала.

С# позволяет легко получить трассировку стека потока, генерирующего исключение, но я хотел бы дополнительно получить трассировки стека из всех остальных потоков, выполняемых в моем AppDomain в момент исключения исключения.

Возможно ли это?

4b9b3361

Ответ 1

В CodePlex есть инструмент, называемый Managed Stack Explorer (который, как я полагаю, возник из Microsoft). Он использует API отладки и профилирования для захвата трассировок стека потоков в запущенном приложении .Net без необходимости изменения приложения.

Вы можете запустить приложение до тех пор, пока не возникнет проблема, а затем проанализируйте его с помощью этого инструмента, чтобы захватить текущие стеки стека всех запущенных потоков. Преимущество такого подхода заключается в том, что вы оставляете приложение неизменным (инструмент может изменить его поведение), и инструмент свободен.

Ответ 2

Я предлагаю взять дамп процесса, когда возникает исключение. В том же месте, где вы регистрируете вызов исключения, метод MakeDumpFile(), как показано ниже.

Предполагается, что на проблемной машине установлено "Средства отладки для Windows" .

private static void MakeDumpFile()
    {            
        int pid = Process.GetCurrentProcess().Id;
        Console.WriteLine("Creating dump for pid " + pid);

        //path to adplus executable; ensure you have Debugging tools installed;
        string program = @"C:\Program Files (x86)\Debugging Tools for Windows (x86)\adplus.exe";

        //args for adplus; ensure the crashdump folder exists!
        string args = string.Format(@"-hang -p {0} -o c:\crashdump", pid);

        var startInfo = new ProcessStartInfo(program, args);
        startInfo.UseShellExecute = false;
        startInfo.ErrorDialog = false;
        startInfo.CreateNoWindow = true;
        startInfo.RedirectStandardOutput = true;

        var process = Process.Start(startInfo);
        Console.WriteLine("The following is output from adplus");
        Console.WriteLine(process.StandardOutput.ReadToEnd());
        Console.WriteLine("Finished creating dump.");
    }

Перейдите в каталог dump, и вы увидите новую папку с файлом в ней с именем FULLDUMP_something_.dmp.

Если вы находитесь на .NET4, вы можете просто перетащить его в VS2010 и проверить все потоки или использовать параллельные потоки, чтобы увидеть, что происходит (это потрясающе!)

Если на NET3.5 или ранее вам нужно будет использовать windbg для анализа. Используйте следующую команду

~ * e! clrstack

чтобы напечатать столбец всех управляемых потоков. Если вам нужна дополнительная помощь, чтобы получить windbg для отправки назад или google для учебника.