繁体   English   中英

如何在 Linux 上的 VS Code 程序中捕获 C 程序中的 CTRL+C?

[英]How to catch CTRL+C inside C Program on VS Code on Linux?

在 Linux 上用 VS Code 编码 C。

我用;

signal(SIGINT, myhandler); 
signal(SIGHUP, myhandler); 
signal(SIGKILL, myhandler); 
signal(SIGTERM, myhandler); 

我使用 VS 代码内部终端,选中“在终端中运行”选项。

当我的代码在循环中运行时,当我发送组合键 CTRL-C 时,执行停止但信号没有被我的代码(我的处理程序)捕获。

我在 .gdbinit 文件中添加了“handle all nostop print pass”,但没有任何改变。

问题是如何在当前正在 VS Code 中调试的程序中捕获从键盘发送的 CTRL-C (SIGINT)?

为了详细说明,我将在下面添加我的 launch.json、tasks.json 和 main.c 文件:

{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"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
      }
    ],
    "preLaunchTask": "C/C++: gcc build active file",
    "miDebuggerPath": "/usr/bin/gdb"
  }
]

}

{
"version": "2.0.0",
"tasks": [
    {
        "type": "cppbuild",
        "label": "C/C++: gcc build active file",
        "command": "/usr/bin/gcc",
        "args": [
            "-g",
            "${workspaceFolder}/*.c",
            "-o",
            "${fileDirname}/bin/${fileBasenameNoExtension}"
        ],
        "options": {
            "cwd": "${fileDirname}"
        },
        "problemMatcher": [
            "$gcc"
        ],
        "group": {
            "isDefault": true,
            "kind": "build"
            },
        "detail": "compiler: /usr/bin/gcc"
    }
]

}

#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...");

    while (1)
    {
        // do something
        printf("looping...");
        usleep(10000);
    }

    return 0;

} //------------------------------- main -------------------------------------//

/**
 * Let's get ready and initialize everything.
 */
void initialize(void)
{
    signal(SIGINT, sigHandler);
    signal(SIGHUP, sigHandler);
    signal(SIGKILL, sigHandler);
    signal(SIGTERM, sigHandler);
}


/**
 * Stop before exiting and close everything.
 */
void sigHandler(int signo)
{
    printf("Caught signal: %d, exiting!", signo);
    exit(0);
}

这没有记录,但使用handle all skips signals used by the debugger,这可以在此处的 GDB 源代码中看到。

由于调试器使用 SIGINT,这意味着 GDB 仍在拦截您发送的 SIGINT,而不是将其转发给您的程序。

您有两种选择,一种是使用:

handle SIGINT ...etc...

专门通过SIGINT。 我建议使用handle SIGINT stop print pass ,这样你仍然可以使用 Ctrl-C 中断你的应用程序,但是当你继续时 GDB 将通过 SIGINT。

如果您确定要将所有信号作为nostop print pass处理,那么事实证明 GDB 实际上接受handle命令的多个信号,因此您可以这样做:

handle all SIGINT SIGTRAP nostop print pass

您的另一种选择可能是在停止程序后使用signal SIGINT ,这将恢复程序但只传递一次 SIGINT。 信号命令在此处记录。

暂无
暂无

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

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