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 9package 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 17import ( 18 "bytes" 19 "fmt" 20 "io" 21 "os" 22 "strings" 23 "sync" 24) 25 26var 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. 30func init() { 31 debugFunc = Debug 32} 33 34var ( 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. 41type tab int 42 43func (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 51func (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. 57type peekReader struct { 58 r io.Reader 59 data []byte // read-ahead data 60} 61 62// newPeekReader returns a peekReader that wraps r. 63func 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. 68func (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. 82func (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 110type 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. 122func (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. 167func 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. 176func 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 193func (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. 201func (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. 208func (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) 220func (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 232func (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. 249func (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 280func (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. 302func (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). 326func (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). 331func (deb *debugger) int() int { 332 return int(deb.int64()) 333} 334 335// typeId returns the type id at the input point. 336func (deb *debugger) typeId() typeId { 337 return typeId(deb.int64()) 338} 339 340// string returns the string at the input point. 341func (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. 354func (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 365func (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 452func (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 464func (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 481func (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] 493func (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 513func (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. 537func (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. 543func (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 574func (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. 605func (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 647func (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] 662func (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) 676func (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)* 690func (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 721func (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} 732