vscode-cpptools icon indicating copy to clipboard operation
vscode-cpptools copied to clipboard

Hex/Binary display of debug variables in C++

Open nilanjan opened this issue 8 years ago • 36 comments

OS - Linux and Mac

Hex (Octal, Binary etc.) display of variables in watch or variable window in debug is not available. This is absolutely imperative for the C++ developers.

Please provide support.

nilanjan avatar Mar 13 '17 14:03 nilanjan

@nilanjan I'll add it to the backlog but in the meantime you can use the gdb-mi command: -var-set-format in the debugConsole by typing -exec -var-set-format <name of variable> <format>. The difficulty we have is offering context menu options to allow the change of the format, which would require VSCode changes. You can also add the variable specifiers in the watch window to change the format.

This is the same request as #319

pieandcakes avatar Mar 13 '17 18:03 pieandcakes

Does it work for lldb too?

nilanjan avatar Mar 13 '17 22:03 nilanjan

@nilanjan I don't have my MacBook with me but I can try it tomorrow and let you know.

pieandcakes avatar Mar 13 '17 23:03 pieandcakes

Tried this on MacBook, but this does not work. Got following message.

Driver. Received command '45-exec -var-set-format hex'. It was not handled. Command 'exec' not in Command Factory (from exec -var-set-format hex)_

thecoder138 avatar Mar 15 '17 15:03 thecoder138

Any update on this? This is significantly affecting productivity. Can you point where to add this feature?

nilanjan avatar Apr 13 '17 23:04 nilanjan

How do I specify the variable name with the below command in the debug console? -exec -var-set-format

If I use the above command while on a breakpoint (using gbg) I always get the error "msg: Variable object not found" but adding the variable name to the watch window works.

Numinel avatar Jun 16 '17 09:06 Numinel

@Numinel Are you doing this on Mac or Linux?

So the format of -var-set-format seems to be -var-set-format <NAME> <FORMAT> where name is the automatic variable name assigned by gdb/lldb.

I enabled "logging": { "engineLogging": true } and I looked for the lines where -var-create was called for Variables and the response will have the <NAME> that you need to specify.

1: (918) <-1023-var-create - * "a" 1: (928) ->1023^done,name="var1",numchild="0",value="0",type="int",thread-id="1",has_more="0"

So for instance, my variable here is a and it is expecting <NAME> to be "var1".

pieandcakes avatar Jun 16 '17 19:06 pieandcakes

I use Linux. The log show that my variable is mapped to the internal name "var29" and when using the command '-exec -var-set-format "var29" hex' the output will be shown as hexadecimal. It was unclear to me that I had to use a different name that the variable name.

Adding a variable to the watch window with ",h" is way better though.

Numinel avatar Jun 19 '17 14:06 Numinel

Is there any timeline for this feature implementation?

nilanjan avatar Jun 30 '17 14:06 nilanjan

@nilanjan Not at this time. If you feel like it is something you would like to contribute we welcome community support. You can find source code at: https://github.com/Microsoft/MIEngine.

pieandcakes avatar Jun 30 '17 19:06 pieandcakes

This feature has been on the backlog for a while now, any plans to resurrect this feature request from the dead?

EmbeddedBacon avatar Nov 19 '19 00:11 EmbeddedBacon

When I enabled the logging to decipher the transposed variable name the out on the Debug Console shows me the value in hex, but the Variable in the Debug tab still remains as decimal

-exec -var-set-format var158.param1 hexadecimal 1: (1205572) <-1599-var-set-format var158.param1 hexadecimal 1: (1205573) ->1599^done,format="hexadecimal",value="0xffffff01" 1: (1205573) ->(gdb) 1: (1205573) 1599: elapsed time 1 result-class: done format: hexadecimal value: 0xffffff01

From this particular experiment this is not a viable long term work around

EmbeddedBacon avatar Nov 19 '19 01:11 EmbeddedBacon

@EmbeddedBacon That is the expected behavior. If you change the var-set-format, it will change it for all future calls but existing data is not updated as the UI hasn't requested to refresh yet.

