eclipse-cdt-cloud / cdt-gdb-adapter

CDT GDB Debug Adapter
Eclipse Public License 2.0
27 stars 40 forks source link

How to format interactive commands in initCommands? #308

Closed XingMicrochip closed 8 months ago

XingMicrochip commented 8 months ago

Hi,

We have a launch configuration that needs to use interactive commands as part of the initCommands. Currently, we did it as follows:

            "initCommands": [
                "define custom_variable\nsome_value\nend",
                ...
            ],

During testing on Windows, we discovered that this format did not work - The adapter stuck at this interactive command and did not proceed. The relevant part of the debug log file looks like this:

...
[16:49:03.270 UTC] To client: {"seq":0,"type":"event","event":"output","body":{"category":"console","output":"connected to remote target localhost:50713"}}
[16:49:03.270 UTC] GDB command: 6 define custom_variable
some_value
end
[16:49:03.272 UTC] To client: {"seq":0,"type":"event","event":"output","body":{"category":"log","output":"define custom_variable\n"}}
[16:49:03.272 UTC] To client: {"seq":0,"type":"event","event":"output","body":{"category":"stdout","output":">"}}
[16:49:03.275 UTC] To client: {"seq":0,"type":"event","event":"output","body":{"category":"stdout","output":">"}}
(Nothing afterwards)

What is weird was define custom_variable\nsome_value\nend worked on Linux. But another interactive command got stuck on Linux. So I was suspecting that we provided the command in the wrong format - i.e. we should not use \n to chain them - or maybe currently cdt-gdb-adapter does not properly support sending interactive commands, so the behavior is undefined. I tried putting them as three separate commands - i.e. define custom_variable, some_value, and end - but we also got stuck at command define ... because it does not complete before receiving end. Before I look into the source code, I just want to check: Does the cdt-gdb-adapter currently have support for including this kind of command (e.g. define) as initCommands?

jonahgraham commented 8 months ago

Does the cdt-gdb-adapter currently have support for including this kind of command (e.g. define) as initCommands?

Short answer is no. I'm not surprised this didn't work as I wouldn't expect interactive parts of GDB work when connected via MI from the adapter. My guess is it worked on Linux because we just send the lines and it happened to work. It may work on Windows with \r\n newlines?

Do you have something working in another environment (e.g. Eclipse CDT)? I don't know how we would setup interactive commands, but it may be nice to have.

Of course I think the workaround of using source which avoids the need to use interactive mode, and probably is easier to read than long strings with \n. It has the disadvantage of needing to manage another file.

Perhaps instead of initCommands run as individual commands passed to GDB, the contents of the array could be stored in a file and then source used to run them all.

WDYT?

XingMicrochip commented 8 months ago

