我的程序在boost :: thread :: thread_start_function中崩溃了,我该怎么调试

时间:2011-02-22 10:45:49

标签: c++ visual-studio boost-thread

我使用Visual Studio 2008构建C ++程序。发行版和调试版都随机崩溃。崩溃的频率取决于它运行的机器(从每周一次到每小时一次)。

该程序使用boost asio进行TCP通信以及使用wxWidget进行UI。然而,崩溃与任何TCP问题或UI交互无关,因为它主要发生在程序空闲时。

这是我崩溃时的调用堆栈:

msvcr90d.dll!_NMSG_WRITE(int rterrnum=10)  Line 198 C
msvcr90d.dll!abort()  Line 59 + 0x7 bytes   C
msvcr90d.dll!terminate()  Line 130  C++
enf_client.exe!boost::thread::thread_start_function(void * param=0x00161e60)  Line 184  C++
msvcr90d.dll!_callthreadstartex()  Line 348 + 0xf bytes C
msvcr90d.dll!_threadstartex(void * ptd=0x01385d28)  Line 331    C
kernel32.dll!7c80b729()     
[Frames below may be incorrect and/or missing, no symbols loaded for kernel32.dll

我对如何调试这个东西毫无头绪。如果你知道在哪里寻找,那就太好了。

修改

我在调试跟踪中注意到了这一点,就在崩溃之前:

First-chance exception at 0x7c812afb in enf_client.exe: Microsoft C++ exception: std::out_of_range at memory location 0x0189efd4..

我无法弄清楚这个地址的内存是什么(看起来像很多垃圾):

L.H............. ð..0.=..zH. ð...ð.......

除了stl容器的at函数之外,哪些函数可以触发这个?

4 个答案:

答案 0 :(得分:2)

terminate()在你的调用堆栈中的事实让我相信正在调用一个纯虚函数。通过以下方案引发这种情况相对容易:

  • 表示线程的基类,在ctor中启动线程。 “执行”功能是纯虚拟的
  • 实现“执行”功能的子类。

偶尔,从Base ctor开始的线程将在基本完成之前开始运行。因此,调用的对象execute不是完全构造的,并且调用Base的execute,导致terminate()

这样一个偶然的终止()可能是由其他几个场景造成的,我建议你试着通过在实际创建你的线程的调用之后立即休眠来激发它。

答案 1 :(得分:2)

您是否尝试将调试器设置为在抛出异常时中断? (调试菜单 - >例外 - > C ++例外 - >选中std :: exception的复选框。)

答案 2 :(得分:1)

如果没有看到任何代码,很难告诉您问题可能是什么。

我会这样做:

似乎在catch块中的boost :: thread :: thread_start_function内调用了terminate()。 在Windows下我会在std :: terminate()之前调用DebugBreak()并启动应用程序(当然你必须运行调试版本)。当错误再次发生时,DebugBreak将启动您的调试器并在此时等待。从那里你可以分析堆栈跟踪并检查谁启动了这个线程并检查内部发生了什么。

答案 3 :(得分:0)

考虑到我有一个std::out_of_range,我查看了对at函数的所有调用。

这就是:

std::string temp; ... ; if (temp.size() >= 8) temp.at(8) = '0'

应该是: if (temp.size() >= 9) temp.at(8) = '0'

我仍然不明白为什么在调试模式下我没有关于此异常的更多调试信息。这可能是因为它位于UI线程上,由wxWidget管理。