When setting a breakpoint in a file with a particular name, breakpoints are set in all files with that file name at the same line.
Win 10
VSCode 1.15 stable build
C/C++ 0.12.2
No other extension installed.
Gdb 7.6.1 is from mingw32
Gcc 5.3.0 is from mingw32
Create the following project layout:
src
|- main.c
|- folder
|- main.c
That is, there are two main.c files. One directly in src:
int foo();
int main(int argc, char *argv[])
{
int a = 0;
a += 3;
a *= 4;
foo();
return 0;
}
The other in src/folder:
int foo()
{
int b = 14;
int d = 13;
b += d - b * d;
return b + d;
}
In both files, line 5 contains executable code.
Compile from within src:
gcc main.c folder/main.c -g -O0 -o a.exe
Add launch.json:
{
"version": "0.2.0",
"configurations": [
{
"name": "(gdb) Launch",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceRoot}/src/a.exe",
"args": [],
"stopAtEntry": false,
"cwd": "${workspaceRoot}",
"environment": [],
"externalConsole": true,
"MIMode": "gdb",
"miDebuggerPath": "C:\\MinGW\\bin\\gdb.exe",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
]
}
]
}
Set breakpoint in src/main.c at line 5. Launch debugger, it breaks in main, hit continue and it will break in foo (which it should not).
The above setup:
"debug.allowBreakpointsEverywhere": true
c_cpp_properties.json is not in use and launch.json is given above.
@pieandcakes Could you please elaborate on why this is considered a request for a feature?
From my perspective, this looks like a bug, really. I have a project with a few hundred *.c files with the same name (they are mostly generated by another tool) and this makes it very hard to debug them because the debugger breaks at seemingly random places - additional to the line where I did set a breakpoint.
@ZobyTwo When we send the bindings for the breakpoints we are currently only sending the filename. As such, it is "by design" even though it is unintended. There have been changes in MIEngine to allow support of this. I'll mark it as a bug also but either way it will require work on my part to get it to work.
@pieandcakes I see, thanks for the explanation.
I've the same bug/lack of feature as I use cpptools to debug an ARM Processor with multiple cores. As each core gets it's own main.cpp (entrypoint) vscode breaks on every line. Would be nice if this feature/bug could be implemented/resolved.
Is the bug has been resolved ?
Seems to still be a problem (at least in 8.1-0ubuntu3). I tried to get round this by setting the full path name of the file but GDB doesn't like this either. I guess it is not using realpath internally to disambiguate files.
Any ETA or roadmap on this? The breakpoint features seem frozen for so long - data breakpoints, log points.
When we send the bindings for the breakpoints we are currently only sending the filename
I have a possibly related issue based on the quote, the object file is built with prefix_filename so it is missing the breakpoint in filename.c(red, looks set but not hit), is this a symptom of the same issue? Is there a workaround?
I am having the same issue but with the vs debugger and it's quite annoying.
We have a big repository and some files have the same name but in a different path.
When I put a breakpoint in Folder1/Folder2/Util.cpp, all the Util.cpp will break regardless of their paths. This makes the debugger unusable.
This is my launch.json
{
"version": "0.2.0",
"configurations": [
{
"name": "Loader",
"type": "cppvsdbg",
"request": "launch",
"program": "c:/SomeExecutable.exe",
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"externalConsole": true,
}
]
}
@psclkhoury It is on our list for current work planning.
Any updates on this bug?
Thanks!
Hello, I also have this problem under Ubuntu Server 18.04. I hope this will be fixed very soon as it's getting really annoying...
However I don't get it under Windows MSVC.
Also got bitten by this on v1.0.1
3 years later still no fix? @pieandcakes Will you accept a PR for this or is it in the closed source part of the code?
I think it's all open source by now.
You can now specify breakpoints to use full path in v1.1.0 via sourceFileMap.
Example:
"sourceFileMap": {
"<compiler-path>": {
"editorPath": "<source-path>",
"useForBreakpoints": true
}
}
@WardenGnaw Can you give a better example on how to use this? Do I have to do this for each breakpoint I set or what? What are <compiler-path> and <source-path>?
I don't agree with the solution. By default I should be able to set a breakpoint and the full path should be sent to the debug engine without any extra action.
This seems more like a workaround than a fix.
<compile-path> is the path that GDB returns when a breakpoint is hit.
<source-path> is the path that you want to see in the editor.
For scenarios where you do not build on a different machine or move the source files before compiling, <compile-path> and <source-path> will be exactly the same.
With the following, all breakpoints (except the first one the debug adapter uses to break at entry) will be fully qualified.
E.g.
"sourceFileMap": {
"C:\Path\To\Project\Root": {
"editorPath": "C:\Path\To\Project\Root",
"useForBreakpoints": true
}
}
By default I should be able to set a breakpoint and the full path should be sent to the debug engine without any extra action.
We decided not make this a default because there are projects that users have debug bits but do not have the source code. This would cause the breakpoint bind to fail.
Here is the related code in the Debug Adapter:
https://github.com/microsoft/MIEngine/blob/73db59d89b8f0fbfdaa3cee1423e674e092ffc0f/src/MIDebugEngine/Engine.Impl/Breakpoints.cs#L114-L118
@WardenGnaw I tried:
"sourceFileMap": {
"${workspaceFolder}": {
"editorPath": "${workspaceFolder}",
"useForBreakpoints": true
}
}
And I got an error:

I then tried to put the real path instead of ${workspaceFolder} (so c:/path/to/root) and the breakpoint was set in all files with the same name.
We decided not make this a default because there are projects that users have debug bits but do not have the source code. This would cause the breakpoint bind to fail.
I think most users will never have to deal with that, so it do not understand why the default is chosen according to that very rare scenario.
If someone has debug bits then maybe they can change some setting or add something to the launch.json to make it work, and the normal use cases should work without any user configuration.
Can you enable logging by adding the following to your launch.json and share the -break-insert logs in Debug Console?
"logging": {
"engineLogging": true
}
When doing that, you can filter and check to see if MIEngine is telling GDB to bind with the specific path for files under that path.
Here's an example of two files with the same name foo.cpp in associated folders called A/B under the project D:/Projects/cpp

If it only shows something like -break-insert -f filename.cpp:15, then it could not resolve the path you provided in sourceFileMap.
I do not see any logging with break-insert after enabling the engineLogging. I only see this which has the correct path.

We decided not make this a default because there are projects that users have debug bits but do not have the source code. This would cause the breakpoint bind to fail.
I can't follow. If you don't have the source code you can't set a breakpoint from the code editor, only manually via the breakpoints view and that user input should be passed on as-is.
Anyway can't the debug adapter decide on its own if a full path is ok, like with File.Exists or whatever?
@WardenGnaw Can we reopen this issue? The solution is not working for me.
Most helpful comment
Any updates on this bug?
Thanks!