Marus / cortex-debug

Visual Studio Code extension for enhancing debug capabilities for Cortex-M Microcontrollers
MIT License
1.01k stars 240 forks source link

Watch window can't handle certain expressions #157

Closed haneefdm closed 5 years ago

haneefdm commented 5 years ago

Lots of times, we want to cast and display a value represented by that expression. It appears, that normal variables are working but not expressions (valid C, btw)

Something like this should work... and does work using the basic cppdbg MS extension

*(unsigned int *)(0x40320000) --> Display in natural format
*(unsigned int *)(0x40320000),h --> Display in hex format

Trouble is that the basic expression does not work. I see in the Debug Console, the following

30-var-update --all-values watch_*(unsigned int *)(0x40320000)
GDB -> App: {"token":30,"outOfBandRecord":[],"resultRecords":{"resultClass":"error","results":[["msg","-var-update: Usage: [PRINT_VALUES] NAME."]]}}

I don't believe we are using the right way of evaluating/watching expressions with gdb. I could be super wrong

I can look into it soon, but wanted to file an issue so that I can keep track. I see Issue #58 as well.

I wanted to know if I am using it wrong or someone has a better workaround?

haneefdm commented 5 years ago

Instead of using 'var-update', perhaps it is better to use 'var-create'. Maybe also quote the variable name. This is what I see what other debuggers are doing and seems to work...

-var-create - * "*(unsigned int *)(0x40320000)"

It takes care of scope & frame. Thing is that it creates a new variable but its expression is evaluated every time you request it. Optionally, you can name the variable yourself and use as a short-cut, may not be worth the pain/code.

Opinions? Feels like I am talking to myself :-)

minkir014 commented 5 years ago

I want to understand what is your problem correctly you that expressions like

(unsigned int )(0x40320000) --> Display in natural format (unsigned int )(0x40320000),h --> Display in hex format

not working....

haneefdm commented 5 years ago

@minkir014, yes, that expression does not work in the watch window with cortex-debug. Works fine using the vscode-cpptools debugger.

Marus commented 5 years ago

I don't think it has to do with var-create vs var-update - var-create should be used initially once to create the variable reference - and the var-update is used to actually get it to re-evaluate the named variable.

I think there are likely two parts to this: One is related to the GDB MI interface - first there are some limitations to the expressions you can provide in particular (copied from the GDB documentation at https://ftp.gnu.org/old-gnu/Manuals/gdb/html_node/gdb_231.html):

expression is any expression valid on the current language set *(must not begin with a ``)**, or one of the following:

So GDB is trying (and failing) to interpret your expression as an address.

Additionally, format specifiers have to be done through a separate command in the MI - which would currently not be handled (you specify the format through a -var-set-format command).

The second part - which may prove to be more of an issue - is that the watch view is provided by VSCode - and we are a bit limited in the format of data that we can provide. I'll do a bit more of an investigation and see what can be improved here.

haneefdm commented 5 years ago

No worries, I will find out why it works in "cppdbg"

Marus commented 5 years ago

So - I've partially fixed this in release v0.2.6 - you can now use one like *(unsigned int *)(0x40320000) successfully. There was a problem with the variable name generation not dealing with all characters that couldn't be used. To fix this I've moved to hashing the expression - which will generate safe, and unique, variable names.

The formatting part is not done yet - but should be fairly easy for me to parse the format strings out of the expressions and call the -var-set-format command - hopefully from there the VSCode restrictions won't cause any issues.

haneefdm commented 5 years ago

What I noticed cppdbg did was to just put the expression in quotes. I don't think they even parsed it. But it was a while ago. I was going to figure it out. But creating a hash as you have done is a pretty good trick too

Marus commented 5 years ago

Yeah - the issue wasn't with the expression (that was in quotes) - but the variable name generation which was flawed in that it could create names with reserved characters; which is why I moved to the hashing - which should prevent collisions (within reason at least) and bad characters.

They would have had to be parsing for the formats - as that has to go into a second command. I actually have the formatting mostly working - the only issue at the moment is that the formatting doesn't properly take effect when you first create the watch - only after the very first update of the value of the watch (because it reads the value in before the set format command has run) - shouldn't be too hard to finish it up - will look at that on Thursday likely - as I have something going on tomorrow.

Marus commented 5 years ago

Oh - do you know what format specifiers cppdbg supports - I'm guessing b, d, h, and o for binary, decimal, hexadecimal, and octal. As those are the formats supported by the GDB MI. Just want to align on the notation with them.

GDBs standard interface supports other options that aren't supported by the MI - but is also a different format than your examples from cppdbg (/x for hex vs ,h).

haneefdm commented 5 years ago

Yes, I was not clear I meant they created the variable names with quotes. I will look into it @marcel. I am not sure where I got the ",h" thing. I think it is a visual studio habit, where both h and x work. No need to do anything beyond what gdb supports.

https://docs.microsoft.com/en-us/visualstudio/debugger/format-specifiers-in-cpp?view=vs-2019

minkir014 commented 5 years ago

@Marus and @haneefdm, why don't you try to know how visual studio use those formatters and provide that here?

Marus commented 5 years ago

Yeah, have it working now; will add ,x as a synonym for ,h as using x to indicate hex is fairly common. Will release this soon once I get a chance.

Marus commented 5 years ago

@minkir014 - Visual Studio's debugger supports a wider range of formats than what can be supported through the GDB MI. For where there is overlap I'm largely using the same formatting strings as visual studio. One slight difference is ,b - in VS they have two variants ,b which shows it with a leading 0b and ,bb that shows it without. GDB always does without - so that is mapped to ,b.

There are some additional formats that VS does that aren't supported by the GDB MI so they won't work.

minkir014 commented 5 years ago

But I think gdb can get some basics like hex, decimal, binary and octal via some formatters either if it was the same as visual studio or others.

Marus commented 5 years ago

@minkir014 - yes and the basic like hex, decimal, binary and octal will be supported - using the same format strings appended to as VS. Just some of the ones that VS supports like UTF encoded string, or scientific notation that do not have GDB equivalents will not be supported.

haneefdm commented 5 years ago

Support what gdb supports should suffice. Sorry for creating the confusion between h and x.

The whole idea of using such an expression was a shortcut to a peripheral register. or an entire memory window. This way can snoop for bit and pieces of the address space. Thank you @Marus

Marus commented 5 years ago

Yeah - I'll push the formatting support out with the next release.

haneefdm commented 5 years ago

I can confirm that the expression without the format specifier does indeed work in the current release. Thanks.

With the change @Marus made for formatting support in the next release, we are golden.

minkir014 commented 5 years ago

So, I think you can close this issue.