You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 17:17:51