Точки останова из ниоткуда при отладке с помощью gdb, внутри ntdll

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

То, что говорит gdb, это:

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

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

Спасибо заранее!

EDIT: (добавление вывода команды 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 ?? ()

Ответ 1

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

Я только столкнулся с этой проблемой при тестировании на 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 перед запуском приложения.

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

Ответ 2

Ничего себе, ты отправил меня назад на 5 лет, когда я использовал gdb на платформе Linux:)

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

handle SIGTRAP nostop

Но я с steve здесь, попробуйте WinDbg. Он был специально создан для окон.

Ответ 3

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

Ответ 4

Я просто испытал этот сбой с помощью 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