1 package gob
2
3
4
5
6
7
8 import (
9 "bytes"
10 "fmt"
11 "io"
12 "os"
13 "strings"
14 "sync"
15 )
16
17 var dumpBytes = false
18
19
20
21 func init() {
22 debugFunc = Debug
23 }
24
25 var (
26 blanks = bytes.Repeat([]byte{' '}, 3*10)
27 empty = []byte(": <empty>\n")
28 tabs = strings.Repeat("\t", 100)
29 )
30
31
32 type tab int
33
34 func (t tab) String() string {
35 n := int(t)
36 if n > len(tabs) {
37 n = len(tabs)
38 }
39 return tabs[0:n]
40 }
41
42 func (t tab) print() {
43 fmt.Fprint(os.Stderr, t)
44 }
45
46
47
48 type peekReader struct {
49 r io.Reader
50 data []byte
51 }
52
53
54 func newPeekReader(r io.Reader) *peekReader {
55 return &peekReader{r: r}
56 }
57
58
59 func (p *peekReader) Read(b []byte) (n int, err os.Error) {
60 if len(p.data) == 0 {
61 return p.r.Read(b)
62 }
63
64 n = copy(b, p.data)
65
66 copy(p.data, p.data[n:])
67 p.data = p.data[:len(p.data)-n]
68 return
69 }
70
71
72
73 func (p *peekReader) peek(b []byte) (n int, err os.Error) {
74 if len(p.data) > 0 {
75 n = copy(b, p.data)
76 if n == len(b) {
77 return
78 }
79 b = b[n:]
80 }
81 if len(b) == 0 {
82 return
83 }
84 m, e := io.ReadFull(p.r, b)
85 if m > 0 {
86 p.data = append(p.data, b[:m]...)
87 }
88 n += m
89 if e == io.ErrUnexpectedEOF {
90
91
92 if n > 0 {
93 e = nil
94 } else {
95 e = os.EOF
96 }
97 }
98 return n, e
99 }
100
101 type debugger struct {
102 mutex sync.Mutex
103 remain int
104 remainingKnown bool
105 r *peekReader
106 wireType map[typeId]*wireType
107 tmp []byte
108 }
109
110
111
112
113 func (deb *debugger) dump(format string, args ...interface{}) {
114 if !dumpBytes {
115 return
116 }
117 fmt.Fprintf(os.Stderr, format+" ", args...)
118 if !deb.remainingKnown {
119 return
120 }
121 if deb.remain < 0 {
122 fmt.Fprintf(os.Stderr, "remaining byte count is negative! %d\n", deb.remain)
123 return
124 }
125 data := make([]byte, deb.remain)
126 n, _ := deb.r.peek(data)
127 if n == 0 {
128 os.Stderr.Write(empty)
129 return
130 }
131 b := new(bytes.Buffer)
132 fmt.Fprintf(b, "[%d]{\n", deb.remain)
133
134 lineLength := 0
135 if n := len(data); n%10 != 0 {
136 lineLength = 10 - n%10
137 fmt.Fprintf(b, "\t%s", blanks[:lineLength*3])
138 }
139
140 for len(data) > 0 {
141 if lineLength == 0 {
142 fmt.Fprint(b, "\t")
143 }
144 m := 10 - lineLength
145 lineLength = 0
146 if m > len(data) {
147 m = len(data)
148 }
149 fmt.Fprintf(b, "% x\n", data[:m])
150 data = data[m:]
151 }
152 fmt.Fprint(b, "}\n")
153 os.Stderr.Write(b.Bytes())
154 }
155
156
157 func Debug(r io.Reader) {
158 err := debug(r)
159 if err != nil {
160 fmt.Fprintf(os.Stderr, "gob debug: %s\n", err)
161 }
162 }
163
164
165
166 func debug(r io.Reader) (err os.Error) {
167 defer catchError(&err)
168 fmt.Fprintln(os.Stderr, "Start of debugging")
169 deb := &debugger{
170 r: newPeekReader(r),
171 wireType: make(map[typeId]*wireType),
172 tmp: make([]byte, 16),
173 }
174 if b, ok := r.(*bytes.Buffer); ok {
175 deb.remain = b.Len()
176 deb.remainingKnown = true
177 }
178 deb.gobStream()
179 return
180 }
181
182
183 func (deb *debugger) consumed(n int) {
184 if deb.remainingKnown {
185 deb.remain -= n
186 }
187 }
188
189
190
191 func (deb *debugger) int64() int64 {
192 return toInt(deb.uint64())
193 }
194
195
196
197
198 func (deb *debugger) uint64() uint64 {
199 n, w, err := decodeUintReader(deb.r, deb.tmp)
200 if err != nil {
201 errorf("debug: read error: %s", err)
202 }
203 deb.consumed(w)
204 return n
205 }
206
207
208
209 func (deb *debugger) gobStream() {
210
211 deb.mutex.Lock()
212 defer deb.mutex.Unlock()
213
214 for deb.delimitedMessage(0) {
215 }
216 }
217
218
219
220 func (deb *debugger) delimitedMessage(indent tab) bool {
221 for {
222 n := deb.loadBlock(true)
223 if n < 0 {
224 return false
225 }
226 deb.dump("Delimited message of length %d", n)
227 deb.message(indent)
228 }
229 return true
230 }
231
232
233
234
235
236
237 func (deb *debugger) loadBlock(eofOK bool) int {
238 n64, w, err := decodeUintReader(deb.r, deb.tmp)
239 if err != nil {
240 if eofOK && err == os.EOF {
241 return -1
242 }
243 errorf("debug: unexpected error: %s", err)
244 }
245 deb.consumed(w)
246 n := int(n64)
247 if n < 0 {
248 errorf("huge value for message length: %d", n64)
249 }
250 return int(n)
251 }
252
253
254
255
256
257
258
259
260
261 func (deb *debugger) message(indent tab) bool {
262 for {
263
264 uid := deb.int64()
265 id := typeId(uid)
266 deb.dump("type id=%d", id)
267 if id < 0 {
268 deb.typeDefinition(indent, -id)
269 n := deb.loadBlock(false)
270 deb.dump("Message of length %d", n)
271 continue
272 } else {
273 deb.value(indent, id)
274 break
275 }
276 }
277 return true
278 }
279
280
281
282
283 func (deb *debugger) common() CommonType {
284 fieldNum := -1
285 name := ""
286 id := typeId(0)
287 for {
288 delta := deb.delta(-1)
289 if delta == 0 {
290 break
291 }
292 fieldNum += delta
293 switch fieldNum {
294 case 0:
295 name = deb.string()
296 case 1:
297
298 id = deb.typeId()
299 default:
300 errorf("corrupted CommonType")
301 }
302 }
303 return CommonType{name, id}
304 }
305
306
307 func (deb *debugger) uint() uint {
308 return uint(deb.uint64())
309 }
310
311
312 func (deb *debugger) int() int {
313 return int(deb.int64())
314 }
315
316
317 func (deb *debugger) typeId() typeId {
318 return typeId(deb.int64())
319 }
320
321
322 func (deb *debugger) string() string {
323 x := int(deb.uint64())
324 b := make([]byte, x)
325 nb, _ := deb.r.Read(b)
326 if nb != x {
327 errorf("corrupted type")
328 }
329 deb.consumed(nb)
330 return string(b)
331 }
332
333
334
335 func (deb *debugger) delta(expect int) int {
336 delta := int(deb.uint64())
337 if delta < 0 || (expect >= 0 && delta != expect) {
338 errorf("decode: corrupted type: delta %d expected %d", delta, expect)
339 }
340 return delta
341 }
342
343
344
345 func (deb *debugger) typeDefinition(indent tab, id typeId) {
346 deb.dump("type definition for id %d", id)
347
348 fieldNum := -1
349 wire := new(wireType)
350
351 delta := deb.delta(-1)
352 fieldNum += delta
353 switch fieldNum {
354 case 0:
355
356 deb.delta(1)
357 com := deb.common()
358
359 deb.delta(1)
360 id := deb.typeId()
361
362 deb.delta(1)
363 length := deb.int()
364 wire.ArrayT = &arrayType{com, id, length}
365
366 case 1:
367
368 deb.delta(1)
369 com := deb.common()
370
371 deb.delta(1)
372 id := deb.typeId()
373 wire.SliceT = &sliceType{com, id}
374
375 case 2:
376
377 deb.delta(1)
378 com := deb.common()
379
380 deb.delta(1)
381 numField := int(deb.uint())
382 field := make([]*fieldType, numField)
383 for i := 0; i < numField; i++ {
384 field[i] = new(fieldType)
385 deb.delta(1)
386 field[i].Name = deb.string()
387 deb.delta(1)
388 field[i].Id = deb.typeId()
389 deb.delta(0)
390 }
391 wire.StructT = &structType{com, field}
392
393 case 3:
394
395 deb.delta(1)
396 com := deb.common()
397
398 deb.delta(1)
399 keyId := deb.typeId()
400
401 deb.delta(1)
402 elemId := deb.typeId()
403 wire.MapT = &mapType{com, keyId, elemId}
404 case 4:
405
406 deb.delta(1)
407 com := deb.common()
408 wire.GobEncoderT = &gobEncoderType{com}
409 default:
410 errorf("bad field in type %d", fieldNum)
411 }
412 deb.printWireType(indent, wire)
413 deb.delta(0)
414 deb.delta(0)
415
416 deb.wireType[id] = wire
417 }
418
419
420
421 func (deb *debugger) value(indent tab, id typeId) {
422 wire, ok := deb.wireType[id]
423 if ok && wire.StructT != nil {
424 deb.structValue(indent, id)
425 } else {
426 deb.singletonValue(indent, id)
427 }
428 }
429
430
431
432 func (deb *debugger) singletonValue(indent tab, id typeId) {
433 deb.dump("Singleton value")
434
435 wire := deb.wireType[id]
436 _, ok := builtinIdToType[id]
437 if !ok && wire == nil {
438 errorf("type id %d not defined", id)
439 }
440 m := deb.uint64()
441 if m != 0 {
442 errorf("expected zero; got %d", m)
443 }
444 deb.fieldValue(indent, id)
445 }
446
447
448
449 func (deb *debugger) interfaceValue(indent tab) {
450 deb.dump("Start of interface value")
451 if nameLen := deb.uint64(); nameLen == 0 {
452 deb.nilInterfaceValue(indent)
453 } else {
454 deb.nonNilInterfaceValue(indent, int(nameLen))
455 }
456 }
457
458
459
460 func (deb *debugger) nilInterfaceValue(indent tab) int {
461 fmt.Fprintf(os.Stderr, "%snil interface\n", indent)
462 return 0
463 }
464
465
466
467
468
469
470
471
472
473 func (deb *debugger) nonNilInterfaceValue(indent tab, nameLen int) {
474
475 b := make([]byte, nameLen)
476 deb.r.Read(b)
477 deb.consumed(nameLen)
478 name := string(b)
479
480 for {
481 id := deb.typeId()
482 if id < 0 {
483 deb.typeDefinition(indent, -id)
484 n := deb.loadBlock(false)
485 deb.dump("Nested message of length %d", n)
486 } else {
487
488 x := deb.uint64()
489 fmt.Fprintf(os.Stderr, "%sinterface value, type %q id=%d; valueLength %d\n", indent, name, id, x)
490 deb.value(indent, id)
491 break
492 }
493 }
494 }
495
496
497 func (deb *debugger) printCommonType(indent tab, kind string, common *CommonType) {
498 indent.print()
499 fmt.Fprintf(os.Stderr, "%s %q id=%d\n", kind, common.Name, common.Id)
500 }
501
502
503 func (deb *debugger) printWireType(indent tab, wire *wireType) {
504 fmt.Fprintf(os.Stderr, "%stype definition {\n", indent)
505 indent++
506 switch {
507 case wire.ArrayT != nil:
508 deb.printCommonType(indent, "array", &wire.ArrayT.CommonType)
509 fmt.Fprintf(os.Stderr, "%slen %d\n", indent+1, wire.ArrayT.Len)
510 fmt.Fprintf(os.Stderr, "%selemid %d\n", indent+1, wire.ArrayT.Elem)
511 case wire.MapT != nil:
512 deb.printCommonType(indent, "map", &wire.MapT.CommonType)
513 fmt.Fprintf(os.Stderr, "%skey id=%d\n", indent+1, wire.MapT.Key)
514 fmt.Fprintf(os.Stderr, "%selem id=%d\n", indent+1, wire.MapT.Elem)
515 case wire.SliceT != nil:
516 deb.printCommonType(indent, "slice", &wire.SliceT.CommonType)
517 fmt.Fprintf(os.Stderr, "%selem id=%d\n", indent+1, wire.SliceT.Elem)
518 case wire.StructT != nil:
519 deb.printCommonType(indent, "struct", &wire.StructT.CommonType)
520 for i, field := range wire.StructT.Field {
521 fmt.Fprintf(os.Stderr, "%sfield %d:\t%s\tid=%d\n", indent+1, i, field.Name, field.Id)
522 }
523 case wire.GobEncoderT != nil:
524 deb.printCommonType(indent, "GobEncoder", &wire.GobEncoderT.CommonType)
525 }
526 indent--
527 fmt.Fprintf(os.Stderr, "%s}\n", indent)
528 }
529
530
531
532
533 func (deb *debugger) fieldValue(indent tab, id typeId) {
534 _, ok := builtinIdToType[id]
535 if ok {
536 if id == tInterface {
537 deb.interfaceValue(indent)
538 } else {
539 deb.printBuiltin(indent, id)
540 }
541 return
542 }
543 wire, ok := deb.wireType[id]
544 if !ok {
545 errorf("type id %d not defined", id)
546 }
547 switch {
548 case wire.ArrayT != nil:
549 deb.arrayValue(indent, wire)
550 case wire.MapT != nil:
551 deb.mapValue(indent, wire)
552 case wire.SliceT != nil:
553 deb.sliceValue(indent, wire)
554 case wire.StructT != nil:
555 deb.structValue(indent, id)
556 case wire.GobEncoderT != nil:
557 deb.gobEncoderValue(indent, id)
558 default:
559 panic("bad wire type for field")
560 }
561 }
562
563
564
565 func (deb *debugger) printBuiltin(indent tab, id typeId) {
566 switch id {
567 case tBool:
568 x := deb.int64()
569 if x == 0 {
570 fmt.Fprintf(os.Stderr, "%sfalse\n", indent)
571 } else {
572 fmt.Fprintf(os.Stderr, "%strue\n", indent)
573 }
574 case tInt:
575 x := deb.int64()
576 fmt.Fprintf(os.Stderr, "%s%d\n", indent, x)
577 case tUint:
578 x := deb.int64()
579 fmt.Fprintf(os.Stderr, "%s%d\n", indent, x)
580 case tFloat:
581 x := deb.uint64()
582 fmt.Fprintf(os.Stderr, "%s%g\n", indent, floatFromBits(x))
583 case tComplex:
584 r := deb.uint64()
585 i := deb.uint64()
586 fmt.Fprintf(os.Stderr, "%s%g+%gi\n", indent, floatFromBits(r), floatFromBits(i))
587 case tBytes:
588 x := int(deb.uint64())
589 b := make([]byte, x)
590 deb.r.Read(b)
591 deb.consumed(x)
592 fmt.Fprintf(os.Stderr, "%s{% x}=%q\n", indent, b, b)
593 case tString:
594 x := int(deb.uint64())
595 b := make([]byte, x)
596 deb.r.Read(b)
597 deb.consumed(x)
598 fmt.Fprintf(os.Stderr, "%s%q\n", indent, b)
599 default:
600 panic("unknown builtin")
601 }
602 }
603
604
605
606 func (deb *debugger) arrayValue(indent tab, wire *wireType) {
607 elemId := wire.ArrayT.Elem
608 u := deb.uint64()
609 length := int(u)
610 for i := 0; i < length; i++ {
611 deb.fieldValue(indent, elemId)
612 }
613 if length != wire.ArrayT.Len {
614 fmt.Fprintf(os.Stderr, "%s(wrong length for array: %d should be %d)\n", indent, length, wire.ArrayT.Len)
615 }
616 }
617
618
619
620 func (deb *debugger) mapValue(indent tab, wire *wireType) {
621 keyId := wire.MapT.Key
622 elemId := wire.MapT.Elem
623 u := deb.uint64()
624 length := int(u)
625 for i := 0; i < length; i++ {
626 deb.fieldValue(indent+1, keyId)
627 deb.fieldValue(indent+1, elemId)
628 }
629 }
630
631
632
633 func (deb *debugger) sliceValue(indent tab, wire *wireType) {
634 elemId := wire.SliceT.Elem
635 u := deb.uint64()
636 length := int(u)
637 deb.dump("Start of slice of length %d", length)
638
639 for i := 0; i < length; i++ {
640 deb.fieldValue(indent, elemId)
641 }
642 }
643
644
645
646 func (deb *debugger) structValue(indent tab, id typeId) {
647 deb.dump("Start of struct value of %q id=%d\n<<\n", id.name(), id)
648 fmt.Fprintf(os.Stderr, "%s%s struct {\n", indent, id.name())
649 wire, ok := deb.wireType[id]
650 if !ok {
651 errorf("type id %d not defined", id)
652 }
653 strct := wire.StructT
654 fieldNum := -1
655 indent++
656 for {
657 delta := deb.uint64()
658 if delta == 0 {
659 break
660 }
661 fieldNum += int(delta)
662 if fieldNum < 0 || fieldNum >= len(strct.Field) {
663 deb.dump("field number out of range: prevField=%d delta=%d", fieldNum-int(delta), delta)
664 break
665 }
666 fmt.Fprintf(os.Stderr, "%sfield %d:\t%s\n", indent, fieldNum, wire.StructT.Field[fieldNum].Name)
667 deb.fieldValue(indent+1, strct.Field[fieldNum].Id)
668 }
669 indent--
670 fmt.Fprintf(os.Stderr, "%s} // end %s struct\n", indent, id.name())
671 deb.dump(">> End of struct value of type %d %q", id, id.name())
672 }
673
674
675
676 func (deb *debugger) gobEncoderValue(indent tab, id typeId) {
677 len := deb.uint64()
678 deb.dump("GobEncoder value of %q id=%d, length %d\n", id.name(), id, len)
679 fmt.Fprintf(os.Stderr, "%s%s (implements GobEncoder)\n", indent, id.name())
680 data := make([]byte, len)
681 _, err := deb.r.Read(data)
682 if err != nil {
683 errorf("gobEncoder data read: %s", err)
684 }
685 fmt.Fprintf(os.Stderr, "%s[% .2x]\n", indent+1, data)
686 }