service/api: in multiline mode print address of pointers (#3448)

When printing a pointer variable first print the address that it points
to before printing its dereferenced value.

Fixes #3446
This commit is contained in:
Alessandro Arzilli 2023-07-26 01:27:00 +02:00 committed by GitHub
parent ca611db449
commit a53f1bf45d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 23 additions and 9 deletions

@ -5,6 +5,7 @@ import (
"fmt"
"go/constant"
"io/ioutil"
"regexp"
"runtime"
"sort"
"strconv"
@ -45,9 +46,14 @@ func matchStringOrPrefix(output, target string) bool {
prefix := target[:len(target)-len("…")]
b := strings.HasPrefix(output, prefix)
return b
} else {
return output == target
}
if strings.HasPrefix(target, "/") && strings.HasSuffix(target, "/") {
rx := regexp.MustCompile(target[1 : len(target)-1])
return rx.MatchString(output)
}
return output == target
}
func assertVariable(t testing.TB, variable *proc.Variable, expected varTest) {
@ -309,7 +315,7 @@ func TestMultilineVariableEvaluation(t *testing.T) {
{"a4", true, "[2]int [1,2]", "", "[2]int", nil},
{"a5", true, "[]int len: 5, cap: 5, [1,2,3,4,5]", "", "[]int", nil},
{"a6", true, "main.FooBar {Baz: 8, Bur: \"word\"}", "", "main.FooBar", nil},
{"a7", true, "*main.FooBar {Baz: 5, Bur: \"strum\"}", "", "*main.FooBar", nil},
{"a7", true, `/^\(\*main\.FooBar\)\(.*?\)\n\*main\.FooBar \{Baz: 5, Bur: "strum"\}$/`, "", "*main.FooBar", nil},
{"a8", true, "main.FooBar2 {Bur: 10, Baz: \"feh\"}", "", "main.FooBar2", nil},
{"a9", true, "*main.FooBar nil", "", "*main.FooBar", nil},
{"a8", true, "main.FooBar2 {Bur: 10, Baz: \"feh\"}", "", "main.FooBar2", nil}, // reread variable after member
@ -331,7 +337,7 @@ func TestMultilineVariableEvaluation(t *testing.T) {
variable, err := evalVariableWithCfg(p, tc.name, pnormalLoadConfig)
assertNoError(err, t, "EvalVariable() returned an error")
if ms := api.ConvertVar(variable).MultilineString("", ""); !matchStringOrPrefix(ms, tc.value) {
t.Fatalf("Expected %s got %s (variable %s)\n", tc.value, ms, variable.Name)
t.Fatalf("Expected %s got %q (variable %s)\n", tc.value, ms, variable.Name)
}
}
})

@ -63,12 +63,12 @@ func (v *Variable) writeTo(buf io.Writer, top, newlines, includeType bool, inden
if v.Type == "" || len(v.Children) == 0 {
fmt.Fprint(buf, "nil")
} else if v.Children[0].OnlyAddr && v.Children[0].Addr != 0 {
if strings.Contains(v.Type, "/") {
fmt.Fprintf(buf, "(%q)(%#x)", v.Type, v.Children[0].Addr)
} else {
fmt.Fprintf(buf, "(%s)(%#x)", v.Type, v.Children[0].Addr)
}
v.writePointerTo(buf)
} else {
if top && newlines && v.Children[0].Addr != 0 {
v.writePointerTo(buf)
fmt.Fprint(buf, "\n")
}
fmt.Fprint(buf, "*")
v.Children[0].writeTo(buf, false, newlines, includeType, indent, fmtstr)
}
@ -145,6 +145,14 @@ func (v *Variable) writeTo(buf io.Writer, top, newlines, includeType bool, inden
}
}
func (v *Variable) writePointerTo(buf io.Writer) {
if strings.Contains(v.Type, "/") {
fmt.Fprintf(buf, "(%q)(%#x)", v.Type, v.Children[0].Addr)
} else {
fmt.Fprintf(buf, "(%s)(%#x)", v.Type, v.Children[0].Addr)
}
}
func (v *Variable) writeBasicType(buf io.Writer, fmtstr string) {
if v.Value == "" && v.Kind != reflect.String {
fmt.Fprintf(buf, "(unknown %s)", v.Kind)