1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
5 // Package proc provides a platform-independent interface for
6 // tracing and controlling running processes. It supports
7 // multi-threaded processes and provides typical low-level debugging
8 // controls such as breakpoints, single stepping, and manipulating
9 // memory and registers.
12 // TODO(rsc): Have to import everything that proc_linux.go
13 // and proc_darwin.go do, because deps.bash only looks at
29 // A Cause explains why a thread is stopped.
30 type Cause interface {
34 // Regs is a set of named machine registers, including a program
35 // counter, link register, and stack pointer.
37 // TODO(austin) There's quite a proliferation of methods here. We
38 // could make a Reg interface with Get and Set and make this just PC,
39 // Link, SP, Names, and Reg. We could also put Index in Reg and that
40 // makes it easy to get the index of things like the PC (currently
41 // there's just no way to know that). This would also let us include
42 // other per-register information like how to print it.
44 // PC returns the value of the program counter.
47 // SetPC sets the program counter to val.
48 SetPC(val Word) os.Error
50 // Link returns the link register, if any.
53 // SetLink sets the link register to val.
54 SetLink(val Word) os.Error
56 // SP returns the value of the stack pointer.
59 // SetSP sets the stack pointer register to val.
60 SetSP(val Word) os.Error
62 // Names returns the names of all of the registers.
65 // Get returns the value of a register, where i corresponds to
66 // the index of the register's name in the array returned by
70 // Set sets the value of a register.
71 Set(i int, val Word) os.Error
74 // Thread is a thread in the process being traced.
75 type Thread interface {
76 // Step steps this thread by a single instruction. The thread
77 // must be stopped. If the thread is currently stopped on a
78 // breakpoint, this will step over the breakpoint.
80 // XXX What if it's stopped because of a signal?
83 // Stopped returns the reason that this thread is stopped. It
84 // is an error is the thread not stopped.
85 Stopped() (Cause, os.Error)
87 // Regs retrieves the current register values from this
88 // thread. The thread must be stopped.
89 Regs() (Regs, os.Error)
91 // Peek reads len(out) bytes from the address addr in this
92 // thread into out. The thread must be stopped. It returns
93 // the number of bytes successfully read. If an error occurs,
94 // such as attempting to read unmapped memory, this count
95 // could be short and an error will be returned. If this does
96 // encounter unmapped memory, it will read up to the byte
97 // preceding the unmapped area.
98 Peek(addr Word, out []byte) (int, os.Error)
100 // Poke writes b to the address addr in this thread. The
101 // thread must be stopped. It returns the number of bytes
102 // successfully written. If an error occurs, such as
103 // attempting to write to unmapped memory, this count could be
104 // short and an error will be returned. If this does
105 // encounter unmapped memory, it will write up to the byte
106 // preceding the unmapped area.
107 Poke(addr Word, b []byte) (int, os.Error)
110 // Process is a process being traced. It consists of a set of
111 // threads. A process can be running, stopped, or terminated. The
112 // process's state extends to all of its threads.
113 type Process interface {
114 // Threads returns an array of all threads in this process.
117 // AddBreakpoint creates a new breakpoint at program counter
118 // pc. Breakpoints can only be created when the process is
119 // stopped. It is an error if a breakpoint already exists at
121 AddBreakpoint(pc Word) os.Error
123 // RemoveBreakpoint removes the breakpoint at the program
124 // counter pc. It is an error if no breakpoint exists at pc.
125 RemoveBreakpoint(pc Word) os.Error
127 // Stop stops all running threads in this process before
131 // Continue resumes execution of all threads in this process.
132 // Any thread that is stopped on a breakpoint will be stepped
133 // over that breakpoint. Any thread that is stopped because
134 // of a signal (other than SIGSTOP or SIGTRAP) will receive
135 // the pending signal.
138 // WaitStop waits until all threads in process p are stopped
139 // as a result of some thread hitting a breakpoint, receiving
140 // a signal, creating a new thread, or exiting.
143 // Detach detaches from this process. All stopped threads
148 // Stopped is a stop cause used for threads that are stopped either by
149 // user request (e.g., from the Stop method or after single stepping),
150 // or that are stopped because some other thread caused the program to
152 type Stopped struct{}
154 func (c Stopped) String() string { return "stopped" }
156 // Breakpoint is a stop cause resulting from a thread reaching a set
160 // PC returns the program counter that the program is stopped at.
161 func (c Breakpoint) PC() Word { return Word(c) }
163 func (c Breakpoint) String() string {
164 return "breakpoint at 0x" + strconv.Uitob64(uint64(c.PC()), 16)
167 // Signal is a stop cause resulting from a thread receiving a signal.
168 // When the process is continued, the signal will be delivered.
171 // Signal returns the signal being delivered to the thread.
172 func (c Signal) Name() string { return string(c) }
174 func (c Signal) String() string { return c.Name() }
176 // ThreadCreate is a stop cause returned from an existing thread when
177 // it creates a new thread. The new thread exists in a primordial
178 // form at this point and will begin executing in earnest when the
179 // process is continued.
180 type ThreadCreate struct {
184 func (c *ThreadCreate) NewThread() Thread { return c.thread }
186 func (c *ThreadCreate) String() string { return "thread create" }
188 // ThreadExit is a stop cause resulting from a thread exiting. When
189 // this cause first arises, the thread will still be in the list of
190 // process threads and its registers and memory will still be
192 type ThreadExit struct {
197 // Exited returns true if the thread exited normally.
198 func (c *ThreadExit) Exited() bool { return c.exitStatus != -1 }
200 // ExitStatus returns the exit status of the thread if it exited
201 // normally or -1 otherwise.
202 func (c *ThreadExit) ExitStatus() int { return c.exitStatus }
204 // Signaled returns true if the thread was terminated by a signal.
205 func (c *ThreadExit) Signaled() bool { return c.exitStatus == -1 }
207 // StopSignal returns the signal that terminated the thread, or "" if
208 // it was not terminated by a signal.
209 func (c *ThreadExit) StopSignal() string { return c.signal }
211 func (c *ThreadExit) String() string {
212 res := "thread exited "
215 res += "with status " + strconv.Itoa(c.ExitStatus())
217 res += "from signal " + c.StopSignal()
219 res += "from unknown cause"