proc,prettyprint: guard against autodereferenced escaped pointers (#1077)

Much like the bug in issue #1031 and commit
f6f6f0bf13e4c708cb501202b83a6327a0f00e31 pointers can also escape to
the heap and then have a zero address (and no children) when we
autodereference.

1. Mark autodereferenced escaped variables with a 0 address as
   unreadable.
2. Add guards to the pretty printers for unsafe.Pointer and pointers.

Fixes #1075
This commit is contained in:
Alessandro Arzilli 2018-01-19 15:50:28 +01:00 committed by GitHub
parent bc77ff4534
commit bec6a65b15
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 44 additions and 2 deletions

10
_fixtures/clientdo.go Normal file

@ -0,0 +1,10 @@
package main
import (
"net/http"
"net/url"
)
func main() {
http.DefaultClient.Do(&http.Request{URL: &url.URL{}})
}

@ -1938,6 +1938,9 @@ func (scope *EvalScope) variablesByTag(tag dwarf.Tag, cfg *LoadConfig) ([]*Varia
for i, v := range vars {
if name := v.Name; len(name) > 1 && name[0] == '&' {
v = v.maybeDereference()
if v.Addr == 0 {
v.Unreadable = fmt.Errorf("no address for escaped variable")
}
v.Name = name[1:]
v.Flags |= VariableEscaped
vars[i] = v

@ -49,7 +49,7 @@ func (v *Variable) writeTo(buf io.Writer, top, newlines, includeType bool, inden
case reflect.Array:
v.writeArrayTo(buf, newlines, includeType, indent)
case reflect.Ptr:
if v.Type == "" {
if v.Type == "" || len(v.Children) == 0 {
fmt.Fprint(buf, "nil")
} else if v.Children[0].OnlyAddr && v.Children[0].Addr != 0 {
fmt.Fprintf(buf, "(%s)(0x%x)", v.Type, v.Children[0].Addr)
@ -58,7 +58,11 @@ func (v *Variable) writeTo(buf io.Writer, top, newlines, includeType bool, inden
v.Children[0].writeTo(buf, false, newlines, includeType, indent)
}
case reflect.UnsafePointer:
fmt.Fprintf(buf, "unsafe.Pointer(0x%x)", v.Children[0].Addr)
if len(v.Children) == 0 {
fmt.Fprintf(buf, "unsafe.Pointer(nil)")
} else {
fmt.Fprintf(buf, "unsafe.Pointer(0x%x)", v.Children[0].Addr)
}
case reflect.String:
v.writeStringTo(buf)
case reflect.Chan:

@ -976,3 +976,28 @@ func TestConstants(t *testing.T) {
}
})
}
func setFunctionBreakpoint(p proc.Process, fname string) (*proc.Breakpoint, error) {
addr, err := proc.FindFunctionLocation(p, fname, true, 0)
if err != nil {
return nil, err
}
return p.SetBreakpoint(addr, proc.UserBreakpoint, nil)
}
func TestIssue1075(t *testing.T) {
withTestProcess("clientdo", t, func(p proc.Process, fixture protest.Fixture) {
_, err := setFunctionBreakpoint(p, "net/http.(*Client).Do")
assertNoError(err, t, "setFunctionBreakpoint")
assertNoError(proc.Continue(p), t, "Continue()")
for i := 0; i < 10; i++ {
scope, err := proc.GoroutineScope(p.CurrentThread())
assertNoError(err, t, fmt.Sprintf("GoroutineScope (%d)", i))
vars, err := scope.LocalVariables(pnormalLoadConfig)
assertNoError(err, t, fmt.Sprintf("LocalVariables (%d)", i))
for _, v := range vars {
api.ConvertVar(v).SinglelineString()
}
}
})
}