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 {
|
||||
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:
|
||||
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()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user