microsoft / vscode

Visual Studio Code
https://code.visualstudio.com
MIT License
163.57k stars 29.02k forks source link

problemMatcher with multiple patterns doesn't work #157096

Open ChrisIdema opened 2 years ago

ChrisIdema commented 2 years ago

Does this issue occur when all extensions are disabled?: N/A

I'm trying to write problemMatchers for linker errors (for some reason linker errors do not generate new entries in "PROBLEMS"). I was able to get a few working in my tasks.json file. But some problemMatchers overrule others (linker2 and linker3). This is a problem. It also takes up a lot of lines of code in my tasks.json file, so I decided to write an Extension so I can add the problemMatcher in one line. The extension has the problem that it only seems to work with 1 pattern. More than one pattern results in 0 problems. Another problem is that the extension is very strict and it forces you to specify a file even if the error isn't specific to a file (such as memory size issues).

Here is my tasks.json:

"version": "2.0.0",
  "tasks": [
    {
      "type": "cmake",
      "label": "Build all",
      "command": "build",
      "targets": [
        "all"
      ],
      "group": "build",
      "problemMatcher": [
        "$gcc",
        "$gcc_linker",
        {
          "owner": "linker0",
          "severity": "error",
          "fileLocation" : "absolute",
          "pattern": {
            "regexp": "((error): ld returned (-?\\d+) exit status)",
            "message": 1,
            "file" : 2
          }
        },
        {
          "owner": "linker1",
          "severity": "error",
          "fileLocation" : "absolute",
          "pattern": {
            "regexp": "(\\S*\\.cp{0,2}):(\\d*):\\s(undefined reference to `\\S*')",
            "file": 1,
            "line": 2,
            "message": 3
          }
        },
        {
          "owner": "linker2",
          "severity": "error",
          "fileLocation" : "absolute",
          "pattern": {
            "regexp": "((.*\\.cp{0,2}):(\\d+): (multiple definition of .+);.+:(.*\\.cp{0,2}):(\\d+): first defined here)",
            "message": 4,
            "file": 2,
            "line": 3
          }
        },
        {
          "owner": "linker3",
          "severity": "error",
          "fileLocation" : "absolute",
          "pattern": {
            "regexp": "((.*\\.cp{0,2}):(\\d+): (multiple definition of .+);.+:(.*\\.cp{0,2}):(\\d+): first defined here)",
            "message": 4,
            "file": 5,
            "line": 6
          }
        },
        {
          "owner": "linker4",
          "severity": "error",
          "fileLocation" : "absolute",
          "pattern": {
            "regexp": "((cannot open linker script file (.+.ld): No such file or directory))",
            "message": 1,
            "file": 3
          }
        },
        {
          "owner": "linker5",
          "severity": "error",
          "fileLocation" : "absolute",
          "pattern": {
            "regexp": "((region `\\S+' overflowed by \\d+ bytes))",
            "message": 1
          }
        }

      ],
      "detail": "CMake template build task"
    }
  ]
}

Here is my extension package.json:

{
  "name": "linker-problems",
  "displayName": "linker_problems",
  "description": "problemMatchers to show linker errors in problems window",
  "version": "0.0.1",
  "engines": {
    "vscode": "^1.69.0"
  },
  "categories": [
    "Other"
  ],
  "activationEvents": [
    "onCommand:linker-problems.command0"
  ],
  "main": "./out/extension.js",
  "contributes": {
    "commands": [
      {
        "command": "linker-problems.command0",
        "title": "Command 0"
      }
    ],
    "problemMatchers": [
      {
        "name": "gcc_linker",
        "owner": "linker-problems",
        "fileLocation": [
          "absolute"
        ],
        "severity": "error",
        "pattern": [  
          {
            "regexp": "(\\S*\\.cp{0,2}):(\\d*):\\s(undefined reference to `\\S*')",
            "file": 1,
            "line": 2,
            "message": 3
          },
          {
            "regexp": "((.*\\.cp{0,2}):(\\d+): (multiple definition of .+);.+:(.*\\.cp{0,2}):(\\d+): first defined here)",
            "message": 4,
            "file": 2,
            "line": 3
          }
        ]
      },
      {
        "name": "gcc_linker2",
        "owner": "linker-problems2",
        "fileLocation": [
          "absolute"
        ],
        "severity": "error",
        "pattern": [  
          {
            "regexp": "((.*\\.cp{0,2}):(\\d+): (multiple definition of .+);.+:(.*\\.cp{0,2}):(\\d+): first defined here)",
            "message": 4,
            "file": 2,
            "line": 3
          }
        ]
      } 
    ]
  },
  "scripts": {
    "vscode:prepublish": "npm run compile",
    "compile": "tsc -p ./",
    "watch": "tsc -watch -p ./",
    "pretest": "npm run compile && npm run lint",
    "lint": "eslint src --ext ts",
    "test": "node ./out/test/runTest.js"
  },
  "devDependencies": {
    "@types/vscode": "^1.69.0",
    "@types/glob": "^7.2.0",
    "@types/mocha": "^9.1.1",
    "@types/node": "16.x",
    "@typescript-eslint/eslint-plugin": "^5.31.0",
    "@typescript-eslint/parser": "^5.31.0",
    "eslint": "^8.20.0",
    "glob": "^8.0.3",
    "mocha": "^10.0.0",
    "typescript": "^4.7.4",
    "@vscode/test-electron": "^2.1.5"
  }
}

