1
2
3
4
5
6
7
8
9 package gob
10
11
12
13
14
15
16
17 import (
18 "bytes"
19 "fmt"
20 "io"
21 "os"
22 "strings"
23 "sync"
24 )
25
26 var dumpBytes = false
27
28
29
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
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
56
57 type peekReader struct {
58 r io.Reader
59 data []byte
60 }
61
62
63 func newPeekReader(r io.Reader) *peekReader {
64 return &peekReader{r: r}
65 }
66
67
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
73 n = copy(b, p.data)
74
75 copy(p.data, p.data[n:])
76 p.data = p.data[:len(p.data)-n]
77 return
78 }
79
80
81
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
100
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
113 remainingKnown bool
114 r *peekReader
115 wireType map[typeId]*wireType
116 tmp []byte
117 }
118
119
120
121
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
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
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
166
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
175
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
193 func (deb *debugger) consumed(n int) {
194 if deb.remainingKnown {
195 deb.remain -= n
196 }
197 }
198
199
200
201 func (deb *debugger) int64() int64 {
202 return toInt(deb.uint64())
203 }
204
205
206
207
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
218
219 func (deb *debugger) gobStream() {
220
221 deb.mutex.Lock()
222 defer deb.mutex.Unlock()
223
224 for deb.delimitedMessage(0) {
225 }
226 }
227
228
229
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
243
244
245
246
247 func (deb *debugger) loadBlock(eofOK bool) int {
248 n64, w, err := decodeUintReader(deb.r, deb.tmp)
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
264
265
266
267
268
269
270
271 func (deb *debugger) message(indent tab) bool {
272 for {
273
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
291
292
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
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
317 func (deb *debugger) uint() uint {
318 return uint(deb.uint64())
319 }
320
321
322 func (deb *debugger) int() int {
323 return int(deb.int64())
324 }
325
326
327 func (deb *debugger) typeId() typeId {
328 return typeId(deb.int64())
329 }
330
331
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
344
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
354
355 func (deb *debugger) typeDefinition(indent tab, id typeId) {
356 deb.dump("type definition for id %d", id)
357
358 fieldNum := -1
359 wire := new(wireType)
360
361 delta := deb.delta(-1)
362 fieldNum += delta
363 switch fieldNum {
364 case 0:
365
366 deb.delta(1)
367 com := deb.common()
368
369 deb.delta(1)
370 id := deb.typeId()
371
372 deb.delta(1)
373 length := deb.int()
374 wire.ArrayT = &arrayType{com, id, length}
375
376 case 1:
377
378 deb.delta(1)
379 com := deb.common()
380
381 deb.delta(1)
382 id := deb.typeId()
383 wire.SliceT = &sliceType{com, id}
384
385 case 2:
386
387 deb.delta(1)
388 com := deb.common()
389
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)
396 field[i].Name = deb.string()
397 deb.delta(1)
398 field[i].Id = deb.typeId()
399 deb.delta(0)
400 }
401 wire.StructT = &structType{com, field}
402
403 case 3:
404
405 deb.delta(1)
406 com := deb.common()
407
408 deb.delta(1)
409 keyId := deb.typeId()
410
411 deb.delta(1)
412 elemId := deb.typeId()
413 wire.MapT = &mapType{com, keyId, elemId}
414 case 4:
415
416 deb.delta(1)
417 com := deb.common()
418 wire.GobEncoderT = &gobEncoderType{com}
419 case 5:
420
421 deb.delta(1)
422 com := deb.common()
423 wire.BinaryMarshalerT = &gobEncoderType{com}
424 case 6:
425
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)
434 deb.delta(0)
435
436 deb.wireType[id] = wire
437 }
438
439
440
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
451
452 func (deb *debugger) singletonValue(indent tab, id typeId) {
453 deb.dump("Singleton value")
454
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
468
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
479
480 func (deb *debugger) nilInterfaceValue(indent tab) int {
481 fmt.Fprintf(os.Stderr, "%snil interface\n", indent)
482 return 0
483 }
484
485
486
487
488
489
490
491
492
493 func (deb *debugger) nonNilInterfaceValue(indent tab, nameLen int) {
494
495 b := make([]byte, nameLen)
496 deb.r.Read(b)
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
508 x := deb.uint64()
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
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
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
551
552
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
584
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
625
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
639
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
652
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
665
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 {
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
695
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 }
707
View as plain text