Skip to content

debug: Convert bytes to string #1459

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
emil14 opened this issue Apr 28, 2021 · 9 comments
Closed

debug: Convert bytes to string #1459

emil14 opened this issue Apr 28, 2021 · 9 comments
Labels
Debug Issues related to the debugging functionality of the extension. FrozenDueToAge
Milestone

Comments

@emil14
Copy link

emil14 commented Apr 28, 2021

Is your feature request related to a problem? Please describe.
I'm debugging some code that works with the filesystem. My code uses bytes.Buffer and to see what content those bytes have I have to save bytes to real file, but as it terns out with JetBrain's "Goland" I don't have to do so.

Describe the solution you'd like
I would like to see bytes as a string content like Goland does

related to

@gopherbot gopherbot added this to the Untriaged milestone Apr 28, 2021
@emil14
Copy link
Author

emil14 commented Apr 28, 2021

I saw that several related issue was closed and I ask you not to close this one. Goland handles this behaviour and someone could implement this in vscode-go

@hyangah
Copy link
Contributor

hyangah commented Apr 28, 2021

I am using dlv-dap https://github.com/golang/vscode-go/blob/master/docs/dlv-dap.md

  1. Right click on the bytes variable
  2. "Copy as an expression"

Screen Shot 2021-04-28 at 10 28 38 AM

  1. Go to DEBUG CONSOLE and string(<the copied expression>).
    Screen Shot 2021-04-28 at 10 28 44 AM

But I agree that it would be better we can skip this manual step.
And, the way VARIABLES panels present []uint8, []byte... isn't very useful. If I can choose, I'd like to see hex format. @polinasok @suzmue

@hyangah hyangah added Debug Issues related to the debugging functionality of the extension. DlvDAP labels Apr 28, 2021
@hyangah hyangah changed the title Convert bytes to string debug: Convert bytes to string Apr 28, 2021
@polinasok
Copy link
Contributor

polinasok commented May 3, 2021

Using go's print formatters, which one would you like to see? There are:

  1. %x - 48656c6c6f20576f6c7264
  2. %v - [72 101 108 108 111 32 87 111 108 114 100] <====================== current
  3. %#v - []byte{0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x57, 0x6f, 0x6c, 0x72, 0x64}
  4. %s - Hello World

We are getting the inlined value from delve's internal pretty-printer. To modify the inlined value, we would need to either modify it (and then dlv cli would see the same format change) or special case bytes in the dap server.

It might be useful to display all of these options as "children" since it sounds like different users might find different formats useful.

@emil14
Copy link
Author

emil14 commented May 3, 2021

I would like to work with human readable %s formatting :)

@polinasok
Copy link
Contributor

Delve at the top of the tree has the following formatting feature:

(dlv) p hellos
"hello world"
(dlv) p hellob
[]uint8 len: 11, cap: 16, [104,101,108,108,111,32,119,111,114,108,100]
(dlv) p string(hellob)
"hello world"
(dlv) p []byte(hellos)
[]uint8 len: 11, cap: 11, [104,101,108,108,111,32,119,111,114,108,100]
(dlv) p %v hellob
[]uint8 len: 11, cap: 16, [104,101,108,108,111,32,119,111,114,108,100]
(dlv) p %+v hellob
[]uint8 len: 11, cap: 16, [104,101,108,108,111,32,119,111,114,108,100]
(dlv) p %#v hellob
[]uint8 len: 11, cap: 16, [0x68,0x65,0x6c,0x6c,0x6f,0x20,0x77,0x6f,0x72,0x6c,0x64]
(dlv) p %T hellob
[]uint8 len: 11, cap: 16, [uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64]
(dlv) p %X hellob
[]uint8 len: 11, cap: 16, [68,65,6C,6C,6F,20,77,6F,72,6C,64]
(dlv) p %s hellob
[]uint8 len: 11, cap: 16, [%!s(uint64=104),%!s(uint64=101),%!s(uint64=108),%!s(uint64=108),%!s(uint64=111),%!s(uint64=32),%!s(uint64=119),%!s(uint64=111),%!s(uint64=114),%!s(uint64=108),%!s(uint64=100)]
(dlv) p %q hellob
[]uint8 len: 11, cap: 16, ['h','e','l','l','o',' ','w','o','r','l','d']

It would be trivial to feed %q to the pretty printer to convert each byte to a character.
More massaging would be needed to turn that into "hello world".

@suzmue
Copy link
Contributor

suzmue commented Jun 3, 2021

There are a few options for how we could display the strings:

  1. String representation as child of the variable

We can load the string representation and make it a child of the parent slice/array node. This would have the advantage of no extra configuration from the user. The possible downsides are the cost of calculating the string, and that not every byte slice makes sense as a string. To deal with the latter, we could have this be an option that can be turned on and off by the user.

Screen Shot 2021-06-16 at 3 36 32 PM

  1. Command to display the string representation

This would be similar to how goland displays the string. We could have a special command that displays the string representation. This can be shown in a custom ui or printed to the debug console.

Screen Shot 2021-06-16 at 3 34 47 PM

  1. Adding string(<expr>) to WATCH or DEBUG CONSOLE

This is the current recommended workflow. It currently has some limitations with the load configuration but these can be fixed in the debug adapter by adjusting MaxArrayValues.

@polinasok
Copy link
Contributor

This feature has been added to dlv-dap:
image

@trmaphi
Copy link

trmaphi commented Jul 5, 2021

@polinasok Is there anyway I can view hex values for byte/uint8 slices?

@polinasok
Copy link
Contributor

You can define your own helper:

func bytesAsHex(b []byte) string { // Do make sure to use it in your code, so the symbol is available
	return fmt.Sprintf("%#v", b)
}

Then use it from WATCH or DEBUG CONSOLE:

call bytesAsHex(mybytes)

It's not great. We really should do something better. Do you mind filing a feature request with what would be a better solution? Would you prefer an inlined version like we did for string? Or perhaps showing each character both as a decimal, as a hex and as a character?

string(): "hello"
%X: [68,65,6C,6C,6F]
[0]: 104 = 0x68 = h
[1]: 101 = 0x65 = e 
[2]: 108 = 0x6c = l
[3]: 108 = 0x6c = l
[4]: 111 = 0x6f = o

@suzmue

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Debug Issues related to the debugging functionality of the extension. FrozenDueToAge
Projects
None yet
Development

No branches or pull requests

6 participants