diff options
-rw-r--r-- | pkg/state/printer.go | 67 |
1 files changed, 65 insertions, 2 deletions
diff --git a/pkg/state/printer.go b/pkg/state/printer.go index 881125ddd..2c8ce60a5 100644 --- a/pkg/state/printer.go +++ b/pkg/state/printer.go @@ -18,13 +18,15 @@ import ( "fmt" "io" "io/ioutil" + "reflect" "strings" "github.com/golang/protobuf/proto" pb "gvisor.googlesource.com/gvisor/pkg/state/object_go_proto" ) -// format formats a single object, for pretty-printing. +// format formats a single object, for pretty-printing. It also returns whether +// the value is a non-zero value. func format(graph uint64, depth int, object *pb.Object, html bool) (string, bool) { switch x := object.GetValue().(type) { case *pb.Object_BoolValue: @@ -76,7 +78,7 @@ func format(graph uint64, depth int, object *pb.Object, html bool) (string, bool } } if len(zeros) > 0 { - items = append(items, fmt.Sprintf("\t... (%d zero),", len(zeros))) + items = append(items, fmt.Sprintf("\t... (%d zeros),", len(zeros))) } items = append(items, "]") return strings.Join(items, tabs), len(zeros) < len(x.ArrayValue.Contents) @@ -115,6 +117,30 @@ func format(graph uint64, depth int, object *pb.Object, html bool) (string, bool } element, _ := format(graph, depth+1, x.InterfaceValue.Value, html) return fmt.Sprintf("interface(\"%s\"){%s}", x.InterfaceValue.Type, element), true + case *pb.Object_ByteArrayValue: + return printArray(reflect.ValueOf(x.ByteArrayValue)) + case *pb.Object_Uint16ArrayValue: + return printArray(reflect.ValueOf(x.Uint16ArrayValue.Values)) + case *pb.Object_Uint32ArrayValue: + return printArray(reflect.ValueOf(x.Uint32ArrayValue.Values)) + case *pb.Object_Uint64ArrayValue: + return printArray(reflect.ValueOf(x.Uint64ArrayValue.Values)) + case *pb.Object_UintptrArrayValue: + return printArray(castSlice(reflect.ValueOf(x.UintptrArrayValue.Values), reflect.TypeOf(uintptr(0)))) + case *pb.Object_Int8ArrayValue: + return printArray(castSlice(reflect.ValueOf(x.Int8ArrayValue.Values), reflect.TypeOf(int8(0)))) + case *pb.Object_Int16ArrayValue: + return printArray(reflect.ValueOf(x.Int16ArrayValue.Values)) + case *pb.Object_Int32ArrayValue: + return printArray(reflect.ValueOf(x.Int32ArrayValue.Values)) + case *pb.Object_Int64ArrayValue: + return printArray(reflect.ValueOf(x.Int64ArrayValue.Values)) + case *pb.Object_BoolArrayValue: + return printArray(reflect.ValueOf(x.BoolArrayValue.Values)) + case *pb.Object_Float64ArrayValue: + return printArray(reflect.ValueOf(x.Float64ArrayValue.Values)) + case *pb.Object_Float32ArrayValue: + return printArray(reflect.ValueOf(x.Float32ArrayValue.Values)) } // Should not happen, but tolerate. @@ -186,3 +212,40 @@ func PrettyPrint(w io.Writer, r io.Reader, html bool) error { return nil } + +func printArray(s reflect.Value) (string, bool) { + zero := reflect.Zero(s.Type().Elem()).Interface() + z := "0" + switch s.Type().Elem().Kind() { + case reflect.Bool: + z = "false" + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + case reflect.Float32, reflect.Float64: + default: + return fmt.Sprintf("unexpected non-primitive type array: %#v", s.Interface()), true + } + + zeros := 0 + items := make([]string, 0, s.Len()) + for i := 0; i <= s.Len(); i++ { + if i < s.Len() && reflect.DeepEqual(s.Index(i).Interface(), zero) { + zeros++ + continue + } + if zeros > 0 { + if zeros <= 4 { + for ; zeros > 0; zeros-- { + items = append(items, z) + } + } else { + items = append(items, fmt.Sprintf("(%d %ss)", zeros, z)) + zeros = 0 + } + } + if i < s.Len() { + items = append(items, fmt.Sprintf("%v", s.Index(i).Interface())) + } + } + return "[" + strings.Join(items, ",") + "]", zeros < s.Len() +} |