try__finally块内可能存在堆栈损坏
Possible stack corruption inside try __finally block
我正在处理的一个新模块存在堆栈损坏问题,该模块是一个大型遗留项目的一部分。我的代码是使用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是否错误?如果是,为什么?
请注意,我意识到有不同/更好的方法来做我正在做的事情,我正在进行重构。然而,我不明白为什么这些代码会导致堆栈损坏。
@duDE指出,您应该使用__try,__finally对,而不是混合C++try和Borland扩展__ finally
我知道原始问题发布后已经很长时间了,但作为对其他人的警告,我可以保证Jonathan Wiens报告的症状。我在Builder XE4中体验过它。这种情况并不经常发生,但Borland/Enbarcadero在多线程进程中对try/finaly块的实现似乎偶尔会破坏堆栈。我也使用了关键部分,尽管这可能是巧合。
我能够通过放弃try/finaly来解决我的问题。幸运的是,我只删除了finally块中的类实例,所以我能够用scope大括号替换try/finaly,使用std::auto_ptr字段来删除有问题的对象。
- C++模板来检查友元函数的存在
- 既然存在危险,为什么项目要使用-I include开关
- 我们可以访问一个不存在的联盟的成员吗
- C++:对不存在的命名空间使用命名空间指令
- C++quit()函数中可能存在作用域问题
- C++擦除(如果存在)
- g++ 说函数不存在,即使包含正确的标头
- 这个极客对极客的trie实现是否存在内存泄漏问题
- 在功能块中使用新运算符时存在于堆或堆栈上?
- "new"创建的实例的所有成员变量是否都存在于堆上而不是堆栈上?
- std :: vector用作堆栈和std :: stack之间是否存在任何复杂性差异
- 为什么堆栈中的函数局部变量之间存在内存空间
- 在堆栈C++上创建的对象中存在无效数据
- 中止的xbegin事务是否还原xbegin启动时存在的堆栈上下文
- C++更改函数参数时怀疑存在堆栈溢出
- 正在检查堆栈中是否存在元素
- 堆栈中的内存中是否存在性能显著下降的点
- try__finally块内可能存在堆栈损坏
- 存在什么样的堆栈展开库,有什么区别?
- 即使从函数返回,堆栈内存也存在