简体   繁体   English

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

[英]Segmentation fault when wxThread::OnExit() is called

Update 2: See the section after my code. 更新2:请参阅我的代码后的部分。

I'm using a thread for calculating PI using the GMP library, but somehow I'm now getting a segmentation fault when wxThread::OnExit() is internally in wxWidgets called. 我正在使用一个线程来使用GMP库计算PI,但是以某种方式现在在wxWidgets内部调用wxThread::OnExit()时出现分段错误。

Here is the line in wxWidgets source code: src/msw/thread.cpp#553 这是wxWidgets源代码中的行: src / msw / thread.cpp#553

Here is the shortened code from my thread entry function: 这是我的线程输入函数的缩短代码:

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);

Update 2: If I comment out the last line with mpf_get_str() , the error does not occur. 更新2:如果我用mpf_get_str()注释掉了最后一行,则不会发生此错误。
I also found a very old bug requests from 2003: http://gmplib.org/list-archives/gmp-discuss/2003-November/000888.html 我还发现了一个来自2003年的非常古老的错误请求: http : //gmplib.org/list-archives/gmp-discuss/2003-November/000888.html

Call stack from GCC Debugger: 从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 ??() (??:??)

new不会“失败”,就本质而言,您的某个地方发生了堆损坏。

If it really crashes on this line (there is also a non negligible probability that gdb just gets lost and doesn't show the subsequent frames), then the thread pointer itself must be NULL or invalid which can't happen in normal execution, so I do agree with the other reply: something seems to corrupt your variables. 如果它确实在此行崩溃(还有gdb丢失并且不显示后续帧的可能性也不可忽略),则thread指针本身必须为NULL或无效,这在正常执行中不会发生,因此我同意其他答复:某些东西似乎破坏了您的变量。 But do check if your OnExit() gets entered at all just in case gdb is lying. 但是,请检查是否完全输入了OnExit()以防万一gdb在说谎。

And as you're using cross-platform libraries, you should be able to rebuild under Linux and run it under valgrind which should pin point all the obvious problems. 而且,当您使用跨平台库时,您应该能够在Linux下重建并在valgrind下运行,这可以指出所有明显的问题。

The exponent pointer (here expptr ) has to be already initialized to an object. 指数指针(此处为expptr )必须已经初始化为一个对象。

This one-liner solves the problem: 这种单线解决了这个问题:

expptr = new mp_exp_t();

// call mpf_get_str()

I also want to note that VZ. 我还想指出VZ。 was right that GDB (GNU Debugger) can show the wrong line of source code in which the error should appear. GDB(GNU调试器) 可以在错误的源代码行中显示错误是正确的。

So do not only rely on that. 因此, 不仅要依赖于此。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM