【问题标题】:VS Code debugging fails when there's a space in the source path源路径中有空格时 VS Code 调试失败
【发布时间】:2019-02-01 03:48:17
【问题描述】:

我正在尝试在 VS Code(Windows)中为我的 c 文件创建 GDB 调试管道。你可以在下面找到我的 tasks.json 和 launch.json。

现在,如果我的源文件的路径不包含任何空格,这可以正常工作。但是,如果它确实包含空格,那么每当调试器尝试中断时,我都会收到这样的消息:

这是因为它要查找的源文件实际上位于

E:\Libraries\Dropbox\UNI\Semester 5\test.c

我猜要么是 GDB 向 VS Code 发送了错误的文件链接,要么 VS Code 不理解其文件路径中的空格(我对此表示怀疑)。抱歉,我在调试期间不太了解 GDB 和 VS Code 之间的联系。

有谁知道如何解决这个问题?

tasks.json:

{
    "version": "2.0.0",
    "tasks": [
        {
            "label": "Build C Program",
            "type": "shell",
            "command": "gcc",
            "options": {"cwd": "${fileDirname}"},
            "args": [
                "-g", "-o", "${fileBasenameNoExtension}.exe", "${fileBasename}"
            ],
            "group": {"kind": "build","isDefault": true}
        }
    ]
}

launch.json:

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "(gdb) Launch",
            "type": "cppdbg",
            "request": "launch",
            "program": "${fileDirname}\\${fileBasenameNoExtension}.exe",
            "args": [],
            "stopAtEntry": false,
            "cwd": "${fileDirname}",
            "environment": [],
            "externalConsole": true,
            "MIMode": "gdb",
            "miDebuggerPath": "C:\\cygwin64\\bin\\gdb.exe",
            "setupCommands": [
                {
                    "description": "Enable pretty-printing for gdb",
                    "text": "-enable-pretty-printing",
                    "ignoreFailures": true
                }
            ],
            "preLaunchTask": "Build C Program"
        }
    ]
}

【问题讨论】:

  • 我的建议:永远不要在文件路径中放置空格,尤其是在源文件(或它们上面的某些目录)中。你会避免很多麻烦(你可以改用_)。因为开发工具(尤其是编译器和调试器)是基于命令行的,并且命令对文件路径中的空格(它们需要以某种方式引用)不友好。
  • 所以将Semester 5 重命名为Semester_5Semester-5。这样做可以避免很多麻烦!
  • Basile 说的第二点。虽然理论上可以让它工作,但它的麻烦多于它的价值。每次你转身,你都会碰到另一个工具,要么无法处理空间,要么必须以某种方式解决。
  • 您询问 C 和 GDB ,然后发布 JSON 代码。
  • 对于那些建议您不要在文件路径中放置空格的人,有时(尤其是在 Windows 上)这是无法避免的,例如尝试链接到 OneDrive for Business 中的某些内容时(它会迫使您在文件路径中有空格)

标签: c windows debugging visual-studio-code gdb


【解决方案1】:

我认为最新版本的 VS Code 可能已经解决了这个问题。但是,有关命令行参数如何工作的一些知识可能会帮助您了解此问题的原因。

基本上,shell 会拆分由空格分隔的单词并将这些单词视为独立参数。对于路径中没有嵌入空格的文件,一切正常。对于路径中嵌入空格的文件,需要额外输入一些内容才能绕过陷阱。


假设我们要编译一个名为pathWithNoEmbeddedSpaces.c 的文件,我们只需键入:

gcc -g -o target1.exe pathWithNoEmbeddedSpaces.c

在上述情况下,由空格分隔的命令行参数(从gcc-gpathWithNoEmbeddedSpaces.c)被视为独立参数。然后它们由 shell 传递给我们的编译器 GCC,它知道我们要编译 1 个源文件。


假设我们要编译另一个名为path With Embedded Spaces.c 的文件,我们输入:

gcc -g -o target2.exe path With Embedded Spaces.c

这次我们有多少个独立的论点? 8!现在,shell 将 gcc ... path With Embeded Spaces.c 全部视为独立参数。 GCC 很困惑,因为它看到的是编译 4 个源文件的要求,而这些源文件甚至可能不存在于当前目录中!


至于解决方案,引号来拯救,这也被称为引用。大多数 shell 都可以使用单引号 (') 和双引号 (")。但是您可能想查看您的 shell 的详细信息。只要文件路径中有嵌入的空格,请使用引号。如:

gcc -g -o target2.exe "path With Embedded Spaces.c"

shell 现在知道path With Embedded Spaces.c 是一个参数,应该将其视为一个整体,然后将其传递给 GCC 以完成编译。


现在,VS Code 与这个问题有什么关系?

在 VS Code 的“远古时代”中,它只是简单地替换 JSON 文件中的预定义变量,例如 ${fileDirname},然后加入以空格分隔的参数,并将命令传递给底层 shell。即使 VS Code 对包含空格或其他特殊字符的命令和参数执行特殊处理,它也不会检查预定义变量的替换。所以${fileBasename} 被替换为不带引号。

假设我们当前的工作目录是E:\Libraries\Dropbox\UNI\Semester 5,那么VS Code将${fileBasename}替换为test.c${fileDirname}替换为E:\Libraries\Dropbox\UNI\Semester 5

gcc -g -o test.exe test.c

编译应该没有任何问题,因为test.c 在当前工作目录中。但是,请考虑 launch.json 中的目标路径:

"program": "${fileDirname}\\${fileBasenameNoExtension}.exe"

GDB会因为没有使用引号而搜索名为E:\Libraries\Dropbox\UNI\Semester的程序,然后因为没有这样的程序而异常退出。


要处理带有嵌入空格的文件路径,请考虑使用引号。例如,您可以用单引号将预定义变量括起来:'${fileDirname}''${fileBasename}' 等。您的 JSON 文件中的几行应类似于以下示例:

"-g", "-o", "'${fileBasenameNoExtension}.exe'", "'${fileBasename}'"
"-g", "-o", "\"${fileBasenameNoExtension}.exe\"", "\"${fileBasename}\""
"program": "'${fileDirname}\\${fileBasenameNoExtension}.exe'"

但是,作为一般规则,应尽可能避免源文件路径中的空格。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-10-05
    • 2021-09-08
    • 2021-04-18
    • 2021-05-18
    • 2018-03-03
    • 2011-04-20
    • 1970-01-01
    • 2015-07-12
    相关资源
    最近更新 更多