And here are some examples of linker errors I was able to artificially generate:

 cmake_echo_color --cyan "====== Print firmware binary sizes ======" && arm-none-eabi-size project_name_development.elf && cd /home/username/git/build-project_name_development && arm-none-eabi-objcopy -O ihex project_name_development.elf project_name_development.hex && cd /home/username/git/build-project_name_development && arm-none-eabi-objcopy -O binary project_name_development.elf project_name_development.bin && cd /home/username/git/build-project_name_development && arm-none-eabi-objdump -h -S project_name_development.elf > project_name_development.list
/usr/share/gcc-arm-11.2-2022.02-x86_64-arm-none-eabi/bin/../lib/gcc/arm-none-eabi/11.2.1/../../../../arm-none-eabi/bin/ld: project_name_development.elf section `.bss' will not fit in region `RAM'
/usr/share/gcc-arm-11.2-2022.02-x86_64-arm-none-eabi/bin/../lib/gcc/arm-none-eabi/11.2.1/../../../../arm-none-eabi/bin/ld: region `RAM' overflowed by 1042280 bytes
Memory region         Used Size  Region Size  %age Used
             RAM:     1050472 B         8 KB    12823.14%
           FLASH:       26000 B        64 KB     39.67%
collect2: error: ld returned 1 exit status
ninja: build stopped: subcommand failed.
Build finished with error(s).
 *  Terminal will be reused by tasks, press any key to close it.

&& /home/username/.local/lib/python3.8/site-packages/cmake/data/bin/cmake -E cmake_echo_color --cyan "====== Print firmware binary sizes ======" && arm-none-eabi-size project_name_development.elf && cd /home/username/git/build-project_name_development && arm-none-eabi-objcopy -O ihex project_name_development.elf project_name_development.hex && cd /home/username/git/build-project_name_development && arm-none-eabi-objcopy -O binary project_name_development.elf project_name_development.bin && cd /home/username/git/build-project_name_development && arm-none-eabi-objdump -h -S project_name_development.elf > project_name_development.list
/usr/share/gcc-arm-11.2-2022.02-x86_64-arm-none-eabi/bin/../lib/gcc/arm-none-eabi/11.2.1/../../../../arm-none-eabi/bin/ld: project_name_development.elf section `.data' will not fit in region `RAM'
/usr/share/gcc-arm-11.2-2022.02-x86_64-arm-none-eabi/bin/../lib/gcc/arm-none-eabi/11.2.1/../../../../arm-none-eabi/bin/ld: project_name_development.elf section `.data' will not fit in region `FLASH'
/usr/share/gcc-arm-11.2-2022.02-x86_64-arm-none-eabi/bin/../lib/gcc/arm-none-eabi/11.2.1/../../../../arm-none-eabi/bin/ld: region `RAM' overflowed by 1042280 bytes
/usr/share/gcc-arm-11.2-2022.02-x86_64-arm-none-eabi/bin/../lib/gcc/arm-none-eabi/11.2.1/../../../../arm-none-eabi/bin/ld: region `FLASH' overflowed by 1009048 bytes
Memory region         Used Size  Region Size  %age Used
             RAM:     1050472 B         8 KB    12823.14%
           FLASH:     1074584 B        64 KB    1639.69%
