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:
parent
ca611db449
commit
a53f1bf45d
@ -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)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user