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:
parent
bc77ff4534
commit
bec6a65b15
10
_fixtures/clientdo.go
Normal file
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 {
|
for i, v := range vars {
|
||||||
if name := v.Name; len(name) > 1 && name[0] == '&' {
|
if name := v.Name; len(name) > 1 && name[0] == '&' {
|
||||||
v = v.maybeDereference()
|
v = v.maybeDereference()
|
||||||
|
if v.Addr == 0 {
|
||||||
|
v.Unreadable = fmt.Errorf("no address for escaped variable")
|
||||||
|
}
|
||||||
v.Name = name[1:]
|
v.Name = name[1:]
|
||||||
v.Flags |= VariableEscaped
|
v.Flags |= VariableEscaped
|
||||||
vars[i] = v
|
vars[i] = v
|
||||||
|
@ -49,7 +49,7 @@ func (v *Variable) writeTo(buf io.Writer, top, newlines, includeType bool, inden
|
|||||||
case reflect.Array:
|
case reflect.Array:
|
||||||
v.writeArrayTo(buf, newlines, includeType, indent)
|
v.writeArrayTo(buf, newlines, includeType, indent)
|
||||||
case reflect.Ptr:
|
case reflect.Ptr:
|
||||||
if v.Type == "" {
|
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 {
|
||||||
fmt.Fprintf(buf, "(%s)(0x%x)", v.Type, v.Children[0].Addr)
|
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)
|
v.Children[0].writeTo(buf, false, newlines, includeType, indent)
|
||||||
}
|
}
|
||||||
case reflect.UnsafePointer:
|
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:
|
case reflect.String:
|
||||||
v.writeStringTo(buf)
|
v.writeStringTo(buf)
|
||||||
case reflect.Chan:
|
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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user