collect2: error: ld returned 1 exit status
ninja: build stopped: subcommand failed.
Build finished with error(s).

/usr/share/gcc-arm-11.2-2022.02-x86_64-arm-none-eabi/bin/../lib/gcc/arm-none-eabi/11.2.1/../../../../arm-none-eabi/bin/ld: cannot open linker script file /home/username/git/project_name_development/project_name/hal/stm32l0xx/project_name_system/init_mcu/linker/STM32L051K8TX_FLASH.ld: No such file or directory
collect2: error: ld returned 1 exit status
ninja: build stopped: subcommand failed.
Build finished with error(s).
 *  Terminal will be reused by tasks, press any key to close it.

Build Started...
project_name_development_test.exe  lib/libgtestd.a  lib/libgmockd.a  lib/libgtest_maind.a  -lgcov  lib/libgtestd.a  -lpthread && :
/usr/bin/ld: CMakeFiles/project_name_development_test.exe.dir/project_name/hal/stm32l0xx/project_name_system/src/project_name_system_stm32l0xx_delay_calibration.c.o: in function `_project_name_system_initDelayUs':
/home/user/git/project_name_development/project_name/hal/stm32l0xx/project_name_system/src/project_name_system_stm32l0xx_delay_calibration.c:16: multiple definition of `_project_name_system_initDelayUs'; CMakeFiles/project_name_development_test.exe.dir/project_name/hal/stm32l0xx/project_name_system/src/project_name_system_stm32l0xx.c.o:/home/user/git/project_name_development/project_name/hal/stm32l0xx/project_name_system/src/project_name_system_stm32l0xx.c:63: first defined here
/usr/bin/ld: CMakeFiles/project_name_development_test.exe.dir/project_name/hal/stm32l0xx/project_name_system/src/project_name_system_stm32l0xx.c.o: in function `_project_name_system_initDelayUs':
/home/user/git/project_name_development/project_name/hal/stm32l0xx/project_name_system/src/project_name_system_stm32l0xx.c:64: undefined reference to `_project_name_system_initDelayUs2'
/usr/bin/ld: CMakeFiles/project_name_development_test.exe.dir/project_name/hal/stm32l0xx/project_name_system/src/project_name_system_stm32l0xx_delay_calibration.c.o: in function `_project_name_system_testDelayUs':
/home/user/git/project_name_development/project_name/hal/stm32l0xx/project_name_system/src/project_name_system_stm32l0xx_delay_calibration.c:232: undefined reference to `LL_GPIO_DeInit'
collect2: error: ld returned 1 exit status
ninja: build stopped: subcommand failed.
Build finished with error(s).

Is there a way to get the following things to work using the problemMatchers?:

If not is there a way to implement this in an extension script? Another useful feature for an extension would be that it would automatically run after a cmake build (from the cmake extension). Right now it can only add or remove problems when I run a custom task.

vscodenpa commented 2 years ago

Thanks for creating this issue! It looks like you may be using an old version of VS Code, the latest stable release is 1.69.2. Please try upgrading to the latest version and checking whether this issue remains.

Happy Coding!

ChrisIdema commented 2 years ago

Updated VSCode; Same problems.

I tried to merge some regular expressions into one. But It seems to have problems with multiple errors in one log line (different source code lines). It works perfectly in regex101.com, but in VSCode it doesn't. It either has 0 matches or matches from the same log line are missing.

undefined reference and multiple definitions combined:
(?<=:\s?)(\S*\.(?:c|cpp)):(\d*): ((?:undefined reference to|multiple definition of) `\S+')
second half of multiple definition of:
(?<=:\s?)(\S*\.(?:c|cpp)):(\d*): (first defined here)
result:
(?::|^)(\S+\.(?:c|cpp)):(\d+): (undefined reference to `\S+'|multiple definition of `\S+'|first defined here)

Example: I want this line:

/home/user/git/project_name_development/project_name/hal/stm32l0xx/project_name_system/src/project_name_system_stm32l0xx_delay_calibration.c:16: multiple definition of `_project_name_system_initDelayUs'; CMakeFiles/project_name_development_test.exe.dir/project_name/hal/stm32l0xx/project_name_system/src/project_name_system_stm32l0xx.c.o:/home/user/git/project_name_development/project_name/hal/stm32l0xx/project_name_system/src/project_name_system_stm32l0xx.c:63: first defined here

To be reported as 2 problems since it references two files. But somehow a match eats the entire log line so only one problem is displayed. I tried the loop command, but it's not working. Is there a way to debug it?

lerchl commented 2 years ago

I have the same issue, two patterns that match on their own yet do not match together. I am on version 1.70.0.

ChrisIdema commented 2 years ago

I've simplified the task.json. I simply echo the build output as a string literal so no actual build is needed. I had to escape the ` (backtick), double quotes(once for json and once for echo) and line endings. Still the same problem in version 1.70.2 of vscode. I still cannot get multiple matches on the same line (linker2 and linker3).

