调用wxThread :: OnExit()时出现分段错误

时间:2012-09-19 20:25:54

标签: c++ segmentation-fault wxwidgets gmp

更新2:请参阅我的代码后的部分。

我使用线程来计算使用GMP库的PI,但是当wxThread::OnExit()内部调用wxWidgets时,我现在以某种方式遇到分段错误。

以下是wxWidgets源代码中的一行:src/msw/thread.cpp#553

以下是我的线程输入功能的缩短代码:

while (i <= m_numIterations && !TestDestroy()) {
    mpf_div(result, perimeter, edgeCount);

    mpf_pow_ui(result, result, 2);
    mpf_ui_sub(result, 1, result);
    mpf_sqrt(result, result);
    mpf_div_ui(result, result, 2);

    mpf_sub(result, half, result);
    mpf_sqrt(result, result);
    mpf_mul_ui(result, result, 2);
    mpf_mul(result, result, edgeCount);

    mpf_set(perimeter, result);

    i++;
    mpf_mul_ui(edgeCount, edgeCount, 2);
}

// Free GMP variables we don't need anymore
mpf_clear(half);
mpf_clear(result);
mpf_clear(edgeCount);

// OUTPUT_DIGITS has a constant value, e.g. 12
char outputStr[OUTPUT_DIGITS];

mp_exp_t *expptr;

// If commented out, the error does not appear!
mpf_get_str(outputStr, expptr, 10, OUTPUT_DIGITS, perimeter);

更新2:如果我用mpf_get_str()注释掉最后一行,则不会发生错误。
我还发现2003年的一个非常老的错误请求:http://gmplib.org/list-archives/gmp-discuss/2003-November/000888.html

从GCC调试器调用堆栈:

#0 63AE80E9 wxThreadInternal::DoThreadOnExit(thread=0x2cfa978) (../../src/msw/thread.cpp:553)
#1 63B27ACF wxScopeGuardImpl1<void (*)(wxThread*) (../../include/wx/scopeguard.h:168)
#2 63B3F95B wxPrivate::OnScopeExit<wxScopeGuardImpl1<void (*)(wxThread*) (../../include/wx/scopeguard.h:67)
#3 63B27B36 wxScopeGuardImpl1<void (*)(wxThread*) (../../include/wx/scopeguard.h:166)
#4 63AE82FB wxThreadInternal::DoThreadStart(thread=0x2cfa978) (../../src/msw/thread.cpp:561)
#5 63AE83F2 wxThreadInternal::WinThreadStart(param=0x2cfa978) (../../src/msw/thread.cpp:602)
#6 75C4906A ui64tow() (C:\Windows\SysWOW64\msvcrt.dll:??)
#7 75C49147 msvcrt!iswalnum() (C:\Windows\SysWOW64\msvcrt.dll:??)
#8 76448543 UnregisterBadMemoryNotification() (C:\Windows\SysWOW64\kernel32.dll:??)
#9 00000000 0x02cfb178 in ??() (??:??)
#10 00000000    0x77e8ac69 in ??() (??:??)
#11 00000000    0x77e8ac3c in ??() (??:??)
#12 00000000    0x00000000 in ??() (??:??)

3 个答案:

答案 0 :(得分:0)

new并没有“失败”,你本身就有堆腐败。

答案 1 :(得分:0)

如果它在这一行上真的崩溃了(gdb刚丢失并且没有显示后续帧的概率也是不可忽略的),那么thread指针本身必须为NULL或无效,这可能是'在正常执行中发生,所以我同意其他回复:似乎有些东西会破坏你的变量。但是,如果gdb正在撒谎,请检查您的OnExit()是否完全输入。

当你使用跨平台库时,你应该能够在Linux下重建并在valgrind下运行它,这应该指出所有明显的问题。

答案 2 :(得分:0)

指针指针(此处为expptr)必须已初始化为对象。

这个单线解决了这个问题:

expptr = new mp_exp_t();

// call mpf_get_str()
我还要注意VZ。是正确的,GDB(GNU调试器)可以显示错误应出现的错误源代码行。

所以不要依赖它。