运行 gdb 命令,然后通过 Visual Studio 代码将其附加到进程
Running a gdb command before attaching it to a process via Visual Studio Code
我正在尝试使用 Visual Studio 代码作为我在 Linux 上的 IDE 单步执行 Postgresql 代码。我正在使用附加到 launch.json 中的进程配置来实现相同的目的。以下是 launch.json 配置:
{
"version": "0.2.0",
"configurations": [
{
"name": "(gdb) Launch",
"type": "cppdbg",
"request": "attach",
"program": "/usr/local/pgsql/bin/postgres",
"processId": 4165,
"MIMode": "gdb",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true,
}
]
}
]
}
当我通过 GUI 启动调试时,它附加到进程。但是每当我添加断点时,我都会在调试控制台上打印以下消息:
Program received signal SIGINT, Interrupt.
0x00007ff5d084e31b in epoll_wait () from /lib64/libc.so.6
加断点失败。从 Postgres 开发人员文档 (link) 可以清楚地看出,我们需要通过向 gdb 发出以下命令来绕过到达 gdb 的中断:
handle SIGUSR1 noprint pass
我认为gdb中的这个命令只能在附加进程调试之前执行。因此,当我通过 Visual Studio 代码上的调试控制台 运行 此命令时,出现以下错误:
Unable to perform this action because the process is running.
有没有办法指示 Visual Studio 代码调试,在通过 gdb 附加目标进程之前将 "handle SIGUSR1 noprint pass" 发送到 gdb?
经过更多研究,我找到了使用 ~/.gdbinit 文件实现此目的的方法。每次 gdb 为 运行 时,该文件可以包含 运行 的命令。我里面有以下内容:
handle SIGUSR1 nostop noprint pass
handle SIGINT nostop noprint pass
现在发生的事情是,由于 SIGINT 被覆盖,每次 IDE 与进程断开连接时,它都会重新启动,因为它无法再正常断开连接。
考虑在 launch.json 的 setupCommands 部分定义这些命令:
{
"version": "0.2.0",
"configurations": [
{
"name": "debugging of local server",
"type": "cppdbg",
"request": "attach",
"program": "/usr/local/pgsql/bin/postgres",
"processId": "${command:pickProcess}",
"MIMode": "gdb",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
},
{
"description": "ignore SIGUSR1 signal",
"text": "handle SIGUSR1 nostop noprint pass"
}
]
}
]
}
除了Keshav的回答。
您还可以在 ~/.gdbinit 文件中添加另一个命令:
set auto-load safe-path /
这将告诉编译器它可以使用您工作目录中的本地 .gdbinit 文件。
现在您可以为每个项目/目录创建一个单独的 .gdbinit 并独立配置它们,而不会使全局 .gdbinit 混乱。
我正在尝试使用 Visual Studio 代码作为我在 Linux 上的 IDE 单步执行 Postgresql 代码。我正在使用附加到 launch.json 中的进程配置来实现相同的目的。以下是 launch.json 配置:
{
"version": "0.2.0",
"configurations": [
{
"name": "(gdb) Launch",
"type": "cppdbg",
"request": "attach",
"program": "/usr/local/pgsql/bin/postgres",
"processId": 4165,
"MIMode": "gdb",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true,
}
]
}
]
}
当我通过 GUI 启动调试时,它附加到进程。但是每当我添加断点时,我都会在调试控制台上打印以下消息:
Program received signal SIGINT, Interrupt.
0x00007ff5d084e31b in epoll_wait () from /lib64/libc.so.6
加断点失败。从 Postgres 开发人员文档 (link) 可以清楚地看出,我们需要通过向 gdb 发出以下命令来绕过到达 gdb 的中断:
handle SIGUSR1 noprint pass
我认为gdb中的这个命令只能在附加进程调试之前执行。因此,当我通过 Visual Studio 代码上的调试控制台 运行 此命令时,出现以下错误:
Unable to perform this action because the process is running.
有没有办法指示 Visual Studio 代码调试,在通过 gdb 附加目标进程之前将 "handle SIGUSR1 noprint pass" 发送到 gdb?
经过更多研究,我找到了使用 ~/.gdbinit 文件实现此目的的方法。每次 gdb 为 运行 时,该文件可以包含 运行 的命令。我里面有以下内容:
handle SIGUSR1 nostop noprint pass
handle SIGINT nostop noprint pass
现在发生的事情是,由于 SIGINT 被覆盖,每次 IDE 与进程断开连接时,它都会重新启动,因为它无法再正常断开连接。
考虑在 launch.json 的 setupCommands 部分定义这些命令:
{
"version": "0.2.0",
"configurations": [
{
"name": "debugging of local server",
"type": "cppdbg",
"request": "attach",
"program": "/usr/local/pgsql/bin/postgres",
"processId": "${command:pickProcess}",
"MIMode": "gdb",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
},
{
"description": "ignore SIGUSR1 signal",
"text": "handle SIGUSR1 nostop noprint pass"
}
]
}
]
}
除了Keshav的回答。
您还可以在 ~/.gdbinit 文件中添加另一个命令:
set auto-load safe-path /
这将告诉编译器它可以使用您工作目录中的本地 .gdbinit 文件。
现在您可以为每个项目/目录创建一个单独的 .gdbinit 并独立配置它们,而不会使全局 .gdbinit 混乱。