C STL映射中的SegFault由于过程退出期间的静态可变清理而找到
Segfault in c++ stl map find due to static variable cleanup during process exit
i在以下功能中在stl映射上进行操作,所有这些功能都受穆特克斯的保护: -
static std::mutex track_active_lock_mtx;
typedef intrusive_ptr<WatchCtxInternal> WatchCtxInternal_h;
static std::map<WatchCtxInternal*, WatchCtxInternal_h> actives;
void* get_ptr(WatchCtxInternal_h ctx)
{
unique_lock<mutex> trackActiveLock(track_active_lock_mtx);
if(actives.find(ctx.get()) == actives.end()) {
actives.insert(make_pair(ctx.get(), ctx));
}
trackActiveLock.unlock();
return ctx.get();
}
void genericWatcher(void *watcherCtx)
{
unique_lock<mutex> trackActiveLock(track_active_lock_mtx);
auto it = actives.find((WatchCtxInternal*)watcherCtx);
if (it == actives.end()) {
return;
}
//do unrelated stuff
actives.erase(it);
}
我在第一个功能中有分割故障: -
Program terminated with signal SIGSEGV, Segmentation fault.
#0 _M_lower_bound (this=<optimized out>, __k=<optimized out>, __y=0xf31256e8, __x=0x65687465) at /volume/evo/files/opt/poky/1.8.2-4/sysroots/i586-poky-linux/usr/include/c++/4.9.2/bits/stl_tree.h:1261
1261 if (!_M_impl._M_key_compare(_S_key(__x), __k))
(gdb) bt
#0 _M_lower_bound (this=<optimized out>, __k=<optimized out>, __y=0xf31256e8, __x=0x65687465) at /volume/evo/files/opt/poky/1.8.2-4/sysroots/i586-poky-linux/usr/include/c++/4.9.2/bits/stl_tree.h:1261
#1 find (__k=<optimized out>, this=0xf6ac8e2c <actives>) at /volume/evo/files/opt/poky/1.8.2-4/sysroots/i586-poky-linux/usr/include/c++/4.9.2/bits/stl_tree.h:1913
#2 find (__x=<optimized out>, this=0xf6ac8e2c <actives>) at /volume/evo/files/opt/poky/1.8.2-4/sysroots/i586-poky-linux/usr/include/c++/4.9.2/bits/stl_map.h:860
#3 get_ptr (ctx=...)
(gdb)fr 3
(gdb) p ctx
$4 = {px = 0xf3124d30}
编辑:我设法使用Memcheck工具获得了堆栈跟踪。发生的事情是,作为过程退出的一部分,静态图被清理了,但是在完全退出之前,在另一个线程中发生了对genericwatcher的回调: -
main.cpp
static void thread1(void *arg) {
//call genericWatcher repeatedly
}
int main() {
if(fork() == 0) {
pthread_create(..., thread1,..)
//call get_ptr() repeatedly
}
return 0;
}
有什么方法可以防止这种情况?我可以分配一个持有活跃物图的单身人士,但我试图避免使用单例
最可能的故障点是release
回调中的erase
调用,因为它是地图上没有任何守卫机制的唯一访问点。您确定您的WatchCtx
是地图密钥的一部分吗?如果没有,听起来插入已经放开了。但是,就像Velkan已经说过的那样,Valgrind(或您选择的调试器)将为您确定。
相关文章:
- 为什么"do while"循环不断退出,即使条件计算结果为 false?
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- #为""定义宏;静态";针对不同的上下文
- cmake如何在fedora工作站中找到boost静态库包
- 静态数据成员的问题-修复链接错误会导致编译器错误
- 将公共但非静态的成员函数与ALGLIB集成
- cmake在我的项目中所需的所有静态库都不成功
- C++从另一个类访问公共静态向量的正确方法是什么
- 基于boost的程序的静态链接——zlib问题
- 在静态库中嵌入类方法
- Qt C++静态thread_local QNetworkAccessManager是线程应用程序的好选择吗
- 如何在C++中获得"静态纯虚拟"功能?
- 创建LinkedList退出,返回代码为-11(SIGSEGV)
- 私有类型的静态常量成员
- thread_local静态类在程序退出时在无效地址处销毁
- C STL映射中的SegFault由于过程退出期间的静态可变清理而找到
- 类的静态实例无法在程序退出时正确处理资源删除
- 为什么全局或静态对象会导致程序退出时崩溃
- 在c++中,一旦程序退出,singleton(静态实例)就会被销毁,这是正确的原因
- 对静态常量变量的未定义引用collect2: ld返回1退出状态