Могу ли я получить следы стека всех потоков в моем приложении c #? - PullRequest
22 голосов
/ 27 апреля 2010

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

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

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

Ответы [ 3 ]

6 голосов
/ 27 апреля 2010

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

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

5 голосов
/ 28 августа 2010

Я предлагаю снять дамп процесса при возникновении исключения. В том же месте, где вы регистрируете исключение, вызовите метод 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.");
    }

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

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

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

~ * e! Clrstack

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

1 голос
/ 27 апреля 2010

Я не пробовал это сам, но это может быть полезно http://www.debuginspector.com/

...