Возможно повреждение стека внутри блока try __finally

У меня проблемы с повреждением стека в новом модуле, над которым я работаю, который является частью большого устаревшего проекта. Мой код написан на 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 блок? Если так, то почему?

Обратите внимание, что я понимаю, что есть разные / лучшие способы сделать то, что я делаю, и я рефакторинг как таковой. Однако я не понимаю, почему этот код должен вызывать повреждение стека.

1

Решение

Как указал @duDE, вы должны использовать пару __пытаться, __в конце концов вместо смешивания C ++ пытаться, и расширение Borland __в конце концов.

1

Другие решения

Я знаю, что прошло много времени после того, как первоначальный вопрос был опубликован, но как предупреждение для других, я могу ручаться за симптом, о котором сообщает Джонатан Венс. Я испытал это с Builder XE4. Это случается не часто, но кажется, что реализация Borland / Embarcadero попробуй / наконец блоки в многопоточном процессе очень иногда портят стек. Я также использовал критические секции, хотя это может быть совпадением.

Я смог решить мою проблему, отбросив попробуй / наконец. Мне повезло, что я удаляю только экземпляры классов в в конце концов блок, так что я смог заменить попробуй / наконец с объемными скобками, используя станд :: auto_ptr поля для удаления рассматриваемых объектов.

1