github.com/code-reading/golang@v0.0.0-20220303082512-ba5bc0e589a3/go/src/encoding/gob/debug.go (about) 1 // Copyright 2009 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // Delete the next line to include in the gob package. 6 //go:build ignore 7 // +build ignore 8 9 package gob 10 11 // This file is not normally included in the gob package. Used only for debugging the package itself. 12 // Except for reading uints, it is an implementation of a reader that is independent of 13 // the one implemented by Decoder. 14 // To enable the Debug function, delete the +build ignore line above and do 15 // go install 16 17 import ( 18 "bytes" 19 "fmt" 20 "io" 21 "os" 22 "strings" 23 "sync" 24 ) 25 26 var dumpBytes = false // If true, print the remaining bytes in the input buffer at each item. 27 28 // Init installs the debugging facility. If this file is not compiled in the 29 // package, the tests in codec_test.go are no-ops. 30 func init() { 31 debugFunc = Debug 32 } 33 34 var ( 35 blanks = bytes.Repeat([]byte{' '}, 3*10) 36 empty = []byte(": <empty>\n") 37 tabs = strings.Repeat("\t", 100) 38 ) 39 40 // tab indents itself when printed. 41 type tab int 42 43 func (t tab) String() string { 44 n := int(t) 45 if n > len(tabs) { 46 n = len(tabs) 47 } 48 return tabs[0:n] 49 } 50 51 func (t tab) print() { 52 fmt.Fprint(os.Stderr, t) 53 } 54 55 // A peekReader wraps an io.Reader, allowing one to peek ahead to see 56 // what's coming without stealing the data from the client of the Reader. 57 type peekReader struct { 58 r io.Reader 59 data []byte // read-ahead data 60 } 61 62 // newPeekReader returns a peekReader that wraps r. 63 func newPeekReader(r io.Reader) *peekReader { 64 return &peekReader{r: r} 65 } 66 67 // Read is the usual method. It will first take data that has been read ahead. 68 func (p *peekReader) Read(b []byte) (n int, err error) { 69 if len(p.data) == 0 { 70 return p.r.Read(b) 71 } 72 // Satisfy what's possible from the read-ahead data. 73 n = copy(b, p.data) 74 // Move data down to beginning of slice, to avoid endless growth 75 copy(p.data, p.data[n:]) 76 p.data = p.data[:len(p.data)-n] 77 return 78 } 79 80 // peek returns as many bytes as possible from the unread 81 // portion of the stream, up to the length of b. 82 func (p *peekReader) peek(b []byte) (n int, err error) { 83 if len(p.data) > 0 { 84 n = copy(b, p.data) 85 if n == len(b) { 86 return 87 } 88 b = b[n:] 89 } 90 if len(b) == 0 { 91 return 92 } 93 m, e := io.ReadFull(p.r, b) 94 if m > 0 { 95 p.data = append(p.data, b[:m]...) 96 } 97 n += m 98 if e == io.ErrUnexpectedEOF { 99 // That means m > 0 but we reached EOF. If we got data 100 // we won't complain about not being able to peek enough. 101 if n > 0 { 102 e = nil 103 } else { 104 e = io.EOF 105 } 106 } 107 return n, e 108 } 109 110 type debugger struct { 111 mutex sync.Mutex 112 remain int // the number of bytes known to remain in the input 113 remainingKnown bool // the value of 'remain' is valid 114 r *peekReader 115 wireType map[typeId]*wireType 116 tmp []byte // scratch space for decoding uints. 117 } 118 119 // dump prints the next nBytes of the input. 120 // It arranges to print the output aligned from call to 121 // call, to make it easy to see what has been consumed. 122 func (deb *debugger) dump(format string, args ...interface{}) { 123 if !dumpBytes { 124 return 125 } 126 fmt.Fprintf(os.Stderr, format+" ", args...) 127 if !deb.remainingKnown { 128 return 129 } 130 if deb.remain < 0 { 131 fmt.Fprintf(os.Stderr, "remaining byte count is negative! %d\n", deb.remain) 132 return 133 } 134 data := make([]byte, deb.remain) 135 n, _ := deb.r.peek(data) 136 if n == 0 { 137 os.Stderr.Write(empty) 138 return 139 } 140 b := new(bytes.Buffer) 141 fmt.Fprintf(b, "[%d]{\n", deb.remain) 142 // Blanks until first byte 143 lineLength := 0 144 if n := len(data); n%10 != 0 { 145 lineLength = 10 - n%10 146 fmt.Fprintf(b, "\t%s", blanks[:lineLength*3]) 147 } 148 // 10 bytes per line 149 for len(data) > 0 { 150 if lineLength == 0 { 151 fmt.Fprint(b, "\t") 152 } 153 m := 10 - lineLength 154 lineLength = 0 155 if m > len(data) { 156 m = len(data) 157 } 158 fmt.Fprintf(b, "% x\n", data[:m]) 159 data = data[m:] 160 } 161 fmt.Fprint(b, "}\n") 162 os.Stderr.Write(b.Bytes()) 163 } 164 165 // Debug prints a human-readable representation of the gob data read from r. 166 // It is a no-op unless debugging was enabled when the package was built. 167 func Debug(r io.Reader) { 168 err := debug(r) 169 if err != nil { 170 fmt.Fprintf(os.Stderr, "gob debug: %s\n", err) 171 } 172 } 173 174 // debug implements Debug, but catches panics and returns 175 // them as errors to be printed by Debug. 176 func debug(r io.Reader) (err error) { 177 defer catchError(&err) 178 fmt.Fprintln(os.Stderr, "Start of debugging") 179 deb := &debugger{ 180 r: newPeekReader(r), 181 wireType: make(map[typeId]*wireType), 182 tmp: make([]byte, 16), 183 } 184 if b, ok := r.(*bytes.Buffer); ok { 185 deb.remain = b.Len() 186 deb.remainingKnown = true 187 } 188 deb.gobStream() 189 return 190 } 191 192 // note that we've consumed some bytes 193 func (deb *debugger) consumed(n int) { 194 if deb.remainingKnown { 195 deb.remain -= n 196 } 197 } 198 199 // int64 decodes and returns the next integer, which must be present. 200 // Don't call this if you could be at EOF. 201 func (deb *debugger) int64() int64 { 202 return toInt(deb.uint64()) 203 } 204 205 // uint64 returns and decodes the next unsigned integer, which must be present. 206 // Don't call this if you could be at EOF. 207 // TODO: handle errors better. 208 func (deb *debugger) uint64() uint64 { 209 n, w, err := decodeUintReader(deb.r, deb.tmp) 210 if err != nil { 211 errorf("debug: read error: %s", err) 212 } 213 deb.consumed(w) 214 return n 215 } 216 217 // GobStream: 218 // DelimitedMessage* (until EOF) 219 func (deb *debugger) gobStream() { 220 // Make sure we're single-threaded through here. 221 deb.mutex.Lock() 222 defer deb.mutex.Unlock() 223 224 for deb.delimitedMessage(0) { 225 } 226 } 227 228 // DelimitedMessage: 229 // uint(lengthOfMessage) Message 230 func (deb *debugger) delimitedMessage(indent tab) bool { 231 for { 232 n := deb.loadBlock(true) 233 if n < 0 { 234 return false 235 } 236 deb.dump("Delimited message of length %d", n) 237 deb.message(indent) 238 } 239 return true 240 } 241 242 // loadBlock preps us to read a message 243 // of the length specified next in the input. It returns 244 // the length of the block. The argument tells whether 245 // an EOF is acceptable now. If it is and one is found, 246 // the return value is negative. 247 func (deb *debugger) loadBlock(eofOK bool) int { 248 n64, w, err := decodeUintReader(deb.r, deb.tmp) // deb.uint64 will error at EOF 249 if err != nil { 250 if eofOK && err == io.EOF { 251 return -1 252 } 253 errorf("debug: unexpected error: %s", err) 254 } 255 deb.consumed(w) 256 n := int(n64) 257 if n < 0 { 258 errorf("huge value for message length: %d", n64) 259 } 260 return int(n) 261 } 262 263 // Message: 264 // TypeSequence TypedValue 265 // TypeSequence 266 // (TypeDefinition DelimitedTypeDefinition*)? 267 // DelimitedTypeDefinition: 268 // uint(lengthOfTypeDefinition) TypeDefinition 269 // TypedValue: 270 // int(typeId) Value 271 func (deb *debugger) message(indent tab) bool { 272 for { 273 // Convert the uint64 to a signed integer typeId 274 uid := deb.int64() 275 id := typeId(uid) 276 deb.dump("type id=%d", id) 277 if id < 0 { 278 deb.typeDefinition(indent, -id) 279 n := deb.loadBlock(false) 280 deb.dump("Message of length %d", n) 281 continue 282 } else { 283 deb.value(indent, id) 284 break 285 } 286 } 287 return true 288 } 289 290 // Helper methods to make it easy to scan a type descriptor. 291 292 // common returns the CommonType at the input point. 293 func (deb *debugger) common() CommonType { 294 fieldNum := -1 295 name := "" 296 id := typeId(0) 297 for { 298 delta := deb.delta(-1) 299 if delta == 0 { 300 break 301 } 302 fieldNum += delta 303 switch fieldNum { 304 case 0: 305 name = deb.string() 306 case 1: 307 // Id typeId 308 id = deb.typeId() 309 default: 310 errorf("corrupted CommonType, delta is %d fieldNum is %d", delta, fieldNum) 311 } 312 } 313 return CommonType{name, id} 314 } 315 316 // uint returns the unsigned int at the input point, as a uint (not uint64). 317 func (deb *debugger) uint() uint { 318 return uint(deb.uint64()) 319 } 320 321 // int returns the signed int at the input point, as an int (not int64). 322 func (deb *debugger) int() int { 323 return int(deb.int64()) 324 } 325 326 // typeId returns the type id at the input point. 327 func (deb *debugger) typeId() typeId { 328 return typeId(deb.int64()) 329 } 330 331 // string returns the string at the input point. 332 func (deb *debugger) string() string { 333 x := int(deb.uint64()) 334 b := make([]byte, x) 335 nb, _ := deb.r.Read(b) 336 if nb != x { 337 errorf("corrupted type") 338 } 339 deb.consumed(nb) 340 return string(b) 341 } 342 343 // delta returns the field delta at the input point. The expect argument, 344 // if non-negative, identifies what the value should be. 345 func (deb *debugger) delta(expect int) int { 346 delta := int(deb.uint64()) 347 if delta < 0 || (expect >= 0 && delta != expect) { 348 errorf("decode: corrupted type: delta %d expected %d", delta, expect) 349 } 350 return delta 351 } 352 353 // TypeDefinition: 354 // [int(-typeId) (already read)] encodingOfWireType 355 func (deb *debugger) typeDefinition(indent tab, id typeId) { 356 deb.dump("type definition for id %d", id) 357 // Encoding is of a wireType. Decode the structure as usual 358 fieldNum := -1 359 wire := new(wireType) 360 // A wireType defines a single field. 361 delta := deb.delta(-1) 362 fieldNum += delta 363 switch fieldNum { 364 case 0: // array type, one field of {{Common}, elem, length} 365 // Field number 0 is CommonType 366 deb.delta(1) 367 com := deb.common() 368 // Field number 1 is type Id of elem 369 deb.delta(1) 370 id := deb.typeId() 371 // Field number 3 is length 372 deb.delta(1) 373 length := deb.int() 374 wire.ArrayT = &arrayType{com, id, length} 375 376 case 1: // slice type, one field of {{Common}, elem} 377 // Field number 0 is CommonType 378 deb.delta(1) 379 com := deb.common() 380 // Field number 1 is type Id of elem 381 deb.delta(1) 382 id := deb.typeId() 383 wire.SliceT = &sliceType{com, id} 384 385 case 2: // struct type, one field of {{Common}, []fieldType} 386 // Field number 0 is CommonType 387 deb.delta(1) 388 com := deb.common() 389 // Field number 1 is slice of FieldType 390 deb.delta(1) 391 numField := int(deb.uint()) 392 field := make([]*fieldType, numField) 393 for i := 0; i < numField; i++ { 394 field[i] = new(fieldType) 395 deb.delta(1) // field 0 of fieldType: name 396 field[i].Name = deb.string() 397 deb.delta(1) // field 1 of fieldType: id 398 field[i].Id = deb.typeId() 399 deb.delta(0) // end of fieldType 400 } 401 wire.StructT = &structType{com, field} 402 403 case 3: // map type, one field of {{Common}, key, elem} 404 // Field number 0 is CommonType 405 deb.delta(1) 406 com := deb.common() 407 // Field number 1 is type Id of key 408 deb.delta(1) 409 keyId := deb.typeId() 410 // Field number 2 is type Id of elem 411 deb.delta(1) 412 elemId := deb.typeId() 413 wire.MapT = &mapType{com, keyId, elemId} 414 case 4: // GobEncoder type, one field of {{Common}} 415 // Field number 0 is CommonType 416 deb.delta(1) 417 com := deb.common() 418 wire.GobEncoderT = &gobEncoderType{com} 419 case 5: // BinaryMarshaler type, one field of {{Common}} 420 // Field number 0 is CommonType 421 deb.delta(1) 422 com := deb.common() 423 wire.BinaryMarshalerT = &gobEncoderType{com} 424 case 6: // TextMarshaler type, one field of {{Common}} 425 // Field number 0 is CommonType 426 deb.delta(1) 427 com := deb.common() 428 wire.TextMarshalerT = &gobEncoderType{com} 429 default: 430 errorf("bad field in type %d", fieldNum) 431 } 432 deb.printWireType(indent, wire) 433 deb.delta(0) // end inner type (arrayType, etc.) 434 deb.delta(0) // end wireType 435 // Remember we've seen this type. 436 deb.wireType[id] = wire 437 } 438 439 // Value: 440 // SingletonValue | StructValue 441 func (deb *debugger) value(indent tab, id typeId) { 442 wire, ok := deb.wireType[id] 443 if ok && wire.StructT != nil { 444 deb.structValue(indent, id) 445 } else { 446 deb.singletonValue(indent, id) 447 } 448 } 449 450 // SingletonValue: 451 // uint(0) FieldValue 452 func (deb *debugger) singletonValue(indent tab, id typeId) { 453 deb.dump("Singleton value") 454 // is it a builtin type? 455 wire := deb.wireType[id] 456 _, ok := builtinIdToType[id] 457 if !ok && wire == nil { 458 errorf("type id %d not defined", id) 459 } 460 m := deb.uint64() 461 if m != 0 { 462 errorf("expected zero; got %d", m) 463 } 464 deb.fieldValue(indent, id) 465 } 466 467 // InterfaceValue: 468 // NilInterfaceValue | NonNilInterfaceValue 469 func (deb *debugger) interfaceValue(indent tab) { 470 deb.dump("Start of interface value") 471 if nameLen := deb.uint64(); nameLen == 0 { 472 deb.nilInterfaceValue(indent) 473 } else { 474 deb.nonNilInterfaceValue(indent, int(nameLen)) 475 } 476 } 477 478 // NilInterfaceValue: 479 // uint(0) [already read] 480 func (deb *debugger) nilInterfaceValue(indent tab) int { 481 fmt.Fprintf(os.Stderr, "%snil interface\n", indent) 482 return 0 483 } 484 485 // NonNilInterfaceValue: 486 // ConcreteTypeName TypeSequence InterfaceContents 487 // ConcreteTypeName: 488 // uint(lengthOfName) [already read=n] name 489 // InterfaceContents: 490 // int(concreteTypeId) DelimitedValue 491 // DelimitedValue: 492 // uint(length) Value 493 func (deb *debugger) nonNilInterfaceValue(indent tab, nameLen int) { 494 // ConcreteTypeName 495 b := make([]byte, nameLen) 496 deb.r.Read(b) // TODO: CHECK THESE READS!! 497 deb.consumed(nameLen) 498 name := string(b) 499 500 for { 501 id := deb.typeId() 502 if id < 0 { 503 deb.typeDefinition(indent, -id) 504 n := deb.loadBlock(false) 505 deb.dump("Nested message of length %d", n) 506 } else { 507 // DelimitedValue 508 x := deb.uint64() // in case we want to ignore the value; we don't. 509 fmt.Fprintf(os.Stderr, "%sinterface value, type %q id=%d; valueLength %d\n", indent, name, id, x) 510 deb.value(indent, id) 511 break 512 } 513 } 514 } 515 516 // printCommonType prints a common type; used by printWireType. 517 func (deb *debugger) printCommonType(indent tab, kind string, common *CommonType) { 518 indent.print() 519 fmt.Fprintf(os.Stderr, "%s %q id=%d\n", kind, common.Name, common.Id) 520 } 521 522 // printWireType prints the contents of a wireType. 523 func (deb *debugger) printWireType(indent tab, wire *wireType) { 524 fmt.Fprintf(os.Stderr, "%stype definition {\n", indent) 525 indent++ 526 switch { 527 case wire.ArrayT != nil: 528 deb.printCommonType(indent, "array", &wire.ArrayT.CommonType) 529 fmt.Fprintf(os.Stderr, "%slen %d\n", indent+1, wire.ArrayT.Len) 530 fmt.Fprintf(os.Stderr, "%selemid %d\n", indent+1, wire.ArrayT.Elem) 531 case wire.MapT != nil: 532 deb.printCommonType(indent, "map", &wire.MapT.CommonType) 533 fmt.Fprintf(os.Stderr, "%skey id=%d\n", indent+1, wire.MapT.Key) 534 fmt.Fprintf(os.Stderr, "%selem id=%d\n", indent+1, wire.MapT.Elem) 535 case wire.SliceT != nil: 536 deb.printCommonType(indent, "slice", &wire.SliceT.CommonType) 537 fmt.Fprintf(os.Stderr, "%selem id=%d\n", indent+1, wire.SliceT.Elem) 538 case wire.StructT != nil: 539 deb.printCommonType(indent, "struct", &wire.StructT.CommonType) 540 for i, field := range wire.StructT.Field { 541 fmt.Fprintf(os.Stderr, "%sfield %d:\t%s\tid=%d\n", indent+1, i, field.Name, field.Id) 542 } 543 case wire.GobEncoderT != nil: 544 deb.printCommonType(indent, "GobEncoder", &wire.GobEncoderT.CommonType) 545 } 546 indent-- 547 fmt.Fprintf(os.Stderr, "%s}\n", indent) 548 } 549 550 // fieldValue prints a value of any type, such as a struct field. 551 // FieldValue: 552 // builtinValue | ArrayValue | MapValue | SliceValue | StructValue | InterfaceValue 553 func (deb *debugger) fieldValue(indent tab, id typeId) { 554 _, ok := builtinIdToType[id] 555 if ok { 556 if id == tInterface { 557 deb.interfaceValue(indent) 558 } else { 559 deb.printBuiltin(indent, id) 560 } 561 return 562 } 563 wire, ok := deb.wireType[id] 564 if !ok { 565 errorf("type id %d not defined", id) 566 } 567 switch { 568 case wire.ArrayT != nil: 569 deb.arrayValue(indent, wire) 570 case wire.MapT != nil: 571 deb.mapValue(indent, wire) 572 case wire.SliceT != nil: 573 deb.sliceValue(indent, wire) 574 case wire.StructT != nil: 575 deb.structValue(indent, id) 576 case wire.GobEncoderT != nil: 577 deb.gobEncoderValue(indent, id) 578 default: 579 panic("bad wire type for field") 580 } 581 } 582 583 // printBuiltin prints a value not of a fundamental type, that is, 584 // one whose type is known to gobs at bootstrap time. 585 func (deb *debugger) printBuiltin(indent tab, id typeId) { 586 switch id { 587 case tBool: 588 x := deb.int64() 589 if x == 0 { 590 fmt.Fprintf(os.Stderr, "%sfalse\n", indent) 591 } else { 592 fmt.Fprintf(os.Stderr, "%strue\n", indent) 593 } 594 case tInt: 595 x := deb.int64() 596 fmt.Fprintf(os.Stderr, "%s%d\n", indent, x) 597 case tUint: 598 x := deb.uint64() 599 fmt.Fprintf(os.Stderr, "%s%d\n", indent, x) 600 case tFloat: 601 x := deb.uint64() 602 fmt.Fprintf(os.Stderr, "%s%g\n", indent, float64FromBits(x)) 603 case tComplex: 604 r := deb.uint64() 605 i := deb.uint64() 606 fmt.Fprintf(os.Stderr, "%s%g+%gi\n", indent, float64FromBits(r), float64FromBits(i)) 607 case tBytes: 608 x := int(deb.uint64()) 609 b := make([]byte, x) 610 deb.r.Read(b) 611 deb.consumed(x) 612 fmt.Fprintf(os.Stderr, "%s{% x}=%q\n", indent, b, b) 613 case tString: 614 x := int(deb.uint64()) 615 b := make([]byte, x) 616 deb.r.Read(b) 617 deb.consumed(x) 618 fmt.Fprintf(os.Stderr, "%s%q\n", indent, b) 619 default: 620 panic("unknown builtin") 621 } 622 } 623 624 // ArrayValue: 625 // uint(n) FieldValue*n 626 func (deb *debugger) arrayValue(indent tab, wire *wireType) { 627 elemId := wire.ArrayT.Elem 628 u := deb.uint64() 629 length := int(u) 630 for i := 0; i < length; i++ { 631 deb.fieldValue(indent, elemId) 632 } 633 if length != wire.ArrayT.Len { 634 fmt.Fprintf(os.Stderr, "%s(wrong length for array: %d should be %d)\n", indent, length, wire.ArrayT.Len) 635 } 636 } 637 638 // MapValue: 639 // uint(n) (FieldValue FieldValue)*n [n (key, value) pairs] 640 func (deb *debugger) mapValue(indent tab, wire *wireType) { 641 keyId := wire.MapT.Key 642 elemId := wire.MapT.Elem 643 u := deb.uint64() 644 length := int(u) 645 for i := 0; i < length; i++ { 646 deb.fieldValue(indent+1, keyId) 647 deb.fieldValue(indent+1, elemId) 648 } 649 } 650 651 // SliceValue: 652 // uint(n) (n FieldValue) 653 func (deb *debugger) sliceValue(indent tab, wire *wireType) { 654 elemId := wire.SliceT.Elem 655 u := deb.uint64() 656 length := int(u) 657 deb.dump("Start of slice of length %d", length) 658 659 for i := 0; i < length; i++ { 660 deb.fieldValue(indent, elemId) 661 } 662 } 663 664 // StructValue: 665 // (uint(fieldDelta) FieldValue)* 666 func (deb *debugger) structValue(indent tab, id typeId) { 667 deb.dump("Start of struct value of %q id=%d\n<<\n", id.name(), id) 668 fmt.Fprintf(os.Stderr, "%s%s struct {\n", indent, id.name()) 669 wire, ok := deb.wireType[id] 670 if !ok { 671 errorf("type id %d not defined", id) 672 } 673 strct := wire.StructT 674 fieldNum := -1 675 indent++ 676 for { 677 delta := deb.uint64() 678 if delta == 0 { // struct terminator is zero delta fieldnum 679 break 680 } 681 fieldNum += int(delta) 682 if fieldNum < 0 || fieldNum >= len(strct.Field) { 683 deb.dump("field number out of range: prevField=%d delta=%d", fieldNum-int(delta), delta) 684 break 685 } 686 fmt.Fprintf(os.Stderr, "%sfield %d:\t%s\n", indent, fieldNum, wire.StructT.Field[fieldNum].Name) 687 deb.fieldValue(indent+1, strct.Field[fieldNum].Id) 688 } 689 indent-- 690 fmt.Fprintf(os.Stderr, "%s} // end %s struct\n", indent, id.name()) 691 deb.dump(">> End of struct value of type %d %q", id, id.name()) 692 } 693 694 // GobEncoderValue: 695 // uint(n) byte*n 696 func (deb *debugger) gobEncoderValue(indent tab, id typeId) { 697 len := deb.uint64() 698 deb.dump("GobEncoder value of %q id=%d, length %d\n", id.name(), id, len) 699 fmt.Fprintf(os.Stderr, "%s%s (implements GobEncoder)\n", indent, id.name()) 700 data := make([]byte, len) 701 _, err := deb.r.Read(data) 702 if err != nil { 703 errorf("gobEncoder data read: %s", err) 704 } 705 fmt.Fprintf(os.Stderr, "%s[% .2x]\n", indent+1, data) 706 }