1 // Copyright 2018 The gVisor Authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 15 package state
16 17 import (
18 "bytes"
19 "context"
20 "fmt"
21 "math"
22 "reflect"
23 24 "gvisor.dev/gvisor/pkg/state/wire"
25 )
26 27 // internalCallback is a interface called on object completion.
28 //
29 // There are two implementations: objectDecodeState & userCallback.
30 type internalCallback interface {
31 // source returns the dependent object. May be nil.
32 source() *objectDecodeState
33 34 // callbackRun executes the callback.
35 callbackRun()
36 }
37 38 // userCallback is an implementation of internalCallback.
39 type userCallback func()
40 41 // source implements internalCallback.source.
42 func (userCallback) source() *objectDecodeState {
43 return nil
44 }
45 46 // callbackRun implements internalCallback.callbackRun.
47 func (uc userCallback) callbackRun() {
48 uc()
49 }
50 51 // objectDecodeState represents an object that may be in the process of being
52 // decoded. Specifically, it represents either a decoded object, or an an
53 // interest in a future object that will be decoded. When that interest is
54 // registered (via register), the storage for the object will be created, but
55 // it will not be decoded until the object is encountered in the stream.
56 type objectDecodeState struct {
57 // id is the id for this object.
58 id objectID
59 60 // typ is the id for this typeID. This may be zero if this is not a
61 // type-registered structure.
62 typ typeID
63 64 // obj is the object. This may or may not be valid yet, depending on
65 // whether complete returns true. However, regardless of whether the
66 // object is valid, obj contains a final storage location for the
67 // object. This is immutable.
68 //
69 // Note that this must be addressable (obj.Addr() must not panic).
70 //
71 // The obj passed to the decode methods below will equal this obj only
72 // in the case of decoding the top-level object. However, the passed
73 // obj may represent individual fields, elements of a slice, etc. that
74 // are effectively embedded within the reflect.Value below but with
75 // distinct types.
76 obj reflect.Value
77 78 // blockedBy is the number of dependencies this object has.
79 blockedBy int
80 81 // callbacksInline is inline storage for callbacks.
82 callbacksInline [2]internalCallback
83 84 // callbacks is a set of callbacks to execute on load.
85 callbacks []internalCallback
86 87 completeEntry
88 }
89 90 // addCallback adds a callback to the objectDecodeState.
91 func (ods *objectDecodeState) addCallback(ic internalCallback) {
92 if ods.callbacks == nil {
93 ods.callbacks = ods.callbacksInline[:0]
94 }
95 ods.callbacks = append(ods.callbacks, ic)
96 }
97 98 // findCycleFor returns when the given object is found in the blocking set.
99 func (ods *objectDecodeState) findCycleFor(target *objectDecodeState) []*objectDecodeState {
100 for _, ic := range ods.callbacks {
101 other := ic.source()
102 if other != nil && other == target {
103 return []*objectDecodeState{target}
104 } else if childList := other.findCycleFor(target); childList != nil {
105 return append(childList, other)
106 }
107 }
108 109 // This should not occur.
110 Failf("no deadlock found?")
111 panic("unreachable")
112 }
113 114 // findCycle finds a dependency cycle.
115 func (ods *objectDecodeState) findCycle() []*objectDecodeState {
116 return append(ods.findCycleFor(ods), ods)
117 }
118 119 // source implements internalCallback.source.
120 func (ods *objectDecodeState) source() *objectDecodeState {
121 return ods
122 }
123 124 // callbackRun implements internalCallback.callbackRun.
125 func (ods *objectDecodeState) callbackRun() {
126 ods.blockedBy--
127 }
128 129 // decodeState is a graph of objects in the process of being decoded.
130 //
131 // The decode process involves loading the breadth-first graph generated by
132 // encode. This graph is read in it's entirety, ensuring that all object
133 // storage is complete.
134 //
135 // As the graph is being serialized, a set of completion callbacks are
136 // executed. These completion callbacks should form a set of acyclic subgraphs
137 // over the original one. After decoding is complete, the objects are scanned
138 // to ensure that all callbacks are executed, otherwise the callback graph was
139 // not acyclic.
140 type decodeState struct {
141 // ctx is the decode context.
142 ctx context.Context
143 144 // r is the input stream.
145 r wire.Reader
146 147 // types is the type database.
148 types typeDecodeDatabase
149 150 // objectByID is the set of objects in progress.
151 objectsByID []*objectDecodeState
152 153 // deferred are objects that have been read, by no interest has been
154 // registered yet. These will be decoded once interest in registered.
155 deferred map[objectID]wire.Object
156 157 // pending is the set of objects that are not yet complete.
158 pending completeList
159 160 // stats tracks time data.
161 stats Stats
162 }
163 164 // lookup looks up an object in decodeState or returns nil if no such object
165 // has been previously registered.
166 func (ds *decodeState) lookup(id objectID) *objectDecodeState {
167 if len(ds.objectsByID) < int(id) {
168 return nil
169 }
170 return ds.objectsByID[id-1]
171 }
172 173 // checkComplete checks for completion.
174 func (ds *decodeState) checkComplete(ods *objectDecodeState) bool {
175 // Still blocked?
176 if ods.blockedBy > 0 {
177 return false
178 }
179 180 // Track stats if relevant.
181 if ods.callbacks != nil && ods.typ != 0 {
182 ds.stats.start(ods.typ)
183 defer ds.stats.done()
184 }
185 186 // Fire all callbacks.
187 for _, ic := range ods.callbacks {
188 ic.callbackRun()
189 }
190 191 // Mark completed.
192 cbs := ods.callbacks
193 ods.callbacks = nil
194 ds.pending.Remove(ods)
195 196 // Recursively check others.
197 for _, ic := range cbs {
198 if other := ic.source(); other != nil && other.blockedBy == 0 {
199 ds.checkComplete(other)
200 }
201 }
202 203 return true // All set.
204 }
205 206 // wait registers a dependency on an object.
207 //
208 // As a special case, we always allow _useable_ references back to the first
209 // decoding object because it may have fields that are already decoded. We also
210 // allow trivial self reference, since they can be handled internally.
211 func (ds *decodeState) wait(waiter *objectDecodeState, id objectID, callback func()) {
212 switch id {
213 case waiter.id:
214 // Trivial self reference.
215 fallthrough
216 case 1:
217 // Root object; see above.
218 if callback != nil {
219 callback()
220 }
221 return
222 }
223 224 // Mark as blocked.
225 waiter.blockedBy++
226 227 // No nil can be returned here.
228 other := ds.lookup(id)
229 if callback != nil {
230 // Add the additional user callback.
231 other.addCallback(userCallback(callback))
232 }
233 234 // Mark waiter as unblocked.
235 other.addCallback(waiter)
236 }
237 238 // waitObject notes a blocking relationship.
239 func (ds *decodeState) waitObject(ods *objectDecodeState, encoded wire.Object, callback func()) {
240 if rv, ok := encoded.(*wire.Ref); ok && rv.Root != 0 {
241 // Refs can encode pointers and maps.
242 ds.wait(ods, objectID(rv.Root), callback)
243 } else if sv, ok := encoded.(*wire.Slice); ok && sv.Ref.Root != 0 {
244 // See decodeObject; we need to wait for the array (if non-nil).
245 ds.wait(ods, objectID(sv.Ref.Root), callback)
246 } else if iv, ok := encoded.(*wire.Interface); ok {
247 // It's an interface (wait recursively).
248 ds.waitObject(ods, iv.Value, callback)
249 } else if callback != nil {
250 // Nothing to wait for: execute the callback immediately.
251 callback()
252 }
253 }
254 255 // walkChild returns a child object from obj, given an accessor path. This is
256 // the decode-side equivalent to traverse in encode.go.
257 //
258 // For the purposes of this function, a child object is either a field within a
259 // struct or an array element, with one such indirection per element in
260 // path. The returned value may be an unexported field, so it may not be
261 // directly assignable. See decode_unsafe.go.
262 func walkChild(path []wire.Dot, obj reflect.Value) reflect.Value {
263 // See wire.Ref.Dots. The path here is specified in reverse order.
264 for i := len(path) - 1; i >= 0; i-- {
265 switch pc := path[i].(type) {
266 case *wire.FieldName: // Must be a pointer.
267 if obj.Kind() != reflect.Struct {
268 Failf("next component in child path is a field name, but the current object is not a struct. Path: %v, current obj: %#v", path, obj)
269 }
270 obj = obj.FieldByName(string(*pc))
271 case wire.Index: // Embedded.
272 if obj.Kind() != reflect.Array {
273 Failf("next component in child path is an array index, but the current object is not an array. Path: %v, current obj: %#v", path, obj)
274 }
275 obj = obj.Index(int(pc))
276 default:
277 panic("unreachable: switch should be exhaustive")
278 }
279 }
280 return obj
281 }
282 283 // register registers a decode with a type.
284 //
285 // This type is only used to instantiate a new object if it has not been
286 // registered previously. This depends on the type provided if none is
287 // available in the object itself.
288 func (ds *decodeState) register(r *wire.Ref, typ reflect.Type) reflect.Value {
289 // Grow the objectsByID slice.
290 id := objectID(r.Root)
291 if len(ds.objectsByID) < int(id) {
292 ds.objectsByID = append(ds.objectsByID, make([]*objectDecodeState, int(id)-len(ds.objectsByID))...)
293 }
294 295 // Does this object already exist?
296 ods := ds.objectsByID[id-1]
297 if ods != nil {
298 return walkChild(r.Dots, ods.obj)
299 }
300 301 // Create the object.
302 if len(r.Dots) != 0 {
303 typ = ds.findType(r.Type)
304 }
305 v := reflect.New(typ)
306 ods = &objectDecodeState{
307 id: id,
308 obj: v.Elem(),
309 }
310 ds.objectsByID[id-1] = ods
311 ds.pending.PushBack(ods)
312 313 // Process any deferred objects & callbacks.
314 if encoded, ok := ds.deferred[id]; ok {
315 delete(ds.deferred, id)
316 ds.decodeObject(ods, ods.obj, encoded)
317 }
318 319 return walkChild(r.Dots, ods.obj)
320 }
321 322 // objectDecoder is for decoding structs.
323 type objectDecoder struct {
324 // ds is decodeState.
325 ds *decodeState
326 327 // ods is current object being decoded.
328 ods *objectDecodeState
329 330 // reconciledTypeEntry is the reconciled type information.
331 rte *reconciledTypeEntry
332 333 // encoded is the encoded object state.
334 encoded *wire.Struct
335 }
336 337 // load is helper for the public methods on Source.
338 func (od *objectDecoder) load(slot int, objPtr reflect.Value, wait bool, fn func()) {
339 // Note that we have reconciled the type and may remap the fields here
340 // to match what's expected by the decoder. The "slot" parameter here
341 // is in terms of the local type, where the fields in the encoded
342 // object are in terms of the wire object's type, which might be in a
343 // different order (but will have the same fields).
344 v := *od.encoded.Field(od.rte.FieldOrder[slot])
345 od.ds.decodeObject(od.ods, objPtr.Elem(), v)
346 if wait {
347 // Mark this individual object a blocker.
348 od.ds.waitObject(od.ods, v, fn)
349 }
350 }
351 352 // aterLoad implements Source.AfterLoad.
353 func (od *objectDecoder) afterLoad(fn func()) {
354 // Queue the local callback; this will execute when all of the above
355 // data dependencies have been cleared.
356 od.ods.addCallback(userCallback(fn))
357 }
358 359 // decodeStruct decodes a struct value.
360 func (ds *decodeState) decodeStruct(ods *objectDecodeState, obj reflect.Value, encoded *wire.Struct) {
361 if encoded.TypeID == 0 {
362 // Allow anonymous empty structs, but only if the encoded
363 // object also has no fields.
364 if encoded.Fields() == 0 && obj.NumField() == 0 {
365 return
366 }
367 368 // Propagate an error.
369 Failf("empty struct on wire %#v has field mismatch with type %q", encoded, obj.Type().Name())
370 }
371 372 // Lookup the object type.
373 rte := ds.types.Lookup(typeID(encoded.TypeID), obj.Type())
374 ods.typ = typeID(encoded.TypeID)
375 376 // Invoke the loader.
377 od := objectDecoder{
378 ds: ds,
379 ods: ods,
380 rte: rte,
381 encoded: encoded,
382 }
383 ds.stats.start(ods.typ)
384 defer ds.stats.done()
385 if sl, ok := obj.Addr().Interface().(SaverLoader); ok {
386 // Note: may be a registered empty struct which does not
387 // implement the saver/loader interfaces.
388 sl.StateLoad(ds.ctx, Source{internal: od})
389 }
390 }
391 392 // decodeMap decodes a map value.
393 func (ds *decodeState) decodeMap(ods *objectDecodeState, obj reflect.Value, encoded *wire.Map) {
394 if obj.IsNil() {
395 // See pointerTo.
396 obj.Set(reflect.MakeMap(obj.Type()))
397 }
398 for i := 0; i < len(encoded.Keys); i++ {
399 // Decode the objects.
400 kv := reflect.New(obj.Type().Key()).Elem()
401 vv := reflect.New(obj.Type().Elem()).Elem()
402 ds.decodeObject(ods, kv, encoded.Keys[i])
403 ds.decodeObject(ods, vv, encoded.Values[i])
404 ds.waitObject(ods, encoded.Keys[i], nil)
405 ds.waitObject(ods, encoded.Values[i], nil)
406 407 // Set in the map.
408 obj.SetMapIndex(kv, vv)
409 }
410 }
411 412 // decodeArray decodes an array value.
413 func (ds *decodeState) decodeArray(ods *objectDecodeState, obj reflect.Value, encoded *wire.Array) {
414 if len(encoded.Contents) != obj.Len() {
415 Failf("mismatching array length expect=%d, actual=%d", obj.Len(), len(encoded.Contents))
416 }
417 // Decode the contents into the array.
418 for i := 0; i < len(encoded.Contents); i++ {
419 ds.decodeObject(ods, obj.Index(i), encoded.Contents[i])
420 ds.waitObject(ods, encoded.Contents[i], nil)
421 }
422 }
423 424 // findType finds the type for the given wire.TypeSpecs.
425 func (ds *decodeState) findType(t wire.TypeSpec) reflect.Type {
426 switch x := t.(type) {
427 case wire.TypeID:
428 typ := ds.types.LookupType(typeID(x))
429 rte := ds.types.Lookup(typeID(x), typ)
430 return rte.LocalType
431 case *wire.TypeSpecPointer:
432 return reflect.PtrTo(ds.findType(x.Type))
433 case *wire.TypeSpecArray:
434 return reflect.ArrayOf(int(x.Count), ds.findType(x.Type))
435 case *wire.TypeSpecSlice:
436 return reflect.SliceOf(ds.findType(x.Type))
437 case *wire.TypeSpecMap:
438 return reflect.MapOf(ds.findType(x.Key), ds.findType(x.Value))
439 default:
440 // Should not happen.
441 Failf("unknown type %#v", t)
442 }
443 panic("unreachable")
444 }
445 446 // decodeInterface decodes an interface value.
447 func (ds *decodeState) decodeInterface(ods *objectDecodeState, obj reflect.Value, encoded *wire.Interface) {
448 if _, ok := encoded.Type.(wire.TypeSpecNil); ok {
449 // Special case; the nil object. Just decode directly, which
450 // will read nil from the wire (if encoded correctly).
451 ds.decodeObject(ods, obj, encoded.Value)
452 return
453 }
454 455 // We now need to resolve the actual type.
456 typ := ds.findType(encoded.Type)
457 458 // We need to imbue type information here, then we can proceed to
459 // decode normally. In order to avoid issues with setting value-types,
460 // we create a new non-interface version of this object. We will then
461 // set the interface object to be equal to whatever we decode.
462 origObj := obj
463 obj = reflect.New(typ).Elem()
464 defer origObj.Set(obj)
465 466 // With the object now having sufficient type information to actually
467 // have Set called on it, we can proceed to decode the value.
468 ds.decodeObject(ods, obj, encoded.Value)
469 }
470 471 // isFloatEq determines if x and y represent the same value.
472 func isFloatEq(x float64, y float64) bool {
473 switch {
474 case math.IsNaN(x):
475 return math.IsNaN(y)
476 case math.IsInf(x, 1):
477 return math.IsInf(y, 1)
478 case math.IsInf(x, -1):
479 return math.IsInf(y, -1)
480 default:
481 return x == y
482 }
483 }
484 485 // isComplexEq determines if x and y represent the same value.
486 func isComplexEq(x complex128, y complex128) bool {
487 return isFloatEq(real(x), real(y)) && isFloatEq(imag(x), imag(y))
488 }
489 490 // decodeObject decodes a object value.
491 func (ds *decodeState) decodeObject(ods *objectDecodeState, obj reflect.Value, encoded wire.Object) {
492 switch x := encoded.(type) {
493 case wire.Nil: // Fast path: first.
494 // We leave obj alone here. That's because if obj represents an
495 // interface, it may have been imbued with type information in
496 // decodeInterface, and we don't want to destroy that.
497 case *wire.Ref:
498 // Nil pointers may be encoded in a "forceValue" context. For
499 // those we just leave it alone as the value will already be
500 // correct (nil).
501 if id := objectID(x.Root); id == 0 {
502 return
503 }
504 505 // Note that if this is a map type, we go through a level of
506 // indirection to allow for map aliasing.
507 if obj.Kind() == reflect.Map {
508 v := ds.register(x, obj.Type())
509 if v.IsNil() {
510 // Note that we don't want to clobber the map
511 // if has already been decoded by decodeMap. We
512 // just make it so that we have a consistent
513 // reference when that eventually does happen.
514 v.Set(reflect.MakeMap(v.Type()))
515 }
516 obj.Set(v)
517 return
518 }
519 520 // Normal assignment: authoritative only if no dots.
521 v := ds.register(x, obj.Type().Elem())
522 obj.Set(reflectValueRWAddr(v))
523 case wire.Bool:
524 obj.SetBool(bool(x))
525 case wire.Int:
526 obj.SetInt(int64(x))
527 if obj.Int() != int64(x) {
528 Failf("signed integer truncated from %v to %v", int64(x), obj.Int())
529 }
530 case wire.Uint:
531 obj.SetUint(uint64(x))
532 if obj.Uint() != uint64(x) {
533 Failf("unsigned integer truncated from %v to %v", uint64(x), obj.Uint())
534 }
535 case wire.Float32:
536 obj.SetFloat(float64(x))
537 case wire.Float64:
538 obj.SetFloat(float64(x))
539 if !isFloatEq(obj.Float(), float64(x)) {
540 Failf("floating point number truncated from %v to %v", float64(x), obj.Float())
541 }
542 case *wire.Complex64:
543 obj.SetComplex(complex128(*x))
544 case *wire.Complex128:
545 obj.SetComplex(complex128(*x))
546 if !isComplexEq(obj.Complex(), complex128(*x)) {
547 Failf("complex number truncated from %v to %v", complex128(*x), obj.Complex())
548 }
549 case *wire.String:
550 obj.SetString(string(*x))
551 case *wire.Slice:
552 // See *wire.Ref above; same applies.
553 if id := objectID(x.Ref.Root); id == 0 {
554 return
555 }
556 // Note that it's fine to slice the array here and assume that
557 // contents will still be filled in later on.
558 typ := reflect.ArrayOf(int(x.Capacity), obj.Type().Elem()) // The object type.
559 v := ds.register(&x.Ref, typ)
560 obj.Set(reflectValueRWSlice3(v, 0, int(x.Length), int(x.Capacity)))
561 case *wire.Array:
562 ds.decodeArray(ods, obj, x)
563 case *wire.Struct:
564 ds.decodeStruct(ods, obj, x)
565 case *wire.Map:
566 ds.decodeMap(ods, obj, x)
567 case *wire.Interface:
568 ds.decodeInterface(ods, obj, x)
569 default:
570 // Should not happen, not propagated as an error.
571 Failf("unknown object %#v for %q", encoded, obj.Type().Name())
572 }
573 }
574 575 // Load deserializes the object graph rooted at obj.
576 //
577 // This function may panic and should be run in safely().
578 func (ds *decodeState) Load(obj reflect.Value) {
579 ds.stats.init()
580 defer ds.stats.fini(func(id typeID) string {
581 return ds.types.LookupName(id)
582 })
583 584 // Create the root object.
585 rootOds := &objectDecodeState{
586 id: 1,
587 obj: obj,
588 }
589 ds.objectsByID = append(ds.objectsByID, rootOds)
590 ds.pending.PushBack(rootOds)
591 592 // Read the number of objects.
593 numObjects, object, err := ReadHeader(&ds.r)
594 if err != nil {
595 Failf("header error: %w", err)
596 }
597 if !object {
598 Failf("object missing")
599 }
600 601 // Decode all objects.
602 var (
603 encoded wire.Object
604 ods *objectDecodeState
605 id objectID
606 tid = typeID(1)
607 )
608 if err := safely(func() {
609 // Decode all objects in the stream.
610 //
611 // Note that the structure of this decoding loop should match the raw
612 // decoding loop in state/pretty/pretty.printer.printStream().
613 for i := uint64(0); i < numObjects; {
614 // Unmarshal either a type object or object ID.
615 encoded = wire.Load(&ds.r)
616 switch we := encoded.(type) {
617 case *wire.Type:
618 ds.types.Register(we)
619 tid++
620 encoded = nil
621 continue
622 case wire.Uint:
623 id = objectID(we)
624 i++
625 // Unmarshal and resolve the actual object.
626 encoded = wire.Load(&ds.r)
627 ods = ds.lookup(id)
628 if ods != nil {
629 // Decode the object.
630 ds.decodeObject(ods, ods.obj, encoded)
631 } else {
632 // If an object hasn't had interest registered
633 // previously or isn't yet valid, we deferred
634 // decoding until interest is registered.
635 ds.deferred[id] = encoded
636 }
637 // For error handling.
638 ods = nil
639 encoded = nil
640 default:
641 Failf("wanted type or object ID, got %T", encoded)
642 }
643 }
644 }); err != nil {
645 // Include as much information as we can, taking into account
646 // the possible state transitions above.
647 if ods != nil {
648 Failf("error decoding object ID %d (%T) from %#v: %w", id, ods.obj.Interface(), encoded, err)
649 } else if encoded != nil {
650 Failf("error decoding from %#v: %w", encoded, err)
651 } else {
652 Failf("general decoding error: %w", err)
653 }
654 }
655 656 // Check if we have any deferred objects.
657 numDeferred := 0
658 for id, encoded := range ds.deferred {
659 numDeferred++
660 if s, ok := encoded.(*wire.Struct); ok && s.TypeID != 0 {
661 typ := ds.types.LookupType(typeID(s.TypeID))
662 Failf("unused deferred object: ID %d, type %v", id, typ)
663 } else {
664 Failf("unused deferred object: ID %d, %#v", id, encoded)
665 }
666 }
667 if numDeferred != 0 {
668 Failf("still had %d deferred objects", numDeferred)
669 }
670 671 // Scan and fire all callbacks. We iterate over the list of incomplete
672 // objects until all have been finished. We stop iterating if no
673 // objects become complete (there is a dependency cycle).
674 //
675 // Note that we iterate backwards here, because there will be a strong
676 // tendendcy for blocking relationships to go from earlier objects to
677 // later (deeper) objects in the graph. This will reduce the number of
678 // iterations required to finish all objects.
679 if err := safely(func() {
680 for ds.pending.Back() != nil {
681 thisCycle := false
682 for ods = ds.pending.Back(); ods != nil; {
683 if ds.checkComplete(ods) {
684 thisCycle = true
685 break
686 }
687 ods = ods.Prev()
688 }
689 if !thisCycle {
690 break
691 }
692 }
693 }); err != nil {
694 Failf("error executing callbacks: %w\nfor object %#v", err, ods.obj.Interface())
695 }
696 697 // Check if we have any remaining dependency cycles. If there are any
698 // objects left in the pending list, then it must be due to a cycle.
699 if ods := ds.pending.Front(); ods != nil {
700 // This must be the result of a dependency cycle.
701 cycle := ods.findCycle()
702 var buf bytes.Buffer
703 buf.WriteString("dependency cycle: {")
704 for i, cycleOS := range cycle {
705 if i > 0 {
706 buf.WriteString(" => ")
707 }
708 fmt.Fprintf(&buf, "%q", cycleOS.obj.Type())
709 }
710 buf.WriteString("}")
711 Failf("incomplete graph: %s", string(buf.Bytes()))
712 }
713 }
714 715 // ReadHeader reads an object header.
716 //
717 // Each object written to the statefile is prefixed with a header. See
718 // WriteHeader for more information; these functions are exported to allow
719 // non-state writes to the file to play nice with debugging tools.
720 func ReadHeader(r *wire.Reader) (length uint64, object bool, err error) {
721 // Read the header.
722 err = safely(func() {
723 length = wire.LoadUint(r)
724 })
725 if err != nil {
726 // On the header, pass raw I/O errors.
727 if sErr, ok := err.(*ErrState); ok {
728 return 0, false, sErr.Unwrap()
729 }
730 }
731 732 // Decode whether the object is valid.
733 object = length&objectFlag != 0
734 length &^= objectFlag
735 return
736 }
737