c – 信号处理期间的堆损坏
我有一个多线程
Windows服务器,我正在研究,发现在我通过control-c关闭程序时出现一定的标准后,它崩溃了.如果我的服务器从客户端接收数据包然后我使用control-c,它会崩溃.如果我启动我的服务器,让它等待任何时间段的数据包,然后使用control-c,它会正常退出.
然而,有什么奇怪的是,即使程序确实抛出异常(除非那是正常的),我的所有线程都报告他们正以状态0退出. First-chance exception at 0x75A16DA7 (kernel32.dll) in server.exe: 0x40010005: Control-C. HEAP[server.exe]: HEAP: Free Heap block 96a818 modified at 96a908 after it was freed server.exe has triggered a breakpoint. The thread 0xc34 has exited with code 0 (0x0). The thread 0x1c64 has exited with code 0 (0x0). The thread 0xdbc has exited with code 0 (0x0). The thread 0x117c has exited with code 0 (0x0). The thread 0x1444 has exited with code 0 (0x0). The thread 0x1d60 has exited with code 0 (0x0). The thread 0x798 has exited with code 0 (0x0). The thread 0x700 has exited with code 0 (0x0). The thread 0x1bbc has exited with code 0 (0x0). The thread 0x1b74 has exited with code 0 (0x0). The program '[7528] server.exe' has exited with code 0 (0x0). 代码的一部分似乎是导致此问题的原因: void handleSignal(int sig) { std::unique_lock<std::mutex> lock(signalMutex); // <-- comment out and it doesn't crash signaled = true; _receivedSignal = sig; signalHandlerCondition.notify_one(); // <-- comment out and it doesn't crash } 互斥和条件变量都是全局变量: std::mutex signalMutex; std::condition_variable signalHandlerCondition; 我有一个专用的信号处理线程,试图在该事件通知时正常关闭服务器. void run() { while (gContinueRunning && _continueRunning) { std::unique_lock<std::mutex> lock(signalMutex); signalHandlerCondition.wait(lock); if (signaled) { gContinueRunning = false; signaled = false; Server::stop(); } } } 当然,当我注释掉有问题的线路时,程序根本不响应信号.我可以有一个wait_for,这样我就不必通知信号处理循环它有一个新信号,但我不认为这是最好的方法. 我确实从MSDN上读到了有关信号的内容:
老实说,我不确定这是否适用于这种情况.如果确实如此,这是否意味着在调用信号处理程序时,我的互斥锁可能存在也可能不存在? 那么,接近信号的最佳方法是什么?我遇到什么问题? 编辑:只是为了清除一些事情: void start() { _receivedSignal = 0; _continueRunning = true; // start thread std::thread signalHandlerThread(run); _signalHandlerThread = std::move(signalHandlerThread); // register signals signal(SIGABRT,SignalHandler::handleSignal); signal(SIGTERM,SignalHandler::handleSignal); signal(SIGINT,SignalHandler::handleSignal); } 即使在删除互斥锁后,程序似乎也会进一步发展 – 尽管只有在主要完成之后. msvcr110d.dll!operator delete(void * pUserData) Line 52 C++ server.exe!std::_Ref_count<User>::_Destroy() Line 161 C++ server.exe!std::_Ref_count_base::_Decref() Line 120 C++ server.exe!std::_Ptr_base<User>::_Decref() Line 347 C++ server.exe!std::shared_ptr<User>::~shared_ptr<User>() Line 624 C++ server.exe!std::pair<unsigned int const,std::shared_ptr<User> >::~pair<unsigned int const,std::shared_ptr<User> >() C++ server.exe!std::pair<unsigned int const,std::shared_ptr<User> >::`scalar deleting destructor'(unsigned int) C++ server.exe!std::allocator<std::_Tree_node<std::pair<unsigned int const,std::shared_ptr<User> >,void *> >::destroy<std::pair<unsigned int const,std::shared_ptr<User> > >(std::pair<unsigned int const,std::shared_ptr<User> > * _Ptr) Line 624 C++ server.exe!std::allocator_traits<std::allocator<std::_Tree_node<std::pair<unsigned int const,void *> > >::destroy<std::pair<unsigned int const,std::shared_ptr<User> > >(std::allocator<std::_Tree_node<std::pair<unsigned int const,void *> > & _Al,std::pair<unsigned int const,std::shared_ptr<User> > * _Ptr) Line 758 C++ server.exe!std::_Wrap_alloc<std::allocator<std::_Tree_node<std::pair<unsigned int const,std::shared_ptr<User> > * _Ptr) Line 909 C++ server.exe!std::_Tree<std::_Tmap_traits<unsigned int,std::shared_ptr<User>,std::less<unsigned int>,std::allocator<std::pair<unsigned int const,std::shared_ptr<User> > >,0> >::_Erase(std::_Tree_node<std::pair<unsigned int const,void *> * _Rootnode) Line 2069 C++ server.exe!std::_Tree<std::_Tmap_traits<unsigned int,0> >::clear() Line 1538 C++ server.exe!std::_Tree<std::_Tmap_traits<unsigned int,0> >::erase(std::_Tree_const_iterator<std::_Tree_val<std::_Tree_simple_types<std::pair<unsigned int const,std::shared_ptr<User> > > > > _First,std::_Tree_const_iterator<std::_Tree_val<std::_Tree_simple_types<std::pair<unsigned int const,std::shared_ptr<User> > > > > _Last) Line 1512 C++ server.exe!std::_Tree<std::_Tmap_traits<unsigned int,0> >::_Tidy() Line 2216 C++ server.exe!std::_Tree<std::_Tmap_traits<unsigned int,0> >::~_Tree<std::_Tmap_traits<unsigned int,0> >() Line 1190 C++ server.exe!std::map<unsigned int,std::shared_ptr<User> > > >::~map<unsigned int,std::shared_ptr<User> > > >() C++ server.exe!`dynamic atexit destructor for 'User::_usersListBySession''() C++ msvcr110d.dll!doexit(int code,int quick,int retcaller) Line 584 C msvcr110d.dll!exit(int code) Line 394 C server.exe!__tmainCRTStartup() Line 549 C server.exe!mainCRTStartup() Line 377 C 看起来所有其他线程都消失了.我想我可能在其他地方犯了一个错误. 感谢您清除信号功能的安全性. 编辑2:看起来像一个不相关的共享指针给我带来麻烦!我很高兴能看到一些好消息. 编辑3:一个完全不相关的问题导致崩溃.现在世界上的一切都很好. 解决方法
我怀疑这是因为您的调试器正在处理Ctrl-C事件.
这个MSDN article有如下说法:
您可以将事件过滤器设置为“输出 – 未处理”以允许您的应用程序处理此事件.我附上了一个如何在WinDbg中设置它的屏幕截图. Visual Studio在“Win32 Exceptions”下列出了这一点. 编辑: (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |