github.com/ice-blockchain/go/src@v0.0.0-20240403114104-1564d284e521/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 // 7 //go: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 ...any) { 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 // 219 // DelimitedMessage* (until EOF) 220 func (deb *debugger) gobStream() { 221 // Make sure we're single-threaded through here. 222 deb.mutex.Lock() 223 defer deb.mutex.Unlock() 224 225 for deb.delimitedMessage(0) { 226 } 227 } 228 229 // DelimitedMessage: 230 // 231 // uint(lengthOfMessage) Message 232 func (deb *debugger) delimitedMessage(indent tab) bool { 233 for { 234 n := deb.loadBlock(true) 235 if n < 0 { 236 return false 237 } 238 deb.dump("Delimited message of length %d", n) 239 deb.message(indent) 240 } 241 return true 242 } 243 244 // loadBlock preps us to read a message 245 // of the length specified next in the input. It returns 246 // the length of the block. The argument tells whether 247 // an EOF is acceptable now. If it is and one is found, 248 // the return value is negative. 249 func (deb *debugger) loadBlock(eofOK bool) int { 250 n64, w, err := decodeUintReader(deb.r, deb.tmp) // deb.uint64 will error at EOF 251 if err != nil { 252 if eofOK && err == io.EOF { 253 return -1 254 } 255 errorf("debug: unexpected error: %s", err) 256 } 257 deb.consumed(w) 258 n := int(n64) 259 if n < 0 { 260 errorf("huge value for message length: %d", n64) 261 } 262 return int(n) 263 } 264 265 // Message: 266 // 267 // TypeSequence TypedValue 268 // 269 // TypeSequence 270 // 271 // (TypeDefinition DelimitedTypeDefinition*)? 272 // 273 // DelimitedTypeDefinition: 274 // 275 // uint(lengthOfTypeDefinition) TypeDefinition 276 // 277 // TypedValue: 278 // 279 // int(typeId) Value 280 func (deb *debugger) message(indent tab) bool { 281 for { 282 // Convert the uint64 to a signed integer typeId 283 uid := deb.int64() 284 id := typeId(uid) 285 deb.dump("type id=%d", id) 286 if id < 0 { 287 deb.typeDefinition(indent, -id) 288 n := deb.loadBlock(false) 289 deb.dump("Message of length %d", n) 290 continue 291 } else { 292 deb.value(indent, id) 293 break 294 } 295 } 296 return true 297 } 298 299 // Helper methods to make it easy to scan a type descriptor. 300 301 // common returns the CommonType at the input point. 302 func (deb *debugger) common() CommonType { 303 fieldNum := -1 304 name := "" 305 id := typeId(0) 306 for { 307 delta := deb.delta(-1) 308 if delta == 0 { 309 break 310 } 311 fieldNum += delta 312 switch fieldNum { 313 case 0: 314 name = deb.string() 315 case 1: 316 // Id typeId 317 id = deb.typeId() 318 default: 319 errorf("corrupted CommonType, delta is %d fieldNum is %d", delta, fieldNum) 320 } 321 } 322 return CommonType{name, id} 323 } 324 325 // uint returns the unsigned int at the input point, as a uint (not uint64). 326 func (deb *debugger) uint() uint { 327 return uint(deb.uint64()) 328 } 329 330 // int returns the signed int at the input point, as an int (not int64). 331 func (deb *debugger) int() int { 332 return int(deb.int64()) 333 } 334 335 // typeId returns the type id at the input point. 336 func (deb *debugger) typeId() typeId { 337 return typeId(deb.int64()) 338 } 339 340 // string returns the string at the input point. 341 func (deb *debugger) string() string { 342 x := int(deb.uint64()) 343 b := make([]byte, x) 344 nb, _ := deb.r.Read(b) 345 if nb != x { 346 errorf("corrupted type") 347 } 348 deb.consumed(nb) 349 return string(b) 350 } 351 352 // delta returns the field delta at the input point. The expect argument, 353 // if non-negative, identifies what the value should be. 354 func (deb *debugger) delta(expect int) int { 355 delta := int(deb.uint64()) 356 if delta < 0 || (expect >= 0 && delta != expect) { 357 errorf("decode: corrupted type: delta %d expected %d", delta, expect) 358 } 359 return delta 360 } 361 362 // TypeDefinition: 363 // 364 // [int(-typeId) (already read)] encodingOfWireType 365 func (deb *debugger) typeDefinition(indent tab, id typeId) { 366 deb.dump("type definition for id %d", id) 367 // Encoding is of a wireType. Decode the structure as usual 368 fieldNum := -1 369 wire := new(wireType) 370 // A wireType defines a single field. 371 delta := deb.delta(-1) 372 fieldNum += delta 373 switch fieldNum { 374 case 0: // array type, one field of {{Common}, elem, length} 375 // Field number 0 is CommonType 376 deb.delta(1) 377 com := deb.common() 378 // Field number 1 is type Id of elem 379 deb.delta(1) 380 id := deb.typeId() 381 // Field number 3 is length 382 deb.delta(1) 383 length := deb.int() 384 wire.ArrayT = &arrayType{com, id, length} 385 386 case 1: // slice type, one field of {{Common}, elem} 387 // Field number 0 is CommonType 388 deb.delta(1) 389 com := deb.common() 390 // Field number 1 is type Id of elem 391 deb.delta(1) 392 id := deb.typeId() 393 wire.SliceT = &sliceType{com, id} 394 395 case 2: // struct type, one field of {{Common}, []fieldType} 396 // Field number 0 is CommonType 397 deb.delta(1) 398 com := deb.common() 399 // Field number 1 is slice of FieldType 400 deb.delta(1) 401 numField := int(deb.uint()) 402 field := make([]*fieldType, numField) 403 for i := 0; i < numField; i++ { 404 field[i] = new(fieldType) 405 deb.delta(1) // field 0 of fieldType: name 406 field[i].Name = deb.string() 407 deb.delta(1) // field 1 of fieldType: id 408 field[i].Id = deb.typeId() 409 deb.delta(0) // end of fieldType 410 } 411 wire.StructT = &structType{com, field} 412 413 case 3: // map type, one field of {{Common}, key, elem} 414 // Field number 0 is CommonType 415 deb.delta(1) 416 com := deb.common() 417 // Field number 1 is type Id of key 418 deb.delta(1) 419 keyId := deb.typeId() 420 // Field number 2 is type Id of elem 421 deb.delta(1) 422 elemId := deb.typeId() 423 wire.MapT = &mapType{com, keyId, elemId} 424 case 4: // GobEncoder type, one field of {{Common}} 425 // Field number 0 is CommonType 426 deb.delta(1) 427 com := deb.common() 428 wire.GobEncoderT = &gobEncoderType{com} 429 case 5: // BinaryMarshaler type, one field of {{Common}} 430 // Field number 0 is CommonType 431 deb.delta(1) 432 com := deb.common() 433 wire.BinaryMarshalerT = &gobEncoderType{com} 434 case 6: // TextMarshaler type, one field of {{Common}} 435 // Field number 0 is CommonType 436 deb.delta(1) 437 com := deb.common() 438 wire.TextMarshalerT = &gobEncoderType{com} 439 default: 440 errorf("bad field in type %d", fieldNum) 441 } 442 deb.printWireType(indent, wire) 443 deb.delta(0) // end inner type (arrayType, etc.) 444 deb.delta(0) // end wireType 445 // Remember we've seen this type. 446 deb.wireType[id] = wire 447 } 448 449 // Value: 450 // 451 // SingletonValue | StructValue 452 func (deb *debugger) value(indent tab, id typeId) { 453 wire, ok := deb.wireType[id] 454 if ok && wire.StructT != nil { 455 deb.structValue(indent, id) 456 } else { 457 deb.singletonValue(indent, id) 458 } 459 } 460 461 // SingletonValue: 462 // 463 // uint(0) FieldValue 464 func (deb *debugger) singletonValue(indent tab, id typeId) { 465 deb.dump("Singleton value") 466 // is it a builtin type? 467 wire := deb.wireType[id] 468 if builtinIdToType(id) == nil && wire == nil { 469 errorf("type id %d not defined", id) 470 } 471 m := deb.uint64() 472 if m != 0 { 473 errorf("expected zero; got %d", m) 474 } 475 deb.fieldValue(indent, id) 476 } 477 478 // InterfaceValue: 479 // 480 // NilInterfaceValue | NonNilInterfaceValue 481 func (deb *debugger) interfaceValue(indent tab) { 482 deb.dump("Start of interface value") 483 if nameLen := deb.uint64(); nameLen == 0 { 484 deb.nilInterfaceValue(indent) 485 } else { 486 deb.nonNilInterfaceValue(indent, int(nameLen)) 487 } 488 } 489 490 // NilInterfaceValue: 491 // 492 // uint(0) [already read] 493 func (deb *debugger) nilInterfaceValue(indent tab) int { 494 fmt.Fprintf(os.Stderr, "%snil interface\n", indent) 495 return 0 496 } 497 498 // NonNilInterfaceValue: 499 // 500 // ConcreteTypeName TypeSequence InterfaceContents 501 // 502 // ConcreteTypeName: 503 // 504 // uint(lengthOfName) [already read=n] name 505 // 506 // InterfaceContents: 507 // 508 // int(concreteTypeId) DelimitedValue 509 // 510 // DelimitedValue: 511 // 512 // uint(length) Value 513 func (deb *debugger) nonNilInterfaceValue(indent tab, nameLen int) { 514 // ConcreteTypeName 515 b := make([]byte, nameLen) 516 deb.r.Read(b) // TODO: CHECK THESE READS!! 517 deb.consumed(nameLen) 518 name := string(b) 519 520 for { 521 id := deb.typeId() 522 if id < 0 { 523 deb.typeDefinition(indent, -id) 524 n := deb.loadBlock(false) 525 deb.dump("Nested message of length %d", n) 526 } else { 527 // DelimitedValue 528 x := deb.uint64() // in case we want to ignore the value; we don't. 529 fmt.Fprintf(os.Stderr, "%sinterface value, type %q id=%d; valueLength %d\n", indent, name, id, x) 530 deb.value(indent, id) 531 break 532 } 533 } 534 } 535 536 // printCommonType prints a common type; used by printWireType. 537 func (deb *debugger) printCommonType(indent tab, kind string, common *CommonType) { 538 indent.print() 539 fmt.Fprintf(os.Stderr, "%s %q id=%d\n", kind, common.Name, common.Id) 540 } 541 542 // printWireType prints the contents of a wireType. 543 func (deb *debugger) printWireType(indent tab, wire *wireType) { 544 fmt.Fprintf(os.Stderr, "%stype definition {\n", indent) 545 indent++ 546 switch { 547 case wire.ArrayT != nil: 548 deb.printCommonType(indent, "array", &wire.ArrayT.CommonType) 549 fmt.Fprintf(os.Stderr, "%slen %d\n", indent+1, wire.ArrayT.Len) 550 fmt.Fprintf(os.Stderr, "%selemid %d\n", indent+1, wire.ArrayT.Elem) 551 case wire.MapT != nil: 552 deb.printCommonType(indent, "map", &wire.MapT.CommonType) 553 fmt.Fprintf(os.Stderr, "%skey id=%d\n", indent+1, wire.MapT.Key) 554 fmt.Fprintf(os.Stderr, "%selem id=%d\n", indent+1, wire.MapT.Elem) 555 case wire.SliceT != nil: 556 deb.printCommonType(indent, "slice", &wire.SliceT.CommonType) 557 fmt.Fprintf(os.Stderr, "%selem id=%d\n", indent+1, wire.SliceT.Elem) 558 case wire.StructT != nil: 559 deb.printCommonType(indent, "struct", &wire.StructT.CommonType) 560 for i, field := range wire.StructT.Field { 561 fmt.Fprintf(os.Stderr, "%sfield %d:\t%s\tid=%d\n", indent+1, i, field.Name, field.Id) 562 } 563 case wire.GobEncoderT != nil: 564 deb.printCommonType(indent, "GobEncoder", &wire.GobEncoderT.CommonType) 565 } 566 indent-- 567 fmt.Fprintf(os.Stderr, "%s}\n", indent) 568 } 569 570 // fieldValue prints a value of any type, such as a struct field. 571 // FieldValue: 572 // 573 // builtinValue | ArrayValue | MapValue | SliceValue | StructValue | InterfaceValue 574 func (deb *debugger) fieldValue(indent tab, id typeId) { 575 if builtinIdToType(id) != nil { 576 if id == tInterface { 577 deb.interfaceValue(indent) 578 } else { 579 deb.printBuiltin(indent, id) 580 } 581 return 582 } 583 wire, ok := deb.wireType[id] 584 if !ok { 585 errorf("type id %d not defined", id) 586 } 587 switch { 588 case wire.ArrayT != nil: 589 deb.arrayValue(indent, wire) 590 case wire.MapT != nil: 591 deb.mapValue(indent, wire) 592 case wire.SliceT != nil: 593 deb.sliceValue(indent, wire) 594 case wire.StructT != nil: 595 deb.structValue(indent, id) 596 case wire.GobEncoderT != nil: 597 deb.gobEncoderValue(indent, id) 598 default: 599 panic("bad wire type for field") 600 } 601 } 602 603 // printBuiltin prints a value not of a fundamental type, that is, 604 // one whose type is known to gobs at bootstrap time. 605 func (deb *debugger) printBuiltin(indent tab, id typeId) { 606 switch id { 607 case tBool: 608 x := deb.int64() 609 if x == 0 { 610 fmt.Fprintf(os.Stderr, "%sfalse\n", indent) 611 } else { 612 fmt.Fprintf(os.Stderr, "%strue\n", indent) 613 } 614 case tInt: 615 x := deb.int64() 616 fmt.Fprintf(os.Stderr, "%s%d\n", indent, x) 617 case tUint: 618 x := deb.uint64() 619 fmt.Fprintf(os.Stderr, "%s%d\n", indent, x) 620 case tFloat: 621 x := deb.uint64() 622 fmt.Fprintf(os.Stderr, "%s%g\n", indent, float64FromBits(x)) 623 case tComplex: 624 r := deb.uint64() 625 i := deb.uint64() 626 fmt.Fprintf(os.Stderr, "%s%g+%gi\n", indent, float64FromBits(r), float64FromBits(i)) 627 case tBytes: 628 x := int(deb.uint64()) 629 b := make([]byte, x) 630 deb.r.Read(b) 631 deb.consumed(x) 632 fmt.Fprintf(os.Stderr, "%s{% x}=%q\n", indent, b, b) 633 case tString: 634 x := int(deb.uint64()) 635 b := make([]byte, x) 636 deb.r.Read(b) 637 deb.consumed(x) 638 fmt.Fprintf(os.Stderr, "%s%q\n", indent, b) 639 default: 640 panic("unknown builtin") 641 } 642 } 643 644 // ArrayValue: 645 // 646 // uint(n) FieldValue*n 647 func (deb *debugger) arrayValue(indent tab, wire *wireType) { 648 elemId := wire.ArrayT.Elem 649 u := deb.uint64() 650 length := int(u) 651 for i := 0; i < length; i++ { 652 deb.fieldValue(indent, elemId) 653 } 654 if length != wire.ArrayT.Len { 655 fmt.Fprintf(os.Stderr, "%s(wrong length for array: %d should be %d)\n", indent, length, wire.ArrayT.Len) 656 } 657 } 658 659 // MapValue: 660 // 661 // uint(n) (FieldValue FieldValue)*n [n (key, value) pairs] 662 func (deb *debugger) mapValue(indent tab, wire *wireType) { 663 keyId := wire.MapT.Key 664 elemId := wire.MapT.Elem 665 u := deb.uint64() 666 length := int(u) 667 for i := 0; i < length; i++ { 668 deb.fieldValue(indent+1, keyId) 669 deb.fieldValue(indent+1, elemId) 670 } 671 } 672 673 // SliceValue: 674 // 675 // uint(n) (n FieldValue) 676 func (deb *debugger) sliceValue(indent tab, wire *wireType) { 677 elemId := wire.SliceT.Elem 678 u := deb.uint64() 679 length := int(u) 680 deb.dump("Start of slice of length %d", length) 681 682 for i := 0; i < length; i++ { 683 deb.fieldValue(indent, elemId) 684 } 685 } 686 687 // StructValue: 688 // 689 // (uint(fieldDelta) FieldValue)* 690 func (deb *debugger) structValue(indent tab, id typeId) { 691 deb.dump("Start of struct value of %q id=%d\n<<\n", id.name(), id) 692 fmt.Fprintf(os.Stderr, "%s%s struct {\n", indent, id.name()) 693 wire, ok := deb.wireType[id] 694 if !ok { 695 errorf("type id %d not defined", id) 696 } 697 strct := wire.StructT 698 fieldNum := -1 699 indent++ 700 for { 701 delta := deb.uint64() 702 if delta == 0 { // struct terminator is zero delta fieldnum 703 break 704 } 705 fieldNum += int(delta) 706 if fieldNum < 0 || fieldNum >= len(strct.Field) { 707 deb.dump("field number out of range: prevField=%d delta=%d", fieldNum-int(delta), delta) 708 break 709 } 710 fmt.Fprintf(os.Stderr, "%sfield %d:\t%s\n", indent, fieldNum, wire.StructT.Field[fieldNum].Name) 711 deb.fieldValue(indent+1, strct.Field[fieldNum].Id) 712 } 713 indent-- 714 fmt.Fprintf(os.Stderr, "%s} // end %s struct\n", indent, id.name()) 715 deb.dump(">> End of struct value of type %d %q", id, id.name()) 716 } 717 718 // GobEncoderValue: 719 // 720 // uint(n) byte*n 721 func (deb *debugger) gobEncoderValue(indent tab, id typeId) { 722 len := deb.uint64() 723 deb.dump("GobEncoder value of %q id=%d, length %d\n", id.name(), id, len) 724 fmt.Fprintf(os.Stderr, "%s%s (implements GobEncoder)\n", indent, id.name()) 725 data := make([]byte, len) 726 _, err := deb.r.Read(data) 727 if err != nil { 728 errorf("gobEncoder data read: %s", err) 729 } 730 fmt.Fprintf(os.Stderr, "%s[% .2x]\n", indent+1, data) 731 }