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

Linux下VS Code中如何在C程序内捕获CTRL+C信号?

调试VS Code中C程序的SIGINT信号捕获问题

问题背景

在Linux系统的VS Code中编写C代码,已通过signal函数注册SIGINT、SIGHUP、SIGKILL、SIGTERM的自定义处理函数,勾选了VS Code内置终端的"run in terminal"选项。程序循环运行时按下CTRL+C,程序直接终止,但自定义的sigHandler函数未被触发。已在.gdbinit中添加handle all nostop print pass配置,问题仍未解决。

解决方案

1. 配置GDB传递SIGINT信号给程序

调试时GDB会默认接管SIGINT信号(用于暂停调试),导致程序无法捕获。需要在VS Code的调试配置中明确让GDB将SIGINT传递给程序:

  • 修改launch.json的setupCommands数组,新增一条GDB命令:
    {
        "description": "Pass SIGINT to program instead of stopping GDB",
        "text": "handle SIGINT nostop print pass",
        "ignoreFailures": true
    }
    
    直接在launch.json中配置比依赖.gdbinit更可靠,因为VS Code启动GDB时可能未加载用户的.gdbinit。

2. 修复输出缓冲问题

原代码中printf未添加换行符,stdout默认行缓冲,导致信号触发后的输出无法及时显示。修改方式二选一:

  • 在所有printf语句末尾添加\n;
  • 在printf后调用fflush(stdout);强制刷新缓冲区。

3. 移除无效的SIGKILL注册

SIGKILL是Linux系统中无法被捕获、阻塞或忽略的信号,注册其处理函数无意义,建议从代码中移除。

修改后的配置与代码

调整后的launch.json

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "gdb build and debug active file",
            "type": "cppdbg",
            "request": "launch",
            "program": "${fileDirname}/bin/${fileBasenameNoExtension}",
            "args": [],
            "stopAtEntry": false,
            "cwd": "${workspaceFolder}",
            "environment": [],
            "externalConsole": false,
            "MIMode": "gdb",
            "setupCommands": [
                {
                    "description": "Enable pretty-printing for gdb",
                    "text": "-enable-pretty-printing",
                    "ignoreFailures": true
                },
                {
                    "description": "Pass SIGINT to program instead of stopping GDB",
                    "text": "handle SIGINT nostop print pass",
                    "ignoreFailures": true
                }
            ],
            "preLaunchTask": "C/C++: gcc build active file",
            "miDebuggerPath": "/usr/bin/gdb"
        }
    ]
}

修改后的main.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>

// function prototypes
void initialize(void);
void sigHandler(int signo);

/*************** main routine which contains the infinite loop ****************/
int main(int argc, char *argv[])
{
    initialize();
    printf("It is alive...\n");

    while (1)
    {
        printf("looping...\n");
        usleep(10000);
    }

    return 0;
}

/**
 * Initialize signal handlers
 */
void initialize(void)
{
    signal(SIGINT, sigHandler);
    signal(SIGHUP, sigHandler);
    signal(SIGTERM, sigHandler);
}

/**
 * Custom signal handler
 */
void sigHandler(int signo)
{
    printf("Caught signal: %d, exiting!\n", signo);
    fflush(stdout);
    exit(0);
}

内容的提问来源于stack exchange,提问作者Cem

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 07:25:24