Точки останова из ниоткуда при отладке с помощью gdb, внутри ntdll - PullRequest
10 голосов
/ 25 октября 2009

Я сделал очень простую программу, которая автоматизирует некоторые вещи для меня. Я написал ее на c ++, и она работает на Windows. Отлаживая его с помощью GDB из IDE Codeblocks, я получаю множество точек останова из ниоткуда. Я понятия не имею, что может быть причиной этой проблемы. Кажется, что точки останова связаны с проблемами с памятью ... поскольку, когда я исправил обнаруженную утечку памяти, число точек останова значительно уменьшилось.

Точно, что GDB говорит мне:

 Program received signal SIGTRAP, Trace/breakpoint trap.
 In ntdll!TpWaitForAlpcCompletion () (C:\Windows\system32\ntdll.dll)

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

Заранее спасибо!

РЕДАКТИРОВАТЬ: (Добавление выходных данных команды GDB where): Где я могу проверить, что делает каждая из этих функций, чтобы я мог видеть, что я делаю неправильно?

#0  0x76fefadd in ntdll!TpWaitForAlpcCompletion () from C:\Windows\system32\ntdll.dll
#1  0x0028e894 in ?? ()
#2  0x76fb272c in ntdll!RtlCreateUserStack () from C:\Windows\system32\ntdll.dll
#3  0x00657fb8 in ?? ()
#4  0x00657fb8 in ?? ()
#5  0x76f4b76a in ntdll!RtlDowncaseUnicodeChar () from C:\Windows\system32\ntdll.dll
#6  0x02070005 in ?? ()
#7  0x00000b10 in ?? ()
#8  0x0028e8dc in ?? ()
#9  0x76ff0b37 in ntdll!TpQueryPoolStackInformation () from C:\Windows\system32\ntdll.dll
#10 0x038b0000 in ?? ()
#11 0x00657fb8 in ?? ()
#12 0x76f4b76a in ntdll!RtlDowncaseUnicodeChar () from C:\Windows\system32\ntdll.dll
#13 0x6e6e9a5e in ?? ()
#14 0x038b0000 in ?? ()
#15 0x038b0000 in ?? ()
#16 0x00000000 in ?? ()

Ответы [ 4 ]

16 голосов
/ 24 ноября 2011

Хотя вопрос сейчас довольно старый, вот некоторые моменты, которые могут помочь кому-то, кто придет сюда после поиска, как я сделал:

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

Короче говоря, в коде приложения был заблокирован блок памяти, ошибочно (вместо использования GlobalAlloc()) и был освобожден с помощью GlobalFree() (что неверно, так как к системной куче обращались с помощью указатель из пула памяти времени выполнения C). Хотя это вызывает (очень небольшую в этом случае) утечку памяти, она была совершенно незаметна при тестировании на WinXP, и вся программа работала, по-видимому, правильно.

Теперь при запуске в Win7 функция мониторинга памяти под названием Fault Tolerant Heap (FTH) обнаруживает эту ошибку приложения (которая вызывает исключение):

  • В то же время он выводит некоторую информацию через OutputDebugString() (или, может быть, DbgPrint()), которую можно просмотреть с помощью простого инструмента DebugView или любого отладчика при трассировке приложения. , Таким образом, прямо перед полученным сигналом вы можете увидеть что-то подобное в сообщениях:

    предупреждение: HEAP [name_of_your.exe]:

    предупреждение: недопустимый адрес, указанный для RtlFreeHeap (006B0000, 006A3698)

  • И (в случае отладки приложения) он выводит точку останова, которая не оказывает влияния вне отладчика, но в противном случае это должно помочь выявить проблему. Эта точка останова отображается как сигнал SIGTRAP с помощью GDB .

На данный момент у вас есть 2 варианта:

  • попробуйте пройтись по стеку вызовов, чтобы найти неверную инструкцию в вашем коде (к сожалению, в этом случае команды bt или where gdb не могут показать достаточно далеко, чтобы увидеть, где в моем коде куча была ошибочно освобождена - если кто-то знает, как отобразить правильный стек вызовов из стартового модуля вместо ntdll, дайте мне знать )
  • попытаться продолжить, так как FTH имеет возможность автоматически исправлять память, пытаясь обойти вашу ошибку (это автоматическое исправление также может произойти заранее при следующем запуске приложения)

Чтобы не останавливаться во время проблемы с кучей, как сказал Моше Леви, вы можете установить handle SIGTRAP nostop в приглашении GDB перед запуском приложения.

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

7 голосов
/ 07 ноября 2009

Ух ты, ты отправил меня на 5 лет назад, когда я использовал gdb на платформе linux

вы можете предотвратить разрыв GDB при получении SIGTRAP с помощью следующей команды:

handle SIGTRAP nostop

Но я со Стивом, попробуйте вместо этого WinDbg. Он был построен специально для окон.

2 голосов
/ 26 октября 2009

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

1 голос
/ 19 июня 2013

Я только что испытал этот сбой, используя gcc / mingw с Qt Creator.

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

У меня было это:

#pragma pack(1)
typedef struct SomeStruct
{
... // structure
} SomeStruct;

... но я не завершил его вызовом pragma pack () для завершения упаковки 1 после структуры и возврата к выравниванию / упаковке байтов по умолчанию. Добавим что исправили это:

#pragma pack(1)
typedef struct SomeStruct
{
... // structure
} SomeStruct;
#pragma pack() // <<-- with this line the heap corruption problem was stopped
...