переполнение стека отладки в Windows? - PullRequest
5 голосов
/ 02 апреля 2009

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

В отладчике VS (2005) я нажимаю «Разбить все» и осматриваю стеки вызовов потоков загадочно исчезающего процесса, когда вижу следующее:

пахнет как SO http://img6.imageshack.us/img6/7628/95434880.jpg

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

Проблема в том, что стек вызовов отладчика VS показывает только то, что вы видите на изображении.

Итак, мой вопрос: как я могу найти, где начинается бесконечный рекурсивный вызов?

Я прочитал где-то , что в Linux вы можете прикрепить обратный вызов к обработчику SIGSEGV и получить больше информации о том, что происходит.

Есть ли что-нибудь похожее в Windows?

Ответы [ 5 ]

3 голосов
/ 02 апреля 2009

Ну, вы знаете, в каком потоке проблема - это может быть простой вопрос проследить ее с самого начала, чтобы увидеть, куда она уходит в сорняки.

Другой вариант - использовать один из отладчиков в пакете Средства отладки для Windows - они могут показать больше, чем отладчик VS (возможно), даже если они, как правило, более сложные и трудные. использовать (на самом деле может быть из-за этого).

3 голосов
/ 02 апреля 2009

Чтобы контролировать, что Windows делает в случае нарушения доступа (SIGSEGV -эквивалент), вызовите SetErrorMode (передайте ему параметр 0, чтобы вызвать всплывающее окно в случае ошибки, позволяющие подключиться к нему с помощью отладчика.)

Однако, исходя из уже полученной трассировки стека, подключение к отладчику по ошибке может не дать никакой дополнительной информации . Либо ваш стек поврежден, либо глубина рекурсии превысила максимальное количество кадров, отображаемых VS. В последнем случае вы можете захотеть уменьшить размер стека по умолчанию для процесса (используйте переключатель /F или эквивалентный параметр в свойствах проекта), чтобы решить проблему проявить себя раньше, и убедитесь, что VS будет отображать все кадры. В качестве альтернативы вы можете добавить точку останова в std :: basic_filebuf <> :: flush () и проходить через нее до фазы уничтожения (или отключить ее только до фазы уничтожения).

1 голос
/ 02 апреля 2009

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

Либо вы просто делаете шаг вперед и видите, каких деструкторов вызывают и когда они попадают в ловушку. Или вы можете поместить printf / OutputDebugString в каждый соответствующий деструктор объектов (это нужно ТОЛЬКО для глобальных объектов). Если сообщение - это первое, что делает деструктор, то последнее сообщение, которое вы видите, - от деструктора, который вешает трубку.

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

0 голосов
/ 04 апреля 2009

Я согласен с Дэном Бреслау. Ваш стек поддельный. может быть, просто потому, что у вас нет правильных символов, хотя. Если программа просто исчезает без включения обработки WER, это обычно нехватка памяти. Вы исследовали эту возможность?

0 голосов
/ 02 апреля 2009

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

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

Попробуйте добавить Sleep() вызовов в выбранные функции в вашем источнике, которые могут быть вовлечены в рекурсию. Это даст вам больше шансов взломать процесс до полного переполнения стека.

...