Точки останова из ниоткуда при отладке с помощью gdb внутри ntdll
Вопрос
Я создал очень простую программу, которая автоматизирует некоторые вещи для меня.Я написал ее на c ++, и она работает в Windows.При отладке с помощью GDB внутри IDE Codeblocks я получаю множество точек останова из ниоткуда.Я понятия не имею, что может быть причиной этой проблемы.Точки останова , по - видимому , связаны с проблемами с памятью ...с тех пор, как я исправил обнаруженную мной утечку памяти, количество точек останова значительно сократилось.
Точная вещь, о которой мне сообщает gdb, это:
Program received signal SIGTRAP, Trace/breakpoint trap.
In ntdll!TpWaitForAlpcCompletion () (C:\Windows\system32\ntdll.dll)
Я получаю это много-много раз внутри своей программы.Я думаю, что, возможно, я делаю что-то очень неправильное, хотя программа, кажется, работает просто отлично и выполняет то, что я от нее хочу.Кто-нибудь может сказать мне, в чем проблема, поскольку я не знаю, где искать?Кроме того, если это не проблема, то кто-нибудь знает, как отключить это, поскольку это мешает мне добраться до точек останова, которые я установил сам?
Заранее спасибо!
Редактировать:(Добавление выходных данных команды where из GDB):Где я могу проверить, что делает каждая из этих функций, чтобы я мог видеть, что я делаю неправильно?
#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 ?? ()
Решение
Хотя вопрос уже довольно старый, вот несколько моментов, которые могли бы помочь кому-то, кто пришел бы сюда после поиска, подобного тому, что сделал я:
Я только что столкнулся с этой проблемой во время тестирования на Win7 приложения, разработанного мной на WinXP.В моем случае это связано как с мониторингом управления памятью Windows 7, так и с плохим выделением памяти в моем приложении.
Короче говоря, в коде приложения блок памяти, который был удален по ошибке (вместо использования GlobalAlloc()
) и был освобожден с помощью GlobalFree()
(что неверно, поскольку доступ к системной куче осуществлялся с помощью указателя из пула памяти среды выполнения C).Хотя это вызывает (в данном случае очень небольшую) утечку памяти, это было совершенно незамечено во время тестирования на WinXP, и вся программа работала, по-видимому, корректно.
Теперь при запуске в Win7 функция мониторинга памяти вызывается Отказоустойчивая Куча (ПЯТЫЙ) обнаруживает эту ошибку в приложении (которая вызывает исключение) :
В то же время он выводит некоторую информацию через
OutputDebugString()
(или, может бытьDbgPrint()
), которые можно просмотреть с помощью простого Отладочный просмотр инструментом или любым отладчиком при трассировке приложения.Таким образом, непосредственно перед полученным сигналом вы можете увидеть что-то подобное в сообщениях :предупреждение:КУЧА[name_of_your.exe]:
предупреждение:Недопустимый адрес, указанный в RtlFreeHeap( 006B0000, 006A3698)
И (в случае, если приложение отлаживается) оно выводит точку останова, которая не имеет никакого эффекта вне отладчика, но в остальном это должно помочь указать на проблему. Эта точка останова отображается GDB в виде сигнала SIGTRAP.
На данный момент у вас есть 2 альтернативы :
- попробуйте обойти стек вызовов, чтобы найти ошибочную инструкцию в вашем коде (к сожалению, в этом случае
bt
илиwhere
команды gdb не могут показать достаточно далеко, чтобы увидеть, где в моем коде куча была ошибочно освобождена - если кто-то знает, как отобразить правильный стек вызовов из начального модуля вместо ntdll, дайте мне знать) - попробуйте продолжить, поскольку FTH имеет возможность автоматического исправления в памяти в качестве попытки обойти вашу ошибку (это автоматическое исправление также может произойти заранее при следующем запуске приложения)
Чтобы не останавливаться во время проблемы с кучей, как сказал Моше Леви, вы можете установить handle SIGTRAP nostop
в приглашении GDB перед запуском приложения.
Итак, вкратце :да, у вас действительно было что-то не так в вашем коде относительно управления памятью, но в некоторых случаях он может работать без сбоев.Но в режиме отладки ядро пытается направить вас на путь решения проблемы.
Другие советы
Ух ты, ты отправил меня обратно на 5 лет назад, когда я использовал gdb на платформе Linux:)
вы можете предотвратить разрыв gdb при получении SIGTRAP с помощью следующей команды:
handle SIGTRAP nostop
Но я со Стивом, попробуйте вместо этого WinDbg. Он был построен специально для окон.
Я бы рекомендовал использовать WinDBG, собственный отладчик Windows. Это даст лучшие трассировки стека, особенно для символов, когда он перейдет в режим ядра.
Я только что испытал это падение, используя 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