debug: Prints more specific error messages. Change-Id: Ib59508eff6c84e1653cfe365429b7c3851c680b6 Reviewed-on: https://go-review.googlesource.com/1997 Reviewed-by: Rob Pike <r@golang.org> Reviewed-by: Nigel Tao <nigeltao@golang.org>
diff --git a/ogle/program/server/print.go b/ogle/program/server/print.go index ccf8df3..7e2d8b5 100644 --- a/ogle/program/server/print.go +++ b/ogle/program/server/print.go
@@ -43,32 +43,21 @@ cacheAddr address // Starting address of cache. } -// printf prints to printBuf, unless there has been an error. +// printf prints to printBuf. func (p *Printer) printf(format string, args ...interface{}) { - if p.err != nil { - return - } fmt.Fprintf(&p.printBuf, format, args...) } -// errorf sets the sticky error for the printer, if not already set. +// errorf prints the error to printBuf, then sets the sticky error for the +// printer, if not already set. func (p *Printer) errorf(format string, args ...interface{}) { + fmt.Fprintf(&p.printBuf, "<"+format+">", args...) if p.err != nil { return } p.err = fmt.Errorf(format, args...) } -// ok checks the error. If it is the first non-nil error encountered, -// it is printed to printBuf, parenthesized for discrimination, and remembered. -func (p *Printer) ok(err error) bool { - if p.err == nil && err != nil { - p.printf("(%s)", err) - p.err = err - } - return p.err == nil -} - // peek reads len bytes at offset, leaving p.tmp with the data and sized appropriately. // It uses the cache if the request is within it. func (p *Printer) peek(a address, length int64) bool { @@ -77,7 +66,8 @@ copy(p.tmp, p.cache[a-p.cacheAddr:]) return true } - return p.ok(p.peeker.peek(uintptr(a), p.tmp)) + err := p.peeker.peek(uintptr(a), p.tmp) + return err == nil } // setCache initializes the cache to contain the contents of the @@ -89,11 +79,13 @@ p.cache = make([]byte, length) } p.cacheAddr = a - ok := p.ok(p.peeker.peek(uintptr(a), p.cache)) - if !ok { + err := p.peeker.peek(uintptr(a), p.cache) + if err != nil { + // If the peek failed, don't cache anything. p.resetCache() + return false } - return ok + return true } func (p *Printer) resetCache() { @@ -221,23 +213,32 @@ } if p.peek(a, 1) { p.printf("%t", p.tmp[0] != 0) + } else { + p.errorf("couldn't read bool") } case *dwarf.PtrType: // This type doesn't define the ByteSize attribute. if p.peek(a, int64(p.arch.PointerSize)) { p.printf("%#x", p.arch.Uintptr(p.tmp)) + } else { + p.errorf("couldn't read pointer") } case *dwarf.IntType: // Sad we can't tell a rune from an int32. if p.peek(a, typ.ByteSize) { p.printf("%d", p.arch.IntN(p.tmp)) + } else { + p.errorf("couldn't read int") } case *dwarf.UintType: if p.peek(a, typ.ByteSize) { p.printf("%d", p.arch.UintN(p.tmp)) + } else { + p.errorf("couldn't read uint") } case *dwarf.FloatType: if !p.peek(a, typ.ByteSize) { + p.errorf("couldn't read float") return } switch typ.ByteSize { @@ -250,6 +251,7 @@ } case *dwarf.ComplexType: if !p.peek(a, typ.ByteSize) { + p.errorf("couldn't read complex") return } switch typ.ByteSize { @@ -343,11 +345,13 @@ structType := typ.Type.(*dwarf.PtrType).Type.(*dwarf.StructType) // Indirect through the pointer. if !p.peek(a, int64(p.arch.PointerSize)) { + p.errorf("couldn't read map") return } a = address(p.arch.Uintptr(p.tmp[:p.arch.PointerSize])) // Now read the struct. if !p.peek(a, structType.ByteSize) { + p.errorf("couldn't read map") return } // From runtime/hashmap.go; We need to walk the map data structure. @@ -398,6 +402,7 @@ // After the header, the bucket struct has an array of keys followed by an array of elements. // Load this bucket struct into p's cache and initialize "pointers" to the key and value slices. if !p.setCache(a, desc.bucketSize) { + p.errorf("couldn't read map") return } keyAddr := a + bucketCnt + address(p.arch.PointerSize) @@ -434,7 +439,7 @@ // Slices look like a struct with fields array *elemtype, len uint32/64, cap uint32/64. // BUG: Slice header appears to have fields with ByteSize == 0 if !p.peek(a, typ.ByteSize) { - p.errorf("slice header has no known size") + p.errorf("couldn't read slice") return } lo := typ.Field[0].ByteOffset @@ -464,7 +469,7 @@ // Strings look like a struct with fields array *elemtype, len uint64. // TODO uint64 on 386 too? if !p.peek(a, typ.ByteSize) { - p.errorf("string header has no known size") + p.errorf("couldn't read string") return } // BUG: String header appears to have fields with ByteSize == 0 @@ -477,10 +482,16 @@ if length > uint64(cap(p.tmp)) { if p.peek(address(ptr), int64(cap(p.tmp))) { p.printf("%q...", p.tmp) + } else { + p.errorf("couldn't read string") + return } } else { if p.peek(address(ptr), int64(length)) { p.printf("%q", p.tmp[:length]) + } else { + p.errorf("couldn't read string") + return } } }