1

我正在处理的新模块中存在堆栈损坏问题,该模块是大型遗留项目的一部分。我的代码是使用 Borland C++Builder 5.0 用 C++ 编写的。

我已将问题跟踪到以下功能:

// 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 派生)的上下文中调用。当数据可用时,另一个线程会用数据填充更改队列。更改队列受临界区对象保护。

运行代码时,我在尝试离开临界区时偶尔会遇到访问冲突。据我所知,有时当进入__finally部分时,堆栈已损坏。堆上的类实例很好,但指向类的指针(例如“this”指针)似乎无效。

如果我在更改队列为空的情况下删除返回调用,问题就会消失。此外,处理队列中项目的代码不是问题的根源,因为我可以将其注释掉,问题仍然存在。

所以我的问题是在 C++Builder 5 中使用__finally时是否存在已知问题?从try __finally块中调用return是否错误?如果是这样,为什么?

请注意,我意识到有不同/更好的方法来做我正在做的事情,我正在重构。但是,我不明白为什么这些代码会导致堆栈损坏。

4

2 回答 2

1

正如@duDE 指出的那样,您应该使用一对__ try 、 _ _finally而不是混合 C++ try和 Borland 扩展__finally

于 2013-06-28T14:26:37.993 回答
1

I know it is a long time after the original question was posted, but as a warning to others, I can vouch for the symptom that Jonathan Wiens is reporting. I experienced it with Builder XE4. It does not happen frequently, but it seems that Borland/Embarcadero's implementation of try / finally blocks in a multi-threaded process very occasionally corrupts the stack. I was also using critical sections, although that may be coincidental.

I was able to resolve my problem by discarding the try / finally. I was fortunate that I was only deleting class instances in the finally block, so I was able to replace the try / finally with scope braces, using std::auto_ptr fields to delete the objects in question.

于 2017-05-30T07:24:09.423 回答