Source file
src/runtime/hexdump_test.go
1
2
3
4
5 package runtime_test
6
7 import (
8 "fmt"
9 "internal/abi"
10 "internal/goarch"
11 "runtime"
12 "slices"
13 "strings"
14 "testing"
15 "unsafe"
16 )
17
18 func TestHexdumper(t *testing.T) {
19 check := func(label, got, want string) {
20 got = strings.TrimRight(got, "\n")
21 want = strings.TrimPrefix(want, "\n")
22 want = strings.TrimRight(want, "\n")
23 if got != want {
24 t.Errorf("%s: got\n%s\nwant\n%s", label, got, want)
25 }
26 }
27
28 data := make([]byte, 32)
29 for i := range data {
30 data[i] = 0x10 + byte(i)
31 }
32
33 check("basic", runtime.Hexdumper(0, 1, nil, data), `
34 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
35 00000000: 10111213 14151617 18191a1b 1c1d1e1f ................
36 00000010: 20212223 24252627 28292a2b 2c2d2e2f !"#$%&'()*+,-./`)
37
38 if !goarch.BigEndian {
39
40 check("word=4", runtime.Hexdumper(0, 4, nil, data), `
41 3 2 1 0 7 6 5 4 b a 9 8 f e d c 0123456789abcdef
42 00000000: 13121110 17161514 1b1a1918 1f1e1d1c ................
43 00000010: 23222120 27262524 2b2a2928 2f2e2d2c !"#$%&'()*+,-./`)
44 check("word=8", runtime.Hexdumper(0, 8, nil, data), `
45 7 6 5 4 3 2 1 0 f e d c b a 9 8 0123456789abcdef
46 00000000: 17161514 13121110 1f1e1d1c 1b1a1918 ................
47 00000010: 27262524 23222120 2f2e2d2c 2b2a2928 !"#$%&'()*+,-./`)
48 }
49
50
51 check("offset=1", runtime.Hexdumper(1, 1, nil, data), `
52 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
53 00000000: 101112 13141516 1718191a 1b1c1d1e ...............
54 00000010: 1f202122 23242526 2728292a 2b2c2d2e . !"#$%&'()*+,-.
55 00000020: 2f /`)
56 if !goarch.BigEndian {
57
58 check("offset=1 and word=4", runtime.Hexdumper(1, 4, nil, data), `
59 3 2 1 0 7 6 5 4 b a 9 8 f e d c 0123456789abcdef
60 00000000: 121110 16151413 1a191817 1e1d1c1b ...............
61 00000010: 2221201f 26252423 2a292827 2e2d2c2b . !"#$%&'()*+,-.
62 00000020: 2f /`)
63 }
64
65
66 partials := make([][]byte, 0)
67 for i := 0; i < len(data); i += 2 {
68 partials = append(partials, data[i:i+2])
69 }
70 check("partials", runtime.Hexdumper(1, 1, nil, partials...), `
71 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
72 00000000: 101112 13141516 1718191a 1b1c1d1e ...............
73 00000010: 1f202122 23242526 2728292a 2b2c2d2e . !"#$%&'()*+,-.
74 00000020: 2f /`)
75
76
77 check("marks", runtime.Hexdumper(0, 1, func(addr uintptr, start func()) {
78 if addr%7 == 0 {
79 start()
80 println("mark")
81 }
82 }, data), `
83 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
84 00000000: 10111213 14151617 18191a1b 1c1d1e1f ................
85 ^ mark
86 ^ mark
87 ^ mark
88 00000010: 20212223 24252627 28292a2b 2c2d2e2f !"#$%&'()*+,-./
89 ^ mark
90 ^ mark`)
91 if !goarch.BigEndian {
92 check("marks and word=4", runtime.Hexdumper(0, 4, func(addr uintptr, start func()) {
93 if addr%7 == 0 {
94 start()
95 println("mark")
96 }
97 }, data), `
98 3 2 1 0 7 6 5 4 b a 9 8 f e d c 0123456789abcdef
99 00000000: 13121110 17161514 1b1a1918 1f1e1d1c ................
100 ^ mark
101 00000010: 23222120 27262524 2b2a2928 2f2e2d2c !"#$%&'()*+,-./
102 ^ mark`)
103 }
104 }
105
106 func TestHexdumpWords(t *testing.T) {
107 if goarch.BigEndian || goarch.PtrSize != 8 {
108
109 t.Skip("requires 64-bit little endian")
110 }
111
112
113
114 pc := abi.FuncPCABIInternal(TestHexdumpWords)
115 pcs := slices.Repeat([]uintptr{pc}, 3)
116
117
118 var p runtime.Pinner
119 defer p.Unpin()
120 p.Pin(&pcs[0])
121
122 start := uintptr(unsafe.Pointer(&pcs[0]))
123 start = (start + 15) &^ uintptr(15)
124
125
126 got := runtime.HexdumpWords(start, 16)
127
128
129 pcStr := fmt.Sprintf("%016x", pc)
130 pcStr = pcStr[:8] + " " + pcStr[8:]
131 ascii := make([]byte, 8)
132 for i := range ascii {
133 b := byte(pc >> (8 * i))
134 if b >= ' ' && b <= '~' {
135 ascii[i] = b
136 } else {
137 ascii[i] = '.'
138 }
139 }
140 want := fmt.Sprintf(`
141 7 6 5 4 3 2 1 0 f e d c b a 9 8 0123456789abcdef
142 %016x: %s %s %s%s
143 ^ <runtime_test.TestHexdumpWords+0x0>
144 ^ <runtime_test.TestHexdumpWords+0x0>
145 `, start, pcStr, pcStr, ascii, ascii)
146 want = strings.TrimPrefix(want, "\n")
147
148 if got != want {
149 t.Errorf("got\n%s\nwant\n%s", got, want)
150 }
151 }
152
View as plain text