У меня проблемы с повреждением стека в новом модуле, над которым я работаю, который является частью большого устаревшего проекта. Мой код написан на C ++ с использованием Borland C ++ Builder 5.0.
Я отследил проблему до следующей функции:
// Note: Class TMarshalServerClientThread has the following objects defined
// CRITICAL_SECTION FCriticalSection;
// std::vector<TMarshalTagInfo*> FTagChangeQueue;
void __fastcall TMarshalServerClientThread::SendChangeNotifications()
{
EnterCriticalSection(FCriticalSection);
try {
if (FTagChangeQueue.size() == 0) {
return;
}
// Process items in change queue
FTagChangeQueue.clear();
} __finally {
LeaveCriticalSection(FCriticalSection);
}
}
Эта функция вызывается в контексте рабочего потока (который происходит от TThread). Другой поток заполняет очередь изменений данными, когда они становятся доступными. Очередь изменений защищена объектом критического раздела.
Когда код запускается, я время от времени получаю нарушения прав доступа при попытке покинуть критическую секцию. Из того, что я могу сказать, иногда, когда __в конце концов раздел введен, стек поврежден. Экземпляр класса в куче в порядке, но указатели на класс (такие как указатель «this») кажутся недействительными.
Если я уберу вызов для возврата, если очередь изменений пуста, проблема исчезнет. Кроме того, код для обработки элементов в очереди не является источником проблемы, так как я могу это закомментировать, и проблема остается.
Поэтому мой вопрос: есть ли известные проблемы при использовании __в конце концов в C ++ Builder 5? Это неправильно называть вернуть изнутри попробуйте __finally блок? Если так, то почему?
Обратите внимание, что я понимаю, что есть разные / лучшие способы сделать то, что я делаю, и я рефакторинг как таковой. Однако я не понимаю, почему этот код должен вызывать повреждение стека.
Как указал @duDE, вы должны использовать пару __пытаться, __в конце концов вместо смешивания C ++ пытаться, и расширение Borland __в конце концов.
Я знаю, что прошло много времени после того, как первоначальный вопрос был опубликован, но как предупреждение для других, я могу ручаться за симптом, о котором сообщает Джонатан Венс. Я испытал это с Builder XE4. Это случается не часто, но кажется, что реализация Borland / Embarcadero попробуй / наконец блоки в многопоточном процессе очень иногда портят стек. Я также использовал критические секции, хотя это может быть совпадением.
Я смог решить мою проблему, отбросив попробуй / наконец. Мне повезло, что я удаляю только экземпляры классов в в конце концов блок, так что я смог заменить попробуй / наконец с объемными скобками, используя станд :: auto_ptr поля для удаления рассматриваемых объектов.