После «все» в Visual Studio 2010 в моей программе на C ++ в большинстве стеков вызовов некоторых потоков нет - PullRequest
2 голосов
/ 10 января 2012

В последней редакции моего кроссплатформенного приложения C ++ (с использованием Juce) есть, вероятно, тупик или, по-видимому, неограниченный цикл в Windows, но не в Mac, и, к сожалению, в настоящее время у нас нет разработчика Windows, так что мне решать.

Я могу запустить программу под Visual Studio 2010 с проблемами, а затем, когда я нажимаю «потеря жизнеспособности»: -DI использую команду «Разбить все», которая, кажется, приостанавливает все мои потоки.Хорошо и хорошо, и большинство стеков вполне разумно.К сожалению, некоторые из потоков, в том числе два, которые, как я подозреваю, находятся в тупике, не имеют пригодных стеков вызовов.

Я прекрасно понимаю, что «вершин» моих стеков не будет, потому чтоУ меня нет отладочной информации, например, ntdll.dll.Но мне кажется, что я получаю немного от середины стека.

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

Этот кадр является допустимым, но я не знаю, почемуЯ не могу видеть другие кадры, и это делает мою работу очень трудной.

Любые идеи будут оценены - надеюсь, ваш день был более продуктивным, чем мой!: -D

РЕДАКТИРОВАТЬ: Извините, подумал, что я был очень ясно выше, когда я указал, что я знал, что символы Microsoft отсутствовали, но все равно.Проблема в том, что в трассировке стека отсутствуют все кадры в моем коде , где я уверен, что у меня есть символы отладки.

Я фактически преодолел тупик, так что это не проблемапрямо сейчас, но это делает эффект еще более загадочным, так как теперь я знаю, что я, например, как-то не испортил стек вызовов.

Теперь у меня есть еще немного информации для «следующего парня» -Дело в том, что я вызывал функцию из окна верхнего уровня из потока, а не из потока Windows.(Это кроссплатформенное приложение, и на Mac его не волнует, из какого потока вы их вызываете.) Именно это и стало причиной «тупика» (на самом деле, я не думаю, что это был действительно тупик, но некоторые другие «потери жизнеспособности»), и мне интересно, не из-за этой ли проблемы Visual Studio 2010 отказалась правильно отображать стек.

- плохой стек -

ntdll.dll!7c90e514()
[Frames below may be incorrect and/or missing, no symbols loaded for ntdll.dll]
user32.dll!7e4299ff()

SlowGold 8 (отладочная сборка) .exe! Juce :: Win32ComponentPeer :: setPosition (int x, int y) Строка 513 C ++ SlowGold 8 (отладочная сборка) .exe! 008005f9 ()

РЕДАКТИРОВАТЬ: Да, я видел тот факт, что "ntdll.dll не было загружено никаких символов", но это не проблема: проблема в том, что в ОДНОМ кадрестек.В следующем стеке приведен пример «хорошего стека» из другого потока в той же программе.

- хороший стек -

ntdll.dll!7c90e514()
[Frames below may be incorrect and/or missing, no symbols loaded for ntdll.dll]
ntdll.dll!7c90df5a()
kernel32.dll!7c8025db()
kernel32.dll!7c802542()
SlowGold 8 (debug build).exe!juce::WaitableEvent::wait(const int timeOutMillisecs)  Line 103 + 0x10 bytes   C++
SlowGold 8 (debug build).exe!juce::Thread::wait(const int timeOutMilliseconds)  Line 304    C++
SlowGold 8 (debug build).exe!rec::util::thread::Looper<int (__cdecl*)(rec::slow::Instance *),rec::slow::Instance *>::run()  Line 24 C++
SlowGold 8 (debug build).exe!juce::Thread::threadEntryPoint()  Line 145 C++
SlowGold 8 (debug build).exe!juce::juce_threadEntryPoint(void * userData)  Line 156 C++
SlowGold 8 (debug build).exe!juce::threadEntryProc(void * userData)  Line 126 + 0x9 bytes   C++
SlowGold 8 (debug build).exe!_callthreadstartex()  Line 314 + 0xf bytes C
SlowGold 8 (debug build).exe!_threadstartex(void * ptd)  Line 297   C

kernel32.dll! 7c80b729 ()

РЕДАКТИРОВАТЬ: вы можете видеть здесь, что, хотя у меня нет полного стека, у меня есть много кадров из моего собственногокод - вы можете видеть, куда мы входим в начало потока и куда мы обращаемся к DLL-библиотекам Microsoft.

Ответы [ 4 ]

2 голосов
/ 10 января 2012

Звучит так, как будто у вас пропущены символы (так как не все даны), однако Microsoft распространяет большую часть, а не все символы, на своем сервере символов.

Примечание: мне никогда не приходилось это делать. В любом случае, посмотрите на сервер символов Microsoft, чтобы выяснить, как это сделать здесь: http://support.microsoft.com/kb/311503.

1 голос
/ 10 января 2012

Вам нужны символы отладки для системных .dll для правильного обхода стека. Даже если вам случится получить, казалось бы, правильные записи в стеке вызовов, у вас все равно могут быть ошибочные стек вызовов, если в самом стеке есть устаревшие данные (например, старые указатели возврата).

Поскольку вы используете VS 2010, вы сможете щелкнуть правой кнопкой мыши любую системную библиотеку DLL в стеке вызовов и загрузить символы непосредственно с сервера Microsoft Symbol Server. Вы также можете перейти в Сервис -> Параметры -> Отладка -> Символы, чтобы отладчик делал это автоматически.

Вы всегда должны использовать системные символы .dll, когда можете.

0 голосов
/ 25 ноября 2013

Это немного поздно для ответа, но у меня была похожая проблема, на которую мне потребовалось некоторое время, чтобы отследить, и, как и в случае с OP, я не смог найти ничего на SO или Google в целом, что решило бы проблему. Я отвечаю здесь, потому что сценарий в этом вопросе очень похож на мой, поэтому Google, вероятно, найдет вопрос для других.

С моей проблемой у нас был один ПК с полной трассировкой стека и один с неполной трассировкой стека. Я нашел решение использовать окно модулей Visual Studio ( Меню отладки | Windows | Модули ). Это окно сообщает вам, какие модули загружены и, что важно, какие модули имеют загруженные символы. В моем случае на обе машины были загружены символы для DLL с неполным стеком, но критически важно, чтобы на одной машине была загружена DLL времени выполнения без загруженных символов, как на другой. Для меня это был исполняемый файл Visual C ++ Msvr110.dll. После того, как правильный файл символов был обнаружен для этой библиотеки DLL, трассировка полного стека была отправлена ​​правильно.

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

Надеюсь, это сэкономит время другим.

0 голосов
/ 10 января 2012

2 вещи:

1) «Очистить» решение, затем собрать и запустить в режиме отладки (убедитесь, что выбрано Начать отладку (F5), а не «Запуск без отладки» (то есть CTRL + F5)

2) Ну, это функции Windows API - вы уверены для плохого стека, который нужно отлаживать на этом уровне? «Плохой стек» входит в user32.dll, который является стороной Windows с графическим интерфейсом. Я не думаю, что вам нужно для отладки этих стеков, но я не уверен.

...