1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package ptrace
18
19 import (
20 "encoding/binary"
21 "math/rand"
22 "os"
23 "os/exec"
24 "testing"
25 "time"
26 "unsafe"
27
28 . "github.com/onsi/ginkgo/v2"
29 . "github.com/onsi/gomega"
30
31 "github.com/chaos-mesh/chaos-mesh/pkg/log"
32 "github.com/chaos-mesh/chaos-mesh/test/pkg/timer"
33 )
34
35 func TestPTrace(t *testing.T) {
36 RegisterFailHandler(Fail)
37
38 RunSpecs(t, "PTrace Suit")
39 }
40
41 var _ = BeforeSuite(func(done Done) {
42 rand.Seed(GinkgoRandomSeed())
43
44 By("change working directory")
45
46 err := os.Chdir("../../")
47 Expect(err).NotTo(HaveOccurred())
48
49 By("register logger")
50
51 close(done)
52 })
53
54
55
56
57 var _ = Describe("PTrace", func() {
58
59 logger, err := log.NewDefaultZapLogger()
60 Expect(err).NotTo(HaveOccurred())
61
62 var t *timer.Timer
63 var program *TracedProgram
64
65 BeforeEach(func() {
66 var err error
67
68 t, err = timer.StartTimer()
69 Expect(err).ShouldNot(HaveOccurred(), "error: %+v", err)
70
71 time.Sleep(time.Millisecond)
72
73 program, err = Trace(t.Pid(), logger)
74 Expect(err).ShouldNot(HaveOccurred(), "error: %+v", err)
75 })
76
77 AfterEach(func() {
78 err := program.Detach()
79 Expect(err).ShouldNot(HaveOccurred(), "error: %+v", err)
80
81 err = t.Stop()
82 Expect(err).ShouldNot(HaveOccurred(), "error: %+v", err)
83 })
84
85 It("should mmap slice successfully", func() {
86 Expect(program.Pid()).Should(Equal(t.Pid()))
87
88 helloWorld := []byte("Hello World")
89 entry, err := program.MmapSlice(helloWorld)
90 Expect(err).ShouldNot(HaveOccurred(), "error: %+v", err)
91
92 readBuf, err := program.ReadSlice(entry.StartAddress, uint64(len(helloWorld)))
93 Expect(err).ShouldNot(HaveOccurred(), "error: %+v", err)
94
95 Expect(*readBuf).Should(Equal(helloWorld))
96 })
97
98 It("double trace should get error", func() {
99 _, err := Trace(t.Pid(), logger)
100 Expect(err).Should(HaveOccurred())
101 })
102
103 It("should ptrace write slice successfully", func() {
104 helloWorld := []byte("Hello World")
105 addr, err := program.Mmap(uint64(len(helloWorld)), 0)
106 Expect(err).ShouldNot(HaveOccurred(), "error: %+v", err)
107
108 err = program.PtraceWriteSlice(addr, helloWorld)
109 Expect(err).ShouldNot(HaveOccurred(), "error: %+v, addr: %d", err, addr)
110
111 readBuf, err := program.ReadSlice(addr, uint64(len(helloWorld)))
112 Expect(err).ShouldNot(HaveOccurred(), "error: %+v, addr: %d", err, addr)
113
114 Expect(*readBuf).Should(Equal(helloWorld))
115 })
116
117 It("should write uint64 successfully", func() {
118 number := rand.Uint64()
119 size := uint64(unsafe.Sizeof(number))
120 expectBuf := make([]byte, size)
121 binary.LittleEndian.PutUint64(expectBuf, number)
122
123 addr, err := program.Mmap(size, 0)
124 Expect(err).ShouldNot(HaveOccurred(), "error: %+v", err)
125
126 err = program.WriteUint64ToAddr(addr, number)
127 Expect(err).ShouldNot(HaveOccurred(), "error: %+v, addr: %d", err, addr)
128
129 readBuf, err := program.ReadSlice(addr, size)
130 Expect(err).ShouldNot(HaveOccurred(), "error: %+v, addr: %d", err, addr)
131
132 Expect(*readBuf).Should(Equal(expectBuf))
133 })
134
135 It("should be able to detach and reattach", func() {
136 err := program.Detach()
137 Expect(err).ShouldNot(HaveOccurred(), "error: %+v", err)
138
139 program, err = Trace(t.Pid(), logger)
140 Expect(err).ShouldNot(HaveOccurred(), "error: %+v", err)
141 })
142
143 It("should be able to attach and detach multithread program", func() {
144 p := exec.Command("./bin/test/multithread_tracee")
145 err := p.Start()
146 Expect(err).ShouldNot(HaveOccurred(), "error: %+v", err)
147
148 time.Sleep(time.Millisecond)
149
150 pid := p.Process.Pid
151 program, err := Trace(pid, logger)
152 Expect(err).ShouldNot(HaveOccurred(), "error: %+v", err)
153
154 err = program.Detach()
155 Expect(err).ShouldNot(HaveOccurred(), "error: %+v", err)
156
157 err = p.Process.Kill()
158 Expect(err).ShouldNot(HaveOccurred(), "error: %+v", err)
159 })
160 })
161