I tried using \r\n on Windows, but this did not work. I think the behavior is undefined - I tried moving define ...\n...\n to not be the first command to run in initCommands and this time it always works on Windows (Linux doesn't require this). But other commands such as commands $bpnum\nsome_command\nend still did not work on either Linux or Windows, even if I tried putting them at different orders.

I will try the source approach.

jonahgraham commented 8 months ago

I will try the source approach.

Sounds like a good idea.

Do you have something working in another environment (e.g. Eclipse CDT)?

XingMicrochip commented 8 months ago

What do you mean by Eclipse CDT?

jonahgraham commented 8 months ago

The c/c++ part of Eclipse as documented here https://microchipdeveloper.com/atstart:eclipse (the source is https://github.com/eclipse-cdt/cdt) and it is a related project to the adapter project as the same team developed both (at different times)

XingMicrochip commented 8 months ago

I will try the source approach.

Sounds like a good idea.

Do you have something working in another environment (e.g. Eclipse CDT)?

I haven't tried using a different environment.

XingMicrochip commented 8 months ago

Of course I think the workaround of using source which avoids the need to use interactive mode, and probably is easier to read than long strings with \n. It has the disadvantage of needing to manage another file.

Perhaps instead of initCommands run as individual commands passed to GDB, the contents of the array could be stored in a file and then source used to run them all.

Can you elaborate on this? Here is what I tried: I created a file called initCommands.txt. Here is the content of the file:

command
p 123
p 456
p 789
end

Then under the launch configuration file I put,

            "initCommands": [
                "source path_to_file/initCommands.txt"
            ],

Still the adapter got stuck. From the debug console log we suspected end was never received / parsed so command command kept on waiting for end. Is this a bug with the adapter code? It is very weird because we tried something else and if there was no commands in between, it will work. So the following will work - which was why we think this is a bug:

command
end
jonahgraham commented 8 months ago

Seems unlikely to be a adapter issue based on your description. Can you reproduce this in gdb run manually? Especially in mi mode?

jonahgraham commented 8 months ago

To clarify my last comment. Because source is a gdb command, if the gdb command isn't returning that seems like an issue outside what the adapter can handle.

One small thing to check is that there is a newline at the end of the file.

XingMicrochip commented 8 months ago

I tried the gdb command source .../initCommands.txt manually on gdb. The command returned successfully. But when running from the IDE, it always gets stuck. Here is the exact command file I used:

b main
commands
  monitor sys_prj Dispose
end

Whenever it gets stuck in the IDE, the debug log looks like one of the following two - which also confused me because I don't understand why the output is non-deterministic. Debug log 1:

[14:38:19.764 UTC] GDB command: 6 source C:\Microchip\initCommands.txt
[14:38:19.764 UTC] To client: {"seq":0,"type":"event","event":"output","body":{"category":"log","output":"source C:\\Microchip\\initCommandsWindowsLineEndings.txt\n"}}
[14:38:19.832 UTC] To client: {"seq":0,"type":"event","event":"output","body":{"category":"stdout","output":"Breakpoint 1 at 0x8000150c: file C:/Microchip/..., line 2029.\n"}}
(Nothing after...got stuck)

Debug log 2:

[14:39:30.865 UTC] GDB command: 6 source C:\Microchip\initCommands.txt
[14:39:30.865 UTC] To client: {"seq":0,"type":"event","event":"output","body":{"category":"log","output":"source C:\\Microchip\\initCommandsWindowsLineEndings.txt\n"}}
[14:39:30.932 UTC] To client: {"seq":0,"type":"event","event":"output","body":{"category":"stdout","output":"Breakpoint 1 at 0x8000150c: file C:/Microchip/..., line 2029.\n"}}
[14:39:30.932 UTC] GDB notify async: breakpoint-created,bkpt={number="1",type="breakpoint",disp="keep",enabled="y",addr="0x8000150c",func="main",file="C:/Microchip/...",fullname="C:\\Microchip\\...",line="2029",thread-groups=["i1"],times="0",original-location="main"}
[14:39:30.932 UTC] GDB unhandled notify: breakpoint-created: {"bkpt":{"number":"1","type":"breakpoint","disp":"keep","enabled":"y","addr":"0x8000150c","func":"main","file":"C:/Microchip/...","fullname":"C:\\Microchip\\...","line":"2029","thread-groups":["i1"],"times":"0","original-location":"main"}}
(Nothing after...got stuck)

Do you have any idea what might cause this particular command file to not work from the IDE through the adapter? Since this command file worked from manual gdb run I also don't understand why it didn't work from the IDE - because from the log file you can see the correct source command was sent to gdb.

jonahgraham commented 8 months ago

Very weird. Can you provide some more info about environment? Eg gdb version? And can you also provide log of gdb when run at the command line in mi mode as a comparison, from the launching of gdb?

jonahgraham commented 8 months ago

I have reproduced the problem and it has shown that the MI parser hangs with the script (commands) part of a breakpoint. See #311 for that issue

jonahgraham commented 8 months ago

In conclusion, with the fix in #313 (thanks @XingMicrochip!), you can do a source commands in initCommands like this in the launch.json:

      "initCommands": ["source ${workspaceFolder}/script"],