microsoft / vscode-cpptools

Official repository for the Microsoft C/C++ extension for VS Code.
Other
5.54k stars 1.57k forks source link

Launching of custom GDB does not correctly set CWD (breaks relative paths) #815

Open ronanpaixao opened 7 years ago

ronanpaixao commented 7 years ago

I'm trying to debug an STM32 microcontroller through OpenOCD in VSCode 1.13.0 on Windows 10.

I have this launch.json:

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "ARM GDB Launch",
            "logging": { "trace": true, "traceResponse": true, "engineLogging": true },
            "type": "cppdbg",
            "request": "launch",
            "args": [],
            "stopAtEntry": true,
            "cwd": "${workspaceRoot}",
            "environment": [],
            "externalConsole": true,
            "MIMode": "gdb",
            "program": "${workspaceRoot}/BUILD/DISCO_F407VG/GCC_ARM/tracker.elf",
            "windows": {
                "miDebuggerPath": "arm-none-eabi-gdb.exe"
            },
            "linux": {
                "miDebuggerPath": "arm-none-eabi-gdb"
            },
            "miDebuggerServerAddress": "localhost:3333",
            "targetArchitecture": "arm",
            "customLaunchSetupCommands": [
                {
                    "description": "Set remote target",
                    "text": "file BUILD/DISCO_F407VG/GCC_ARM/tracker.elf"
                },
                {
                    "description": "Set remote target",
                    "text": "target remote localhost:3333"
                },
                {
                    "description": "Set hardware breakpoints",
                    "text": "set remote hardware-breakpoint-limit 6"
                },
                {
                    "description": "Set hardware breakpoints",
                    "text": "set remote hardware-watchpoint-limit 4"
                },
                {
                    "description": "Reset 1",
                    "text": "monitor reset halt"
                },
                {
                    "description": "Load code",
                    "text": "load"
                },
                {
                    "description": "Reset 2",
                    "text": "monitor reset halt"
                }
            ]
        }
    ]
}

However, this doesn't work. I get the following error:

Unable to start debugging. Unexpected GDB output from command "-interpreter-exec console "file BUILD/DISCO_F407VG/GCC_ARM/tracker.elf"". BUILD/DISCO_F407VG/GCC_ARM/tracker.elf: No such file or directory.

However, the file is there, and if I use the full path, it works. (I do consider it bad practice to use full paths in any code, specially code that others might use).

Since it looked like a path problem, I launched SysInternals' Process Explorer and tried to find the arm-none-eabi-gdb.exe process. I found that its Current directory field is just empty! Screenshot:

image

One workaround that I found, at least until the bug is fixed, is to create a batch (.bat) with this content:

@arm-none-eabi-gdb.exe %*

Then I changed the miDebuggerPath setting to:

                "miDebuggerPath": "${workspaceRoot}/wingdb.bat"

Where wingdb.bat is the name of the file I just created.

Curiously, this does work, which suggests that VSCode is not properly setting the debugger's current directory properly.

pieandcakes commented 7 years ago

@ronanpaixao I think you are looking at two different issues. We set current working directory for gdb inside gdb using -environment-cd and your "cwd" value. This should be enough for gdb to figure out where your program is, but it doesn't look like it is working in this instance.

The code where we set the current directory is here and it looks like we are trying to set it to the directory of the debugger executable.

ivankravets commented 7 years ago

The same issue. We have own GDB wrapper which depends on real $workspaceRoot. However, VSCode starts custom /path/to/custom/bin/gdb from/path/to/custom/bininstead of$workspaceRootwhich is declared incwd`.

How to resolve it?

pieandcakes commented 7 years ago

@ivankravets Please post your launch.json. If you set cwd, we set it to that value. If you want to call a different gdb instead of /usr/bin/gdb you can specify "miDebuggerPath" to use a different gdb. Or you can use his example above and create a bash script.

ivankravets commented 7 years ago

@pieandcakes You don't use cwd when spawning a process. Here is hidden a bug.

proc.StartInfo.WorkingDirectory = options.DebuggerMIMode == MIMode.Lldb ? options.WorkingDirectory : miDebuggerDir;

The process should start with CWD which we ask in launch.json.

pieandcakes commented 7 years ago

@ivankravets From my understanding, 'gdb' uses -environment-cd command to set that. If you look at: https://sourceware.org/gdb/onlinedocs/gdb/GDB_002fMI-Program-Context.html and search for -environment-cd it tells me that the command will set the working directory. If your gdb isn't doing that, then please file a bug against gdb. The reason we have that case for lldb is that lldb doesn't support that command.

ivankravets commented 7 years ago

There is no problem in GDB. Why did you decide that cwd should be related to GDB? This is an independent option which instructs further processes to be launched from a specified directory. That is very important for us. See https://github.com/Microsoft/vscode-cpptools/issues/763#issuecomment-316802590

/dynamic/path/to/piodebuggdb - this is not GDB, this our PlatformIO Unified Interface, and it requires to be started from a project directory (cwd). Other option, you can instruct it to use custom project directory via platformio debug --project-dir /path/to/platformio/project --interface=gdb. But... Your manifest doesn't allow to customize miPath with extra arguments.

Please take a look at other IDEs, for example Eclipse. They use cwd for process spawning.

pieandcakes commented 7 years ago

@ivankravets We use "MI Interpreter mode" to talk to our debuggers. Based on the mode we support, the correct way of setting the working directory was -environment-cd command. We added lldb support after the fact and we made changes to ensure that would also work. As MIEngine code is open source, you are welcome to submit and suggest a change and have all the parties sign off on it.

It seems like you are using our extension for a special case, which is great, but it probably isn't going to work out of the box. If you would like to help extend the functionality to support other debuggers, you are welcome to.

ivankravets commented 7 years ago

If you would like to help extend the functionality to support other debuggers, you are welcome to.

That is simple. It already works when I manually fix a VSCode C/C++ debug bug where I hardcode project directory in our custom debugger.

How is difficult to start mi's process from cwd? Yes, you can later pass later extra mi commands. This will not break your code.

ivankravets commented 7 years ago

@robotdad , @pieandcakes

How many months do you need to fix URGENT BUG with incorrect handling of cwd before spawning GDB process?

pieandcakes commented 7 years ago

@ivankravets The reason this has not been resolved is we are unsure what would happen to the working scenarios if this change were made. You can work around this by creating a script file that contains a call to cd <directory> before executing your platformio program.

ivankravets commented 7 years ago

URGENT

@pieandcakes have you tried it?

Debugger executable '/private/tmp/piodebug.sh' is not signed. As a result, debugging may not work properly.

/cc @robotdad

robotdad commented 7 years ago

Is that just an informational message or does it actually block? If it is just informational that seems like enough for validating, then you could sign when done and the message would go away.

@ronanpaixao have you been able to get your scenario working?

pieandcakes commented 7 years ago

@ivankravets We added that message because people did not know that the debugger executable needed to be signed and some platforms, the OS does not allow debug/attaching to another process without signing. We do basic signing verification. if the script works outside the extension, you should be fine. Our extension just gives you the informational warning

ivankravets commented 7 years ago

Is that just an informational message or does it actually block? If it is just informational that seems like enough for validating, then you could sign when done and the message would go away.

@robotdad , how do you recommend me "you could sign" Shell Script which @pieandcakes recommends as a "crutch" because cwd option does not work properly?

The same problem with our GDB binary which we don't build. It will be automatically built by Python Package Manager (pip) when a user installs PlatformIO Core. Our GDB is virtual backend between different debug interfaces and debug servers.

Thanks.

robotdad commented 7 years ago

I feel like the signing issue here is orthogonal to the cwd issue. We should probably open a new issue on that. I'm guessing we would enforce signing on mac and windows but not Linux.

@ivankravets did your script work though? If so we can work through the signing issue on a new issue and resolve this one. I tend to agree with @pieandcakes that changing the existing behavior sounds risky but I'll ask some others for comment as well.

pieandcakes commented 7 years ago

I feel like the signing issue here is orthogonal to the cwd issue. We should probably open a new issue on that. I'm guessing we would enforce signing on mac and windows but not Linux.

We (the extension) aren't enforcing signing. Mac OS X does the enforcing. The warning is just an informational message we pass to warn you (the user) that the executable (script, binary, etc) you are running is not signed. It's a warning since we have had users of gdb on Mac not realize that their binary needed to be signed to debug a process and Mac's error message was not very helpful. We as the debug adapter don't verify the signature or do any enforcement around it.

ivankravets commented 6 years ago

@robotdad

We should probably open a new issue on that

Thanks! Done: https://github.com/Microsoft/vscode-cpptools/issues/1740

snahmad commented 5 years ago

I am getting this error No symbol table is loaded. Use the "file" command

I did try this

{ "type": "gdb", "request": "attach", "name": "Attach to gdbserver", "executable": "../bin/squiddebug/pip", "target": "192.168.43.68:1234", "remote": true, "cwd": "${workspaceRoot}", "valuesFormatting": "parseText", "gdbpath": "/home/syeda/workspace/work/build/multigw_cpp_1.3.12/host/usr/arm-buildroot-linux-gnueabi/sysroot/bin/arm-buildroot-linux-gnueabi-gdb", "additionalSOLibSearchPath": "/home/syeda/workspace/apps-zwave-source/lib/squiddebug" "customLaunchSetupCommands": [ { "description": "Enable pretty-printing for gdb", "text": "file /home/syeda/workspace/apps-zwave-source/bin/squiddebug/pip", } ] }

pieandcakes commented 5 years ago

@snahmad we aren't the extension that provides "type": "gdb". Please check your installed extensions and contact that extension owner. Our extension provides "type": "cppdbg".

snahmad commented 5 years ago

ok, who is extension owner "type": "gdb" for remote debugging.

pieandcakes commented 5 years ago

You need to go to your VS Code install, go to the extensions page and identify it.

My search on the VS Code Extension Gallery brings up a few options

sherief commented 4 years ago

I came here because I'm running into this same exact issue and I think a monument should be built somewhere for someone because it has been three years and "Fix embedded debugging on Windows by simply respecting the current working directory" is still an unresolved issue, it's like watching 12 Angry Men meets Dr. Strangelove.

wc7086 commented 2 years ago

Does anyone plan to fix this?

vittorioromeo commented 2 years ago

Still broken.

totszwai commented 1 year ago

Still experiencing the same issue, CWD is not set.