{
    "version": "2.0.0",
    "tasks": [
        {
            "label": "problemMatcherTest",
            "type": "shell",
            "command": "echo \"cmake_echo_color --cyan \\\"====== Print firmware binary sizes ======\\\" && arm-none-eabi-size project_name_development.elf && cd /home/username/git/build-project_name_development && arm-none-eabi-objcopy -O ihex project_name_development.elf project_name_development.hex && cd /home/username/git/build-project_name_development && arm-none-eabi-objcopy -O binary project_name_development.elf project_name_development.bin && cd /home/username/git/build-project_name_development && arm-none-eabi-objdump -h -S project_name_development.elf > project_name_development.list\n/usr/share/gcc-arm-11.2-2022.02-x86_64-arm-none-eabi/bin/../lib/gcc/arm-none-eabi/11.2.1/../../../../arm-none-eabi/bin/ld: project_name_development.elf section \\`.bss' will not fit in region \\`RAM'\n/usr/share/gcc-arm-11.2-2022.02-x86_64-arm-none-eabi/bin/../lib/gcc/arm-none-eabi/11.2.1/../../../../arm-none-eabi/bin/ld: region \\`RAM' overflowed by 1042280 bytes\nMemory region         Used Size  Region Size  %age Used\n             RAM:     1050472 B         8 KB    12823.14%\n           FLASH:       26000 B        64 KB     39.67%\ncollect2: error: ld returned 1 exit status\nninja: build stopped: subcommand failed.\nBuild finished with error(s).\n *  Terminal will be reused by tasks, press any key to close it.\n\n\n&& /home/username/.local/lib/python3.8/site-packages/cmake/data/bin/cmake -E cmake_echo_color --cyan \\\"====== Print firmware binary sizes ======\\\" && arm-none-eabi-size project_name_development.elf && cd /home/username/git/build-project_name_development && arm-none-eabi-objcopy -O ihex project_name_development.elf project_name_development.hex && cd /home/username/git/build-project_name_development && arm-none-eabi-objcopy -O binary project_name_development.elf project_name_development.bin && cd /home/username/git/build-project_name_development && arm-none-eabi-objdump -h -S project_name_development.elf > project_name_development.list\n/usr/share/gcc-arm-11.2-2022.02-x86_64-arm-none-eabi/bin/../lib/gcc/arm-none-eabi/11.2.1/../../../../arm-none-eabi/bin/ld: project_name_development.elf section \\`.data' will not fit in region \\`RAM'\n/usr/share/gcc-arm-11.2-2022.02-x86_64-arm-none-eabi/bin/../lib/gcc/arm-none-eabi/11.2.1/../../../../arm-none-eabi/bin/ld: project_name_development.elf section \\`.data' will not fit in region \\`FLASH'\n/usr/share/gcc-arm-11.2-2022.02-x86_64-arm-none-eabi/bin/../lib/gcc/arm-none-eabi/11.2.1/../../../../arm-none-eabi/bin/ld: region \\`RAM' overflowed by 1042280 bytes\n/usr/share/gcc-arm-11.2-2022.02-x86_64-arm-none-eabi/bin/../lib/gcc/arm-none-eabi/11.2.1/../../../../arm-none-eabi/bin/ld: region \\`FLASH' overflowed by 1009048 bytes\nMemory region         Used Size  Region Size  %age Used\n             RAM:     1050472 B         8 KB    12823.14%\n           FLASH:     1074584 B        64 KB    1639.69%\ncollect2: error: ld returned 1 exit status\nninja: build stopped: subcommand failed.\nBuild finished with error(s).\n\n\n/usr/share/gcc-arm-11.2-2022.02-x86_64-arm-none-eabi/bin/../lib/gcc/arm-none-eabi/11.2.1/../../../../arm-none-eabi/bin/ld: cannot open linker script file /home/username/git/project_name_development/project_name/hal/stm32l0xx/project_name_system/init_mcu/linker/STM32L051K8TX_FLASH.ld: No such file or directory\ncollect2: error: ld returned 1 exit status\nninja: build stopped: subcommand failed.\nBuild finished with error(s).\n *  Terminal will be reused by tasks, press any key to close it.\n\n\nBuild Started...\nproject_name_development_test.exe  lib/libgtestd.a  lib/libgmockd.a  lib/libgtest_maind.a  -lgcov  lib/libgtestd.a  -lpthread && :\n/usr/bin/ld: CMakeFiles/project_name_development_test.exe.dir/project_name/hal/stm32l0xx/project_name_system/src/project_name_system_stm32l0xx_delay_calibration.c.o: in function \\`_project_name_system_initDelayUs':\n/home/user/git/project_name_development/project_name/hal/stm32l0xx/project_name_system/src/project_name_system_stm32l0xx_delay_calibration.c:16: multiple definition of \\`_project_name_system_initDelayUs'; CMakeFiles/project_name_development_test.exe.dir/project_name/hal/stm32l0xx/project_name_system/src/project_name_system_stm32l0xx.c.o:/home/user/git/project_name_development/project_name/hal/stm32l0xx/project_name_system/src/project_name_system_stm32l0xx.c:63: first defined here\n/usr/bin/ld: CMakeFiles/project_name_development_test.exe.dir/project_name/hal/stm32l0xx/project_name_system/src/project_name_system_stm32l0xx.c.o: in function \\`_project_name_system_initDelayUs':\n/home/user/git/project_name_development/project_name/hal/stm32l0xx/project_name_system/src/project_name_system_stm32l0xx.c:64: undefined reference to \\`_project_name_system_initDelayUs2'\n/usr/bin/ld: CMakeFiles/project_name_development_test.exe.dir/project_name/hal/stm32l0xx/project_name_system/src/project_name_system_stm32l0xx_delay_calibration.c.o: in function \\`_project_name_system_testDelayUs':\n/home/user/git/project_name_development/project_name/hal/stm32l0xx/project_name_system/src/project_name_system_stm32l0xx_delay_calibration.c:232: undefined reference to \\`LL_GPIO_DeInit'\ncollect2: error: ld returned 1 exit status\nninja: build stopped: subcommand failed.\nBuild finished with error(s).\n\n\n\n\n\"",
            "problemMatcher": [
                "$gcc",
                "$gcc_linker",
                {
                  "owner": "linker0",
                  "severity": "error",
                  "fileLocation" : "absolute",
                  "pattern": {
                    "regexp": "((error): ld returned (-?\\d+) exit status)",
                    "message": 1,
                    "file" : 2
                  }
                },
                {
                  "owner": "linker1",
                  "severity": "error",
                  "fileLocation" : "absolute",
                  "pattern": {
                    "regexp": "(\\S*\\.cp{0,2}):(\\d*):\\s(undefined reference to `\\S*')",
                    "file": 1,
                    "line": 2,
                    "message": 3
                  }
                },
                {
                  "owner": "linker2",
                  "severity": "error",
                  "fileLocation" : "absolute",
                  "pattern": {
                    "regexp": "((.*\\.cp{0,2}):(\\d+): (multiple definition of .+);.+:(.*\\.cp{0,2}):(\\d+): first defined here)",
                    "message": 4,
                    "file": 2,
                    "line": 3
                  }
                },
                {
                  "owner": "linker3",
                  "severity": "error",
                  "fileLocation" : "absolute",
                  "pattern": {
                    "regexp": "((.*\\.cp{0,2}):(\\d+): (multiple definition of .+);.+:(.*\\.cp{0,2}):(\\d+): first defined here)",
                    "message": 4,
                    "file": 5,
                    "line": 6
                  }
                },
                {
                  "owner": "linker4",
                  "severity": "error",
                  "fileLocation" : "absolute",
                  "pattern": {
                    "regexp": "((cannot open linker script file (.+.ld): No such file or directory))",
                    "message": 1,
                    "file": 3
                  }
                },
                {
                  "owner": "linker5",
                  "severity": "error",
                  "fileLocation" : "absolute",
                  "pattern": {
                    "regexp": "((region `\\S+' overflowed by \\d+ bytes))",
                    "message": 1
                  }
                }
            ],
        },
    ]
}