We don't have a gesture in the UI to change the value and I haven't had time to investigate if VS Code's extensibility contains the ability to add this feature.

pieandcakes avatar Nov 19 '19 19:11 pieandcakes

@pieandcakes Thanks for the info, but I still couldn't get it to work. This will not work with Locals under Variables since I don't control those. I did try this in the Watch panel, but this doesn't seem to work correctly. I also noticed the translated variable is always changing. In one case the varible "pFsaCmd" was initially var39, then var40, then var42, then var43, then etc. If I didn't have pFasCmd in the Watch panel, then after trying to set its format. I tried setting the format to pFasCmd and pFasCmd.param1, but unfortunately neither worked for me. I am not sure what I am doing wrong.

Here is the output from the Debug Console. If I were to look into this, what area of the code base would I look at?

MI Log
1: (1213357) ->(gdb)
1: (1213357) 1296: elapsed time 1
1: (1213357) <-1297-var-create - * "pFsaCmd"
1: (1213363) ->1297^done,name="var39",numchild="5",value="0xaa57d4c <ddrMemory+18033228>",type="VsFsaOperateReq_t *",thread-id="137",has_more="0"
1: (1213363) ->(gdb)
1: (1213363) 1297: elapsed time 5
1: (1213637) <-1298-stack-list-variables 0
1: (1213637) ->1298^done,variables=[{name="pFsaCmd"},{name="status"}]
1: (1213638) ->(gdb)
1: (1213638) 1298: elapsed time 0
1: (1213638) <-1299-var-create - * "pFsaCmd"
1: (1213643) ->1299^done,name="var40",numchild="5",value="0xaa57d4c <ddrMemory+18033228>",type="VsFsaOperateReq_t *",thread-id="137",has_more="0"
1: (1213643) ->(gdb)
1: (1213643) 1299: elapsed time 4
1: (1213643) <-1300-var-create - * "status"
1: (1213644) ->1300^done,name="var41",numchild="0",value="VS_STAT_COMMAND_SUCCESS",type="VsProtocolStatusCode_t",thread-id="137",has_more="0"
1: (1213644) ->(gdb)
1: (1213644) 1300: elapsed time 1
1: (1213728) <-1301-var-list-children --simple-values "var40" 0 1000
1: (1213734) ->1301^done,numchild="5",children=[child={name="var40.task",exp="task",numchild="0",value="0",type="uint32_t",thread-id="137"},child={name="var40.param1",exp="param1",numchild="0",value="4294967041",type="uint32_t",thread-id="137"},child={name="var40.param2",exp="param2",numchild="0",value="0",type="uint32_t",thread-id="137"},child={name="var40.param3",exp="param3",numchild="0",value="0",type="uint32_t",thread-id="137"},child={name="var40.data",exp="data",numchild="0",type="uint8_t []",thread-id="137"}],has_more="0"
1: (1213734) ->(gdb)
1: (1213735) 1301: elapsed time 6
-exec -var-set-format var40.param1 hexadecimal
1: (1242036) <-1302-var-set-format var40.param1 hexadecimal
1: (1242037) ->1302^done,format="hexadecimal",value="0xffffff01"
1: (1242037) ->(gdb)
1: (1242037) 1302: elapsed time 0

1: (1242043) <-1303-var-create - * "pFsaCmd"
1: (1242045) ->1303^done,name="var42",numchild="5",value="0xaa57d4c <ddrMemory+18033228>",type="VsFsaOperateReq_t *",thread-id="137",has_more="0"
1: (1242045) ->(gdb)
1: (1242045) 1303: elapsed time 1
1: (1248577) <-1304-var-list-children --simple-values "var42" 0 1000
1: (1248584) ->1304^done,numchild="5",children=[child={name="var42.task",exp="task",numchild="0",value="0",type="uint32_t",thread-id="137"},child={name="var42.param1",exp="param1",numchild="0",value="4294967041",type="uint32_t",thread-id="137"},child={name="var42.param2",exp="param2",numchild="0",value="0",type="uint32_t",thread-id="137"},child={name="var42.param3",exp="param3",numchild="0",value="0",type="uint32_t",thread-id="137"},child={name="var42.data",exp="data",numchild="0",type="uint8_t []",thread-id="137"}],has_more="0"
1: (1248584) ->(gdb)
1: (1248584) 1304: elapsed time 7
1: (1258554) <-1305-var-create - * "pFsaCmd"
1: (1258558) ->1305^done,name="var43",numchild="5",value="0xaa57d4c <ddrMemory+18033228>",type="VsFsaOperateReq_t *",thread-id="137",has_more="0"
1: (1258558) ->(gdb)
1: (1258558) 1305: elapsed time 4
1: (1258567) <-1306-var-create - * "pFsaCmd"
1: (1258571) ->1306^done,name="var44",numchild="5",value="0xaa57d4c <ddrMemory+18033228>",type="VsFsaOperateReq_t *",thread-id="137",has_more="0"
1: (1258572) ->(gdb)
1: (1258572) 1306: elapsed time 4
1: (1261053) <-1307-var-list-children --simple-values "var44" 0 1000
1: (1261060) ->1307^done,numchild="5",children=[child={name="var44.task",exp="task",numchild="0",value="0",type="uint32_t",thread-id="137"},child={name="var44.param1",exp="param1",numchild="0",value="4294967041",type="uint32_t",thread-id="137"},child={name="var44.param2",exp="param2",numchild="0",value="0",type="uint32_t",thread-id="137"},child={name="var44.param3",exp="param3",numchild="0",value="0",type="uint32_t",thread-id="137"},child={name="var44.data",exp="data",numchild="0",type="uint8_t []",thread-id="137"}],has_more="0"
1: (1261060) ->(gdb)
1: (1261060) 1307: elapsed time 7
1: (1268111) <-1308-var-create - * "part"
1: (1268126) ->1308^error,msg="-var-create: unable to create variable object"
1: (1268126) ->(gdb)
1: (1268126) 1308: elapsed time 14
-exec -var-set-format var40 hexadecimal
1: (1390499) <-1309-var-set-format var40 hexadecimal
1: (1390500) ->1309^done,format="hexadecimal",value="0xaa57d4c"
1: (1390500) ->(gdb)
1: (1390500) 1309: elapsed time 0

1: (1402256) <-1310-var-create - * "pFsaCmd"
1: (1402260) ->1310^done,name="var46",numchild="5",value="0xaa57d4c <ddrMemory+18033228>",type="VsFsaOperateReq_t *",thread-id="137",has_more="0"
1: (1402260) ->(gdb)
1: (1402260) 1310: elapsed time 4
1: (1402270) <-1311-var-create - * "pFsaCmd"
1: (1402271) ->1311^done,name="var47",numchild="5",value="0xaa57d4c <ddrMemory+18033228>",type="VsFsaOperateReq_t *",thread-id="137",has_more="0"
1: (1402271) ->(gdb)
1: (1402271) 1311: elapsed time 1
1: (1404271) <-1312-var-list-children --simple-values "var47" 0 1000
1: (1404278) ->1312^done,numchild="5",children=[child={name="var47.task",exp="task",numchild="0",value="0",type="uint32_t",thread-id="137"},child={name="var47.param1",exp="param1",numchild="0",value="4294967041",type="uint32_t",thread-id="137"},child={name="var47.param2",exp="param2",numchild="0",value="0",type="uint32_t",thread-id="137"},child={name="var47.param3",exp="param3",numchild="0",value="0",type="uint32_t",thread-id="137"},child={name="var47.data",exp="data",numchild="0",type="uint8_t []",thread-id="137"}],has_more="0"
1: (1404278) ->(gdb)
1: (1404278) 1312: elapsed time 7

EmbeddedBacon avatar Nov 20 '19 00:11 EmbeddedBacon

@EmbeddedBacon if you are trying to view just a few items as hex for gdb, you can add to the watch window as <variable>,x where x is the hex format and it should give you the value correctly.

Every time a -var-create is issued, the name assigned to it is new. When you step and a stackwalk is performed, this causes all the variables to be refreshed and in that instance the variable names are also refreshed.

As a reference, here is the documentation for variables through mi commands`. The problem is unless we have a way for the user to ask for it in the UI, we don't have a way to know to change the value. VS Code has an open issue https://github.com/Microsoft/vscode/issues/28025 which should be upvoted so they can add the gesture in the UI.

Depending if they make it a global or per variable flag, we would need to do work to let the Eval call know that we want something other than the gdb default.

pieandcakes avatar Nov 20 '19 18:11 pieandcakes

For watch variables and natvis you can use format specifiers. See microsoft/MIEngine#1031.

Trass3r avatar Aug 26 '20 13:08 Trass3r

https://github.com/microsoft/vscode/issues/70377 https://code.visualstudio.com/api/references/contribution-points#contributes.menus seem that vscode has add something to invest debugging view. it's time to pick it up

heartacker avatar Sep 01 '20 02:09 heartacker

https://code.visualstudio.com/updates/v1_49#_contributable-context-menu-for-variables-view looks like delicious on 1.49.0 image

heartacker avatar Sep 10 '20 23:09 heartacker

FYIScreenshot_2020-11-06-08-25-43-271_GitHub.png

heartacker avatar Nov 06 '20 00:11 heartacker

You should link to it instead of posting a screenshot: https://github.com/microsoft/vscode/issues/28025#issuecomment-722687806

Trass3r avatar Nov 06 '20 02:11 Trass3r

Today I had this problem too. 'b'(binary) and 'o'(octal) both work, but, 'x' or 'h' dosen't work, I work on C++ on Linux. Any updates?

windweed avatar Mar 12 '21 08:03 windweed

I'm also seeing that ,x and ,h don't work but the rest of them do work.

danielbee avatar Mar 15 '21 23:03 danielbee

Which version of gdb are you using? Also you can check what's going on with the debug launch options:

			"logging": {
				"engineLogging": true
			},

Trass3r avatar Mar 17 '21 12:03 Trass3r

@Trass3r My gdb version: 7.3.1. I'll try that "engineLogging" option tomorrow. Thanks. Maybe it's because my gdb's version is too low ? I'll try a higher version on Fedora33 later

windweed avatar Mar 17 '21 12:03 windweed

Indeed, it may not support the format specifier.

Trass3r avatar Mar 17 '21 14:03 Trass3r

I can also try the logging when j get a chance. Note that doing ,b does work and I see the variable in binary. I'm also able to just use the debug console to print my variable in hex with -exec p/x <var_name>.

danielbee avatar Mar 17 '21 20:03 danielbee

Well binary wasn't implemented before so it looks like my https://github.com/microsoft/MIEngine/pull/1031/files got silently integrated by now. I can only imagine your gdb version not supporting zero-hexadecimal. Please try -exec p/z.

Trass3r avatar Mar 17 '21 21:03 Trass3r

Yeah -exec p/z doesn't work on my GDB.

Does this mean your changes actually always use p/z (var,z) even if we only specify ,x which is supported as p/x?

danielbee avatar Mar 17 '21 21:03 danielbee

There is no ,z in https://docs.microsoft.com/en-us/visualstudio/debugger/format-specifiers-in-cpp. Yes ,x maps to /z which seems to have been introduced in 7.11, available even in Ubuntu 16.04.

Trass3r avatar Mar 18 '21 13:03 Trass3r

Yeah I'm using GNU gdb (GDB) Red Hat Enterprise Linux 7.6.1-110.el7. Is there any chance of this changing? p/x gives the functionality that I'd want, and the error message when i try ,x is slightly misleading.

image I have correctly specified ,x for hexadecimal. But because my GDB is outdated and doesn't support /z, I get this error message.

At least, I think we should catch this scenario and say something like: "To display hexadecimal values in watch. Please use a GDB version >= 7.11" Then link to some documentation that explains the workaround to use the debug console directly with /x.

danielbee avatar Mar 18 '21 13:03 danielbee