LEFT | RIGHT |
(no file at all) | |
1 // Copyright 2014 The Go Authors. All rights reserved. | 1 // Copyright 2014 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 package server | 5 package server |
6 | |
7 // TODO: syscall.PTRACE_O_TRACECLONE shenanigans to trace multi-threaded | |
8 // programs. | |
9 | 6 |
10 import ( | 7 import ( |
11 "fmt" | 8 "fmt" |
12 "os" | 9 "os" |
13 "runtime" | 10 "runtime" |
14 "syscall" | 11 "syscall" |
15 ) | 12 ) |
16 | 13 |
17 // ptraceRun runs all the closures from fc on a dedicated OS thread. Errors | 14 // ptraceRun runs all the closures from fc on a dedicated OS thread. Errors |
18 // are returned on ec. Both channels must be unbuffered, to ensure that the | 15 // are returned on ec. Both channels must be unbuffered, to ensure that the |
(...skipping 24 matching lines...) Expand all Loading... |
43 return <-s.ec | 40 return <-s.ec |
44 } | 41 } |
45 | 42 |
46 func (s *Server) ptraceGetRegs(pid int, regsout *syscall.PtraceRegs) (err error)
{ | 43 func (s *Server) ptraceGetRegs(pid int, regsout *syscall.PtraceRegs) (err error)
{ |
47 s.fc <- func() error { | 44 s.fc <- func() error { |
48 return syscall.PtraceGetRegs(pid, regsout) | 45 return syscall.PtraceGetRegs(pid, regsout) |
49 } | 46 } |
50 return <-s.ec | 47 return <-s.ec |
51 } | 48 } |
52 | 49 |
53 func (s *Server) ptraceSetRegs(pid int, regs *syscall.PtraceRegs) (err error) { | |
54 s.fc <- func() error { | |
55 return syscall.PtraceSetRegs(pid, regs) | |
56 } | |
57 return <-s.ec | |
58 } | |
59 | |
60 func (s *Server) ptracePeek(pid int, addr uintptr, out []byte) (err error) { | 50 func (s *Server) ptracePeek(pid int, addr uintptr, out []byte) (err error) { |
61 s.fc <- func() error { | 51 s.fc <- func() error { |
62 n, err := syscall.PtracePeekText(pid, addr, out) | 52 n, err := syscall.PtracePeekText(pid, addr, out) |
63 if err != nil { | 53 if err != nil { |
64 return err | 54 return err |
65 } | 55 } |
66 if n != len(out) { | 56 if n != len(out) { |
67 return fmt.Errorf("ptracePeek: peeked %d bytes, want %d"
, n, len(out)) | 57 return fmt.Errorf("ptracePeek: peeked %d bytes, want %d"
, n, len(out)) |
68 } | 58 } |
69 return nil | 59 return nil |
70 } | 60 } |
71 return <-s.ec | 61 return <-s.ec |
72 } | 62 } |
73 | 63 |
74 func (s *Server) ptracePoke(pid int, addr uintptr, data []byte) (err error) { | 64 func (s *Server) ptracePoke(pid int, addr uintptr, data []byte) (err error) { |
75 s.fc <- func() error { | 65 s.fc <- func() error { |
76 n, err := syscall.PtracePokeText(pid, addr, data) | 66 n, err := syscall.PtracePokeText(pid, addr, data) |
77 if err != nil { | 67 if err != nil { |
78 return err | 68 return err |
79 } | 69 } |
80 if n != len(data) { | 70 if n != len(data) { |
81 return fmt.Errorf("ptracePoke: poked %d bytes, want %d",
n, len(data)) | 71 return fmt.Errorf("ptracePoke: poked %d bytes, want %d",
n, len(data)) |
82 } | 72 } |
83 return nil | 73 return nil |
84 } | 74 } |
85 return <-s.ec | 75 return <-s.ec |
86 } | 76 } |
87 | 77 |
| 78 func (s *Server) ptraceSetOptions(pid int, options int) (err error) { |
| 79 s.fc <- func() error { |
| 80 return syscall.PtraceSetOptions(pid, options) |
| 81 } |
| 82 return <-s.ec |
| 83 } |
| 84 |
| 85 func (s *Server) ptraceSetRegs(pid int, regs *syscall.PtraceRegs) (err error) { |
| 86 s.fc <- func() error { |
| 87 return syscall.PtraceSetRegs(pid, regs) |
| 88 } |
| 89 return <-s.ec |
| 90 } |
| 91 |
88 func (s *Server) ptraceSingleStep(pid int) (err error) { | 92 func (s *Server) ptraceSingleStep(pid int) (err error) { |
89 s.fc <- func() error { | 93 s.fc <- func() error { |
90 return syscall.PtraceSingleStep(pid) | 94 return syscall.PtraceSingleStep(pid) |
91 } | 95 } |
92 return <-s.ec | 96 return <-s.ec |
93 } | 97 } |
94 | 98 |
95 func (s *Server) wait() (err error) { | 99 func (s *Server) wait(pid int) (wpid int, status syscall.WaitStatus, err error)
{ |
96 » var status syscall.WaitStatus | |
97 s.fc <- func() error { | 100 s.fc <- func() error { |
98 » » _, err1 := syscall.Wait4(-1, &status, 0, nil) | 101 » » var err1 error |
| 102 » » wpid, err1 = syscall.Wait4(pid, &status, syscall.WALL, nil) |
99 return err1 | 103 return err1 |
100 } | 104 } |
101 » // TODO: do something with status. | 105 » return wpid, status, <-s.ec |
102 » return <-s.ec | |
103 } | 106 } |
LEFT | RIGHT |