VSCode中多线程C++程序出现Paused on Exception问题求助
问题:pthread多线程程序调试时的异常行为差异
直接编译运行基于pthread的C++程序时,VSCode调用堆栈窗口弹出“Paused on Exception”错误,程序输出不完整;但在ThreadFunc2函数的cout << "Thread 2 begin." << endl;行添加断点,触发断点后继续运行,程序可顺利执行至结束,输出完整。
程序代码
#include <iostream> #include <pthread.h> #include <cstdlib> #include <windows.h> using namespace std; void *ThreadFun(void *arg) { cout << "Thread begin. Id:" << (*(int *)arg) << endl; return (void *)"Thread start successfully."; } void *ThreadFunc2(void *arg) { int res; res = pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, nullptr); if (res) { cerr << "set cancel state failure." << endl; } res = pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, nullptr); if (res) { cerr << "set cancel type failure." << endl; } cout << "Thread 2 begin." << endl; while (1) ; // can not respond to pthread_cancel() if using the default attribute. return nullptr; } int main() { pthread_t thread1; int res; void *ret_val; int id = 0; res = pthread_create(&thread1, nullptr, ThreadFun, (int *)&id); if (res) { cerr << "thread create failure!" << endl; } // wait until the thread ends res = pthread_join(thread1, &ret_val); if (res) { cerr << "thread join failure!" << endl; } cout << "return val:" << (static_cast<char *>(ret_val)) << endl; pthread_t thread2; res = pthread_create(&thread2, nullptr, ThreadFunc2, nullptr); if (res) { cerr << "thread 2 create failure." << endl; } Sleep(1000); res = pthread_cancel(thread2); if (res) { cerr << "thread 2 cancel failure." << endl; } res = pthread_join(thread2, &ret_val); if (res) { cerr << "wait thread 2 failure." << endl; } if (ret_val == PTHREAD_CANCELED) { cout << "thread 2 canceled successfully." << endl; } else { cerr << "unknown error." << endl; } cout << "the program ends" << endl; return 0; }
直接运行的输出
D:\Projects\Cpp_Programs\book> cmd /C "c:\Users\XinLi\.vscode\extensions\ms-vscode.cpptools-1.14.4-win32-x64\debugAdapters\bin\WindowsDebugLauncher.exe --stdin=Microsoft-MIEngine-In-ouoz00s4.upe --stdout=Microsoft-MIEngine-Out-ci0ah54f.agf --stderr=Microsoft-MIEngine-Error-mwm5j45t.fxs --pid=Microsoft-MIEngine-Pid-dmi1kcw4.wyk --dbgExe=D:\Software\MSYS2\mingw64\bin\gdb.exe --interpreter=mi " Thread begin. Id:0 return val:Thread start successfully. Thread 2 begin.
添加断点后运行的输出
D:\Projects\Cpp_Programs\book> cmd /C "c:\Users\XinLi\.vscode\extensions\ms-vscode.cpptools-1.14.4-win32-x64\debugAdapters\bin\WindowsDebugLauncher.exe --stdin=Microsoft-MIEngine-In-slivj5pt.ixi --stdout=Microsoft-MIEngine-Out-jgple5z1.4to --stderr=Microsoft-MIEngine-Error-gl514cr1.gmy --pid=Microsoft-MIEngine-Pid-g40uu33a.2lb --dbgExe=D:\Software\MSYS2\mingw64\bin\gdb.exe --interpreter=mi " Thread begin. Id:0 return val:Thread start successfully. thread 2 canceled successfully. the program ends
原因分析
- 异步取消与编译器优化的冲突:
ThreadFunc2中设置了PTHREAD_CANCEL_ASYNCHRONOUS(异步取消模式),随后进入while(1);的空死循环。GCC等编译器会对这种空死循环做激进优化,生成的机器码不会包含任何pthread取消点,而异步取消需要线程执行特定指令时响应取消请求。优化后的死循环没有可触发取消的指令,导致pthread_cancel无法生效,主线程卡在pthread_join处,程序无法正常结束,输出中断。 - 断点对优化的抑制作用:在
cout行添加断点后,调试器会强制编译器生成该位置的调试信息,同时自动禁用该函数内的部分优化逻辑。此时while(1);不再是完全优化后的空循环,或者调试器的断点机制让线程执行过程中产生了足够的指令间隙,使得异步取消信号能被线程捕获,pthread_cancel生效,线程被正常取消,主线程完成pthread_join后顺利执行到程序结束。 - VSCode的异常提示:程序卡住时,调试器可能捕获到pthread库内部因取消失败触发的异常,因此弹出“Paused on Exception”提示。
内容的提问来源于stack exchange,提问作者pikalee
相关产品推荐
相关产品推荐

