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
相关产品推荐
相关产品推荐

