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"
|
"fmt"
|
||||||
"go/constant"
|
"go/constant"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
"regexp"
|
||||||
"runtime"
|
"runtime"
|
||||||
"sort"
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
@ -45,9 +46,14 @@ func matchStringOrPrefix(output, target string) bool {
|
|||||||
prefix := target[:len(target)-len("…")]
|
prefix := target[:len(target)-len("…")]
|
||||||
b := strings.HasPrefix(output, prefix)
|
b := strings.HasPrefix(output, prefix)
|
||||||
return b
|
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) {
|
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},
|
{"a4", true, "[2]int [1,2]", "", "[2]int", nil},
|
||||||
{"a5", true, "[]int len: 5, cap: 5, [1,2,3,4,5]", "", "[]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},
|
{"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},
|
{"a8", true, "main.FooBar2 {Bur: 10, Baz: \"feh\"}", "", "main.FooBar2", nil},
|
||||||
{"a9", true, "*main.FooBar nil", "", "*main.FooBar", nil},
|
{"a9", true, "*main.FooBar nil", "", "*main.FooBar", nil},
|
||||||
{"a8", true, "main.FooBar2 {Bur: 10, Baz: \"feh\"}", "", "main.FooBar2", nil}, // reread variable after member
|
{"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)
|
variable, err := evalVariableWithCfg(p, tc.name, pnormalLoadConfig)
|
||||||
assertNoError(err, t, "EvalVariable() returned an error")
|
assertNoError(err, t, "EvalVariable() returned an error")
|
||||||
if ms := api.ConvertVar(variable).MultilineString("", ""); !matchStringOrPrefix(ms, tc.value) {
|
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 {
|
if v.Type == "" || len(v.Children) == 0 {
|
||||||
fmt.Fprint(buf, "nil")
|
fmt.Fprint(buf, "nil")
|
||||||
} else if v.Children[0].OnlyAddr && v.Children[0].Addr != 0 {
|
} else if v.Children[0].OnlyAddr && v.Children[0].Addr != 0 {
|
||||||
if strings.Contains(v.Type, "/") {
|
v.writePointerTo(buf)
|
||||||
fmt.Fprintf(buf, "(%q)(%#x)", v.Type, v.Children[0].Addr)
|
|
||||||
} else {
|
|
||||||
fmt.Fprintf(buf, "(%s)(%#x)", v.Type, v.Children[0].Addr)
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
|
if top && newlines && v.Children[0].Addr != 0 {
|
||||||
|
v.writePointerTo(buf)
|
||||||
|
fmt.Fprint(buf, "\n")
|
||||||
|
}
|
||||||
fmt.Fprint(buf, "*")
|
fmt.Fprint(buf, "*")
|
||||||
v.Children[0].writeTo(buf, false, newlines, includeType, indent, fmtstr)
|
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) {
|
func (v *Variable) writeBasicType(buf io.Writer, fmtstr string) {
|
||||||
if v.Value == "" && v.Kind != reflect.String {
|
if v.Value == "" && v.Kind != reflect.String {
|
||||||
fmt.Fprintf(buf, "(unknown %s)", v.Kind)
|
fmt.Fprintf(buf, "(unknown %s)", v.Kind)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user