diff options
author | Robert Griesemer <gri@golang.org> | 2009-12-15 15:27:16 -0800 |
---|---|---|
committer | Robert Griesemer <gri@golang.org> | 2009-12-15 15:27:16 -0800 |
commit | 881d6064d23d9da5c7ff368bc7d41d271290deff (patch) | |
tree | 44d5d948e3f27cc7eff15ec8cd7ee5165d9a7e90 /src/pkg/debug/proc/proc_linux.go | |
parent | d9dfea3ebd51cea89fef8afc6b2377c2958b24f1 (diff) | |
download | golang-881d6064d23d9da5c7ff368bc7d41d271290deff.tar.gz |
1) Change default gofmt default settings for
parsing and printing to new syntax.
Use -oldparser to parse the old syntax,
use -oldprinter to print the old syntax.
2) Change default gofmt formatting settings
to use tabs for indentation only and to use
spaces for alignment. This will make the code
alignment insensitive to an editor's tabwidth.
Use -spaces=false to use tabs for alignment.
3) Manually changed src/exp/parser/parser_test.go
so that it doesn't try to parse the parser's
source files using the old syntax (they have
new syntax now).
4) gofmt -w src misc test/bench
2nd set of files.
R=rsc
CC=golang-dev
http://codereview.appspot.com/179067
Diffstat (limited to 'src/pkg/debug/proc/proc_linux.go')
-rw-r--r-- | src/pkg/debug/proc/proc_linux.go | 670 |
1 files changed, 335 insertions, 335 deletions
diff --git a/src/pkg/debug/proc/proc_linux.go b/src/pkg/debug/proc/proc_linux.go index b7192580d..7273e97d8 100644 --- a/src/pkg/debug/proc/proc_linux.go +++ b/src/pkg/debug/proc/proc_linux.go @@ -7,15 +7,15 @@ package proc // TODO(rsc): Imports here after to be in proc.go too in order // for deps.bash to get the right answer. import ( - "container/vector"; - "fmt"; - "io/ioutil"; - "os"; - "runtime"; - "strconv"; - "strings"; - "sync"; - "syscall"; + "container/vector" + "fmt" + "io/ioutil" + "os" + "runtime" + "strconv" + "strings" + "sync" + "syscall" ) // This is an implementation of the process tracing interface using @@ -35,9 +35,9 @@ import ( // as well as experimentation and examination of gdb's behavior. const ( - trace = false; - traceIP = false; - traceMem = false; + trace = false + traceIP = false + traceMem = false ) /* @@ -63,17 +63,17 @@ const ( type threadState string const ( - running threadState = "Running"; - singleStepping threadState = "SingleStepping"; // Transient - stopping threadState = "Stopping"; // Transient - stopped threadState = "Stopped"; - stoppedBreakpoint threadState = "StoppedBreakpoint"; - stoppedSignal threadState = "StoppedSignal"; - stoppedThreadCreate threadState = "StoppedThreadCreate"; - stoppedExiting threadState = "StoppedExiting"; - exiting threadState = "Exiting"; // Transient (except main thread) - exited threadState = "Exited"; - detached threadState = "Detached"; + running threadState = "Running" + singleStepping threadState = "SingleStepping" // Transient + stopping threadState = "Stopping" // Transient + stopped threadState = "Stopped" + stoppedBreakpoint threadState = "StoppedBreakpoint" + stoppedSignal threadState = "StoppedSignal" + stoppedThreadCreate threadState = "StoppedThreadCreate" + stoppedExiting threadState = "StoppedExiting" + exiting threadState = "Exiting" // Transient (except main thread) + exited threadState = "Exited" + detached threadState = "Detached" ) func (ts threadState) isRunning() bool { @@ -84,11 +84,11 @@ func (ts threadState) isStopped() bool { return ts == stopped || ts == stoppedBreakpoint || ts == stoppedSignal || ts == stoppedThreadCreate || ts == stoppedExiting } -func (ts threadState) isZombie() bool { return ts == exiting } +func (ts threadState) isZombie() bool { return ts == exiting } -func (ts threadState) isTerminal() bool { return ts == exited || ts == detached } +func (ts threadState) isTerminal() bool { return ts == exited || ts == detached } -func (ts threadState) String() string { return string(ts) } +func (ts threadState) String() string { return string(ts) } /* * Basic types @@ -98,15 +98,15 @@ func (ts threadState) String() string { return string(ts) } // including its program counter, the overwritten text if the // breakpoint is installed. type breakpoint struct { - pc uintptr; - olddata []byte; + pc uintptr + olddata []byte } func (bp *breakpoint) String() string { if bp == nil { return "<nil>" } - return fmt.Sprintf("%#x", bp.pc); + return fmt.Sprintf("%#x", bp.pc) } // bpinst386 is the breakpoint instruction used on 386 and amd64. @@ -114,15 +114,15 @@ var bpinst386 = []byte{0xcc} // A debugEvent represents a reason a thread stopped or a wait error. type debugEvent struct { - *os.Waitmsg; - t *thread; - err os.Error; + *os.Waitmsg + t *thread + err os.Error } // A debugReq is a request to execute a closure in the monitor thread. type debugReq struct { - f func() os.Error; - res chan os.Error; + f func() os.Error + res chan os.Error } // A transitionHandler specifies a function to be called when a thread @@ -131,8 +131,8 @@ type debugReq struct { // invokes a handler, it removes the handler from the handler queue. // The handler should re-add itself if needed. type transitionHandler struct { - handle func(*thread, threadState, threadState); - onErr func(os.Error); + handle func(*thread, threadState, threadState) + onErr func(os.Error) } // A process is a Linux process, which consists of a set of threads. @@ -146,36 +146,36 @@ type transitionHandler struct { // returns false, the monitor is not running (the ready channel has // been closed), and the reason it is not running will be stored in err. type process struct { - pid int; - threads map[int]*thread; - breakpoints map[uintptr]*breakpoint; - ready chan bool; - debugEvents chan *debugEvent; - debugReqs chan *debugReq; - stopReq chan os.Error; - transitionHandlers *vector.Vector; - err os.Error; + pid int + threads map[int]*thread + breakpoints map[uintptr]*breakpoint + ready chan bool + debugEvents chan *debugEvent + debugReqs chan *debugReq + stopReq chan os.Error + transitionHandlers *vector.Vector + err os.Error } // A thread represents a Linux thread in another process that is being // debugged. Each running thread has an associated goroutine that // waits for thread updates and sends them to the process monitor. type thread struct { - tid int; - proc *process; + tid int + proc *process // Whether to ignore the next SIGSTOP received by wait. - ignoreNextSigstop bool; + ignoreNextSigstop bool // Thread state. Only modified via setState. - state threadState; + state threadState // If state == StoppedBreakpoint - breakpoint *breakpoint; + breakpoint *breakpoint // If state == StoppedSignal or state == Exited - signal int; + signal int // If state == StoppedThreadCreate - newThread *thread; + newThread *thread // If state == Exited - exitStatus int; + exitStatus int } /* @@ -183,9 +183,9 @@ type thread struct { */ type badState struct { - thread *thread; - message string; - state threadState; + thread *thread + message string + state threadState } func (e *badState) String() string { @@ -200,12 +200,12 @@ func (e breakpointExistsError) String() string { type noBreakpointError Word -func (e noBreakpointError) String() string { return fmt.Sprintf("no breakpoint at PC %#x", e) } +func (e noBreakpointError) String() string { return fmt.Sprintf("no breakpoint at PC %#x", e) } type newThreadError struct { - *os.Waitmsg; - wantPid int; - wantSig int; + *os.Waitmsg + wantPid int + wantSig int } func (e *newThreadError) String() string { @@ -214,66 +214,66 @@ func (e *newThreadError) String() string { type ProcessExited struct{} -func (p ProcessExited) String() string { return "process exited" } +func (p ProcessExited) String() string { return "process exited" } /* * Ptrace wrappers */ func (t *thread) ptracePeekText(addr uintptr, out []byte) (int, os.Error) { - c, err := syscall.PtracePeekText(t.tid, addr, out); + c, err := syscall.PtracePeekText(t.tid, addr, out) if traceMem { fmt.Printf("peek(%#x) => %v, %v\n", addr, out, err) } - return c, os.NewSyscallError("ptrace(PEEKTEXT)", err); + return c, os.NewSyscallError("ptrace(PEEKTEXT)", err) } func (t *thread) ptracePokeText(addr uintptr, out []byte) (int, os.Error) { - c, err := syscall.PtracePokeText(t.tid, addr, out); + c, err := syscall.PtracePokeText(t.tid, addr, out) if traceMem { fmt.Printf("poke(%#x, %v) => %v\n", addr, out, err) } - return c, os.NewSyscallError("ptrace(POKETEXT)", err); + return c, os.NewSyscallError("ptrace(POKETEXT)", err) } func (t *thread) ptraceGetRegs(regs *syscall.PtraceRegs) os.Error { - err := syscall.PtraceGetRegs(t.tid, regs); - return os.NewSyscallError("ptrace(GETREGS)", err); + err := syscall.PtraceGetRegs(t.tid, regs) + return os.NewSyscallError("ptrace(GETREGS)", err) } func (t *thread) ptraceSetRegs(regs *syscall.PtraceRegs) os.Error { - err := syscall.PtraceSetRegs(t.tid, regs); - return os.NewSyscallError("ptrace(SETREGS)", err); + err := syscall.PtraceSetRegs(t.tid, regs) + return os.NewSyscallError("ptrace(SETREGS)", err) } func (t *thread) ptraceSetOptions(options int) os.Error { - err := syscall.PtraceSetOptions(t.tid, options); - return os.NewSyscallError("ptrace(SETOPTIONS)", err); + err := syscall.PtraceSetOptions(t.tid, options) + return os.NewSyscallError("ptrace(SETOPTIONS)", err) } func (t *thread) ptraceGetEventMsg() (uint, os.Error) { - msg, err := syscall.PtraceGetEventMsg(t.tid); - return msg, os.NewSyscallError("ptrace(GETEVENTMSG)", err); + msg, err := syscall.PtraceGetEventMsg(t.tid) + return msg, os.NewSyscallError("ptrace(GETEVENTMSG)", err) } func (t *thread) ptraceCont() os.Error { - err := syscall.PtraceCont(t.tid, 0); - return os.NewSyscallError("ptrace(CONT)", err); + err := syscall.PtraceCont(t.tid, 0) + return os.NewSyscallError("ptrace(CONT)", err) } func (t *thread) ptraceContWithSignal(sig int) os.Error { - err := syscall.PtraceCont(t.tid, sig); - return os.NewSyscallError("ptrace(CONT)", err); + err := syscall.PtraceCont(t.tid, sig) + return os.NewSyscallError("ptrace(CONT)", err) } func (t *thread) ptraceStep() os.Error { - err := syscall.PtraceSingleStep(t.tid); - return os.NewSyscallError("ptrace(SINGLESTEP)", err); + err := syscall.PtraceSingleStep(t.tid) + return os.NewSyscallError("ptrace(SINGLESTEP)", err) } func (t *thread) ptraceDetach() os.Error { - err := syscall.PtraceDetach(t.tid); - return os.NewSyscallError("ptrace(DETACH)", err); + err := syscall.PtraceDetach(t.tid) + return os.NewSyscallError("ptrace(DETACH)", err) } /* @@ -286,38 +286,38 @@ func (t *thread) logTrace(format string, args ...) { if !trace { return } - logLock.Lock(); - defer logLock.Unlock(); - fmt.Fprintf(os.Stderr, "Thread %d", t.tid); + logLock.Lock() + defer logLock.Unlock() + fmt.Fprintf(os.Stderr, "Thread %d", t.tid) if traceIP { - var regs syscall.PtraceRegs; - err := t.ptraceGetRegs(®s); + var regs syscall.PtraceRegs + err := t.ptraceGetRegs(®s) if err == nil { fmt.Fprintf(os.Stderr, "@%x", regs.PC()) } } - fmt.Fprint(os.Stderr, ": "); - fmt.Fprintf(os.Stderr, format, args); - fmt.Fprint(os.Stderr, "\n"); + fmt.Fprint(os.Stderr, ": ") + fmt.Fprintf(os.Stderr, format, args) + fmt.Fprint(os.Stderr, "\n") } func (t *thread) warn(format string, args ...) { - logLock.Lock(); - defer logLock.Unlock(); - fmt.Fprintf(os.Stderr, "Thread %d: WARNING ", t.tid); - fmt.Fprintf(os.Stderr, format, args); - fmt.Fprint(os.Stderr, "\n"); + logLock.Lock() + defer logLock.Unlock() + fmt.Fprintf(os.Stderr, "Thread %d: WARNING ", t.tid) + fmt.Fprintf(os.Stderr, format, args) + fmt.Fprint(os.Stderr, "\n") } func (p *process) logTrace(format string, args ...) { if !trace { return } - logLock.Lock(); - defer logLock.Unlock(); - fmt.Fprintf(os.Stderr, "Process %d: ", p.pid); - fmt.Fprintf(os.Stderr, format, args); - fmt.Fprint(os.Stderr, "\n"); + logLock.Lock() + defer logLock.Unlock() + fmt.Fprintf(os.Stderr, "Process %d: ", p.pid) + fmt.Fprintf(os.Stderr, format, args) + fmt.Fprint(os.Stderr, "\n") } /* @@ -334,7 +334,7 @@ func (p *process) someStoppedThread() *thread { return t } } - return nil; + return nil } // someRunningThread returns a running thread from the process. @@ -347,7 +347,7 @@ func (p *process) someRunningThread() *thread { return t } } - return nil; + return nil } /* @@ -358,32 +358,32 @@ func (p *process) someRunningThread() *thread { // // Must be called from the monitor thread. func (p *process) installBreakpoints() os.Error { - n := 0; - main := p.someStoppedThread(); + n := 0 + main := p.someStoppedThread() for _, b := range p.breakpoints { if b.olddata != nil { continue } - b.olddata = make([]byte, len(bpinst386)); - _, err := main.ptracePeekText(uintptr(b.pc), b.olddata); + b.olddata = make([]byte, len(bpinst386)) + _, err := main.ptracePeekText(uintptr(b.pc), b.olddata) if err != nil { - b.olddata = nil; - return err; + b.olddata = nil + return err } - _, err = main.ptracePokeText(uintptr(b.pc), bpinst386); + _, err = main.ptracePokeText(uintptr(b.pc), bpinst386) if err != nil { - b.olddata = nil; - return err; + b.olddata = nil + return err } - n++; + n++ } if n > 0 { p.logTrace("installed %d/%d breakpoints", n, len(p.breakpoints)) } - return nil; + return nil } // uninstallBreakpoints removes the installed breakpoints from p. @@ -393,25 +393,25 @@ func (p *process) uninstallBreakpoints() os.Error { if len(p.threads) == 0 { return nil } - n := 0; - main := p.someStoppedThread(); + n := 0 + main := p.someStoppedThread() for _, b := range p.breakpoints { if b.olddata == nil { continue } - _, err := main.ptracePokeText(uintptr(b.pc), b.olddata); + _, err := main.ptracePokeText(uintptr(b.pc), b.olddata) if err != nil { return err } - b.olddata = nil; - n++; + b.olddata = nil + n++ } if n > 0 { p.logTrace("uninstalled %d/%d breakpoints", n, len(p.breakpoints)) } - return nil; + return nil } /* @@ -425,17 +425,17 @@ func (p *process) uninstallBreakpoints() os.Error { // event. func (t *thread) wait() { for { - var ev debugEvent; - ev.t = t; - t.logTrace("beginning wait"); - ev.Waitmsg, ev.err = os.Wait(t.tid, syscall.WALL); + var ev debugEvent + ev.t = t + t.logTrace("beginning wait") + ev.Waitmsg, ev.err = os.Wait(t.tid, syscall.WALL) if ev.err == nil && ev.Pid != t.tid { panic("Wait returned pid ", ev.Pid, " wanted ", t.tid) } if ev.StopSignal() == syscall.SIGSTOP && t.ignoreNextSigstop { // Spurious SIGSTOP. See Thread.Stop(). - t.ignoreNextSigstop = false; - err := t.ptraceCont(); + t.ignoreNextSigstop = false + err := t.ptraceCont() if err == nil { continue } @@ -447,8 +447,8 @@ func (t *thread) wait() { // The monitor exited break } - t.proc.debugEvents <- &ev; - break; + t.proc.debugEvents <- &ev + break } } @@ -457,9 +457,9 @@ func (t *thread) wait() { // // Must be called from the monitor thread. func (t *thread) setState(newState threadState) { - oldState := t.state; - t.state = newState; - t.logTrace("state %v -> %v", oldState, newState); + oldState := t.state + t.state = newState + t.logTrace("state %v -> %v", oldState, newState) if !oldState.isRunning() && (newState.isRunning() || newState.isZombie()) { // Start waiting on this thread @@ -467,23 +467,23 @@ func (t *thread) setState(newState threadState) { } // Invoke state change handlers - handlers := t.proc.transitionHandlers; + handlers := t.proc.transitionHandlers if handlers.Len() == 0 { return } - t.proc.transitionHandlers = new(vector.Vector); + t.proc.transitionHandlers = new(vector.Vector) for _, h := range handlers.Data() { - h := h.(*transitionHandler); - h.handle(t, oldState, newState); + h := h.(*transitionHandler) + h.handle(t, oldState, newState) } } // sendSigstop sends a SIGSTOP to this thread. func (t *thread) sendSigstop() os.Error { - t.logTrace("sending SIGSTOP"); - err := syscall.Tgkill(t.proc.pid, t.tid, syscall.SIGSTOP); - return os.NewSyscallError("tgkill", err); + t.logTrace("sending SIGSTOP") + err := syscall.Tgkill(t.proc.pid, t.tid, syscall.SIGSTOP) + return os.NewSyscallError("tgkill", err) } // stopAsync sends SIGSTOP to all threads in state 'running'. @@ -492,14 +492,14 @@ func (t *thread) sendSigstop() os.Error { func (p *process) stopAsync() os.Error { for _, t := range p.threads { if t.state == running { - err := t.sendSigstop(); + err := t.sendSigstop() if err != nil { return err } - t.setState(stopping); + t.setState(stopping) } } - return nil; + return nil } // doTrap handles SIGTRAP debug events with a cause of 0. These can @@ -508,7 +508,7 @@ func (p *process) stopAsync() os.Error { // // TODO(austin) I think we also get this on an execve syscall. func (ev *debugEvent) doTrap() (threadState, os.Error) { - t := ev.t; + t := ev.t if t.state == singleStepping { return stopped, nil @@ -517,13 +517,13 @@ func (ev *debugEvent) doTrap() (threadState, os.Error) { // Hit a breakpoint. Linux leaves the program counter after // the breakpoint. If this is an installed breakpoint, we // need to back the PC up to the breakpoint PC. - var regs syscall.PtraceRegs; - err := t.ptraceGetRegs(®s); + var regs syscall.PtraceRegs + err := t.ptraceGetRegs(®s) if err != nil { return stopped, err } - b, ok := t.proc.breakpoints[uintptr(regs.PC())-uintptr(len(bpinst386))]; + b, ok := t.proc.breakpoints[uintptr(regs.PC())-uintptr(len(bpinst386))] if !ok { // We must have hit a breakpoint that was actually in // the program. Leave the IP where it is so we don't @@ -532,38 +532,38 @@ func (ev *debugEvent) doTrap() (threadState, os.Error) { return stoppedSignal, nil } - t.breakpoint = b; - t.logTrace("at breakpoint %v, backing up PC from %#x", b, regs.PC()); + t.breakpoint = b + t.logTrace("at breakpoint %v, backing up PC from %#x", b, regs.PC()) - regs.SetPC(uint64(b.pc)); - err = t.ptraceSetRegs(®s); + regs.SetPC(uint64(b.pc)) + err = t.ptraceSetRegs(®s) if err != nil { return stopped, err } - return stoppedBreakpoint, nil; + return stoppedBreakpoint, nil } // doPtraceClone handles SIGTRAP debug events with a PTRACE_EVENT_CLONE // cause. It initializes the new thread, adds it to the process, and // returns the appropriate thread state for the existing thread. func (ev *debugEvent) doPtraceClone() (threadState, os.Error) { - t := ev.t; + t := ev.t // Get the TID of the new thread - tid, err := t.ptraceGetEventMsg(); + tid, err := t.ptraceGetEventMsg() if err != nil { return stopped, err } - nt, err := t.proc.newThread(int(tid), syscall.SIGSTOP, true); + nt, err := t.proc.newThread(int(tid), syscall.SIGSTOP, true) if err != nil { return stopped, err } // Remember the thread - t.newThread = nt; + t.newThread = nt - return stoppedThreadCreate, nil; + return stoppedThreadCreate, nil } // doPtraceExit handles SIGTRAP debug events with a PTRACE_EVENT_EXIT @@ -571,15 +571,15 @@ func (ev *debugEvent) doPtraceClone() (threadState, os.Error) { // the process. A later WIFEXITED debug event will remove it from the // process. func (ev *debugEvent) doPtraceExit() (threadState, os.Error) { - t := ev.t; + t := ev.t // Get exit status - exitStatus, err := t.ptraceGetEventMsg(); + exitStatus, err := t.ptraceGetEventMsg() if err != nil { return stopped, err } - ws := syscall.WaitStatus(exitStatus); - t.logTrace("exited with %v", ws); + ws := syscall.WaitStatus(exitStatus) + t.logTrace("exited with %v", ws) switch { case ws.Exited(): t.exitStatus = ws.ExitStatus() @@ -589,7 +589,7 @@ func (ev *debugEvent) doPtraceExit() (threadState, os.Error) { // We still need to continue this thread and wait on this // thread's WIFEXITED event. We'll delete it then. - return stoppedExiting, nil; + return stoppedExiting, nil } // process handles a debug event. It modifies any thread or process @@ -600,20 +600,20 @@ func (ev *debugEvent) process() os.Error { return ev.err } - t := ev.t; - t.exitStatus = -1; - t.signal = -1; + t := ev.t + t.exitStatus = -1 + t.signal = -1 // Decode wait status. - var state threadState; + var state threadState switch { case ev.Stopped(): - state = stoppedSignal; - t.signal = ev.StopSignal(); - t.logTrace("stopped with %v", ev); + state = stoppedSignal + t.signal = ev.StopSignal() + t.logTrace("stopped with %v", ev) if ev.StopSignal() == syscall.SIGTRAP { // What caused the debug trap? - var err os.Error; + var err os.Error switch cause := ev.TrapCause(); cause { case 0: // Breakpoint or single stepping @@ -630,25 +630,25 @@ func (ev *debugEvent) process() os.Error { } if err != nil { - t.setState(stopped); - t.warn("failed to handle trap %v: %v", ev, err); + t.setState(stopped) + t.warn("failed to handle trap %v: %v", ev, err) } } case ev.Exited(): - state = exited; - t.proc.threads[t.tid] = nil, false; - t.logTrace("exited %v", ev); + state = exited + t.proc.threads[t.tid] = nil, false + t.logTrace("exited %v", ev) // We should have gotten the exit status in // PTRACE_EVENT_EXIT, but just in case. - t.exitStatus = ev.ExitStatus(); + t.exitStatus = ev.ExitStatus() case ev.Signaled(): - state = exited; - t.proc.threads[t.tid] = nil, false; - t.logTrace("signaled %v", ev); + state = exited + t.proc.threads[t.tid] = nil, false + t.logTrace("signaled %v", ev) // Again, this should be redundant. - t.signal = ev.Signal(); + t.signal = ev.Signal() default: panic(fmt.Sprintf("Unexpected wait status %v", ev.Waitmsg)) @@ -666,14 +666,14 @@ func (ev *debugEvent) process() os.Error { // TODO(austin) If we're in state stopping and get a SIGSTOP, // set state stopped instead of stoppedSignal. - t.setState(state); + t.setState(state) if t.proc.someRunningThread() == nil { // Nothing is running, uninstall breakpoints return t.proc.uninstallBreakpoints() } // Stop any other running threads - return t.proc.stopAsync(); + return t.proc.stopAsync() } // onStop adds a handler for state transitions from running to @@ -686,15 +686,15 @@ func (t *thread) onStop(handle func(), onErr func(os.Error)) { // stepping all threads during a continue. Maybe move // transitionHandlers to the thread, or have both per-thread // and per-process transition handlers. - h := &transitionHandler{nil, onErr}; + h := &transitionHandler{nil, onErr} h.handle = func(st *thread, old, new threadState) { if t == st && old.isRunning() && !new.isRunning() { handle() } else { t.proc.transitionHandlers.Push(h) } - }; - t.proc.transitionHandlers.Push(h); + } + t.proc.transitionHandlers.Push(h) } /* @@ -704,17 +704,17 @@ func (t *thread) onStop(handle func(), onErr func(os.Error)) { // monitor handles debug events and debug requests for p, exiting when // there are no threads left in p. func (p *process) monitor() { - var err os.Error; + var err os.Error // Linux requires that all ptrace calls come from the thread // that originally attached. Prevent the Go scheduler from // migrating us to other OS threads. - runtime.LockOSThread(); - defer runtime.UnlockOSThread(); + runtime.LockOSThread() + defer runtime.UnlockOSThread() - hadThreads := false; + hadThreads := false for err == nil { - p.ready <- true; + p.ready <- true select { case event := <-p.debugEvents: err = event.process() @@ -728,8 +728,8 @@ func (p *process) monitor() { if len(p.threads) == 0 { if err == nil && hadThreads { - p.logTrace("no more threads; monitor exiting"); - err = ProcessExited{}; + p.logTrace("no more threads; monitor exiting") + err = ProcessExited{} } } else { hadThreads = true @@ -739,13 +739,13 @@ func (p *process) monitor() { // Abort waiting handlers // TODO(austin) How do I stop the wait threads? for _, h := range p.transitionHandlers.Data() { - h := h.(*transitionHandler); - h.onErr(err); + h := h.(*transitionHandler) + h.onErr(err) } // Indicate that the monitor cannot receive any more messages - p.err = err; - close(p.ready); + p.err = err + close(p.ready) } // do executes f in the monitor thread (and, thus, atomically with @@ -756,9 +756,9 @@ func (p *process) do(f func() os.Error) os.Error { if !<-p.ready { return p.err } - req := &debugReq{f, make(chan os.Error)}; - p.debugReqs <- req; - return <-req.res; + req := &debugReq{f, make(chan os.Error)} + p.debugReqs <- req + return <-req.res } // stopMonitor stops the monitor with the given error. If the monitor @@ -777,14 +777,14 @@ func (p *process) stopMonitor(err os.Error) { */ func (t *thread) Regs() (Regs, os.Error) { - var regs syscall.PtraceRegs; + var regs syscall.PtraceRegs err := t.proc.do(func() os.Error { if !t.state.isStopped() { return &badState{t, "cannot get registers", t.state} } - return t.ptraceGetRegs(®s); - }); + return t.ptraceGetRegs(®s) + }) if err != nil { return nil, err } @@ -794,42 +794,42 @@ func (t *thread) Regs() (Regs, os.Error) { if !t.state.isStopped() { return &badState{t, "cannot get registers", t.state} } - return t.ptraceSetRegs(r); + return t.ptraceSetRegs(r) }) - }; - return newRegs(®s, setter), nil; + } + return newRegs(®s, setter), nil } func (t *thread) Peek(addr Word, out []byte) (int, os.Error) { - var c int; + var c int err := t.proc.do(func() os.Error { if !t.state.isStopped() { return &badState{t, "cannot peek text", t.state} } - var err os.Error; - c, err = t.ptracePeekText(uintptr(addr), out); - return err; - }); + var err os.Error + c, err = t.ptracePeekText(uintptr(addr), out) + return err + }) - return c, err; + return c, err } func (t *thread) Poke(addr Word, out []byte) (int, os.Error) { - var c int; + var c int err := t.proc.do(func() os.Error { if !t.state.isStopped() { return &badState{t, "cannot poke text", t.state} } - var err os.Error; - c, err = t.ptracePokeText(uintptr(addr), out); - return err; - }); + var err os.Error + c, err = t.ptracePokeText(uintptr(addr), out) + return err + }) - return c, err; + return c, err } // stepAsync starts this thread single stepping. When the single step @@ -841,30 +841,30 @@ func (t *thread) stepAsync(ready chan os.Error) os.Error { if err := t.ptraceStep(); err != nil { return err } - t.setState(singleStepping); + t.setState(singleStepping) t.onStop(func() { ready <- nil }, - func(err os.Error) { ready <- err }); - return nil; + func(err os.Error) { ready <- err }) + return nil } func (t *thread) Step() os.Error { - t.logTrace("Step {"); - defer t.logTrace("}"); + t.logTrace("Step {") + defer t.logTrace("}") - ready := make(chan os.Error); + ready := make(chan os.Error) err := t.proc.do(func() os.Error { if !t.state.isStopped() { return &badState{t, "cannot single step", t.state} } - return t.stepAsync(ready); - }); + return t.stepAsync(ready) + }) if err != nil { return err } - err = <-ready; - return err; + err = <-ready + return err } // TODO(austin) We should probably get this via C's strsignal. @@ -884,11 +884,11 @@ func sigName(signal int) string { if signal < 0 || signal >= len(sigNames) { return "<invalid>" } - return sigNames[signal]; + return sigNames[signal] } func (t *thread) Stopped() (Cause, os.Error) { - var c Cause; + var c Cause err := t.proc.do(func() os.Error { switch t.state { case stopped: @@ -913,35 +913,35 @@ func (t *thread) Stopped() (Cause, os.Error) { default: return &badState{t, "cannot get stop cause", t.state} } - return nil; - }); + return nil + }) if err != nil { return nil, err } - return c, nil; + return c, nil } func (p *process) Threads() []Thread { - var res []Thread; + var res []Thread p.do(func() os.Error { - res = make([]Thread, len(p.threads)); - i := 0; + res = make([]Thread, len(p.threads)) + i := 0 for _, t := range p.threads { // Exclude zombie threads. - st := t.state; + st := t.state if st == exiting || st == exited || st == detached { continue } - res[i] = t; - i++; + res[i] = t + i++ } - res = res[0:i]; - return nil; - }); - return res; + res = res[0:i] + return nil + }) + return res } func (p *process) AddBreakpoint(pc Word) os.Error { @@ -952,8 +952,8 @@ func (p *process) AddBreakpoint(pc Word) os.Error { if _, ok := p.breakpoints[uintptr(pc)]; ok { return breakpointExistsError(pc) } - p.breakpoints[uintptr(pc)] = &breakpoint{pc: uintptr(pc)}; - return nil; + p.breakpoints[uintptr(pc)] = &breakpoint{pc: uintptr(pc)} + return nil }) } @@ -965,22 +965,22 @@ func (p *process) RemoveBreakpoint(pc Word) os.Error { if _, ok := p.breakpoints[uintptr(pc)]; !ok { return noBreakpointError(pc) } - p.breakpoints[uintptr(pc)] = nil, false; - return nil; + p.breakpoints[uintptr(pc)] = nil, false + return nil }) } func (p *process) Continue() os.Error { // Single step any threads that are stopped at breakpoints so // we can reinstall breakpoints. - var ready chan os.Error; - count := 0; + var ready chan os.Error + count := 0 err := p.do(func() os.Error { // We make the ready channel big enough to hold all // ready message so we don't jam up the monitor if we // stop listening (e.g., if there's an error). - ready = make(chan os.Error, len(p.threads)); + ready = make(chan os.Error, len(p.threads)) for _, t := range p.threads { if !t.state.isStopped() { @@ -992,34 +992,34 @@ func (p *process) Continue() os.Error { // it could have been stopped at a breakpoint // for some other reason, or the breakpoint // could have been added since it was stopped. - var regs syscall.PtraceRegs; - err := t.ptraceGetRegs(®s); + var regs syscall.PtraceRegs + err := t.ptraceGetRegs(®s) if err != nil { return err } if b, ok := p.breakpoints[uintptr(regs.PC())]; ok { - t.logTrace("stepping over breakpoint %v", b); + t.logTrace("stepping over breakpoint %v", b) if err := t.stepAsync(ready); err != nil { return err } - count++; + count++ } } - return nil; - }); + return nil + }) if err != nil { - p.stopMonitor(err); - return err; + p.stopMonitor(err) + return err } // Wait for single stepping threads for count > 0 { - err = <-ready; + err = <-ready if err != nil { - p.stopMonitor(err); - return err; + p.stopMonitor(err) + return err } - count--; + count-- } // Continue all threads @@ -1029,18 +1029,18 @@ func (p *process) Continue() os.Error { } for _, t := range p.threads { - var err os.Error; + var err os.Error switch { case !t.state.isStopped(): continue case t.state == stoppedSignal && t.signal != syscall.SIGSTOP && t.signal != syscall.SIGTRAP: - t.logTrace("continuing with signal %d", t.signal); - err = t.ptraceContWithSignal(t.signal); + t.logTrace("continuing with signal %d", t.signal) + err = t.ptraceContWithSignal(t.signal) default: - t.logTrace("continuing"); - err = t.ptraceCont(); + t.logTrace("continuing") + err = t.ptraceCont() } if err != nil { return err @@ -1051,59 +1051,59 @@ func (p *process) Continue() os.Error { t.setState(running) } } - return nil; - }); + return nil + }) if err != nil { // TODO(austin) Do we need to stop the monitor with // this error atomically with the do-routine above? - p.stopMonitor(err); - return err; + p.stopMonitor(err) + return err } - return nil; + return nil } func (p *process) WaitStop() os.Error { // We need a non-blocking ready channel for the case where all // threads are already stopped. - ready := make(chan os.Error, 1); + ready := make(chan os.Error, 1) err := p.do(func() os.Error { // Are all of the threads already stopped? if p.someRunningThread() == nil { - ready <- nil; - return nil; + ready <- nil + return nil } // Monitor state transitions - h := &transitionHandler{}; + h := &transitionHandler{} h.handle = func(st *thread, old, new threadState) { if !new.isRunning() { if p.someRunningThread() == nil { - ready <- nil; - return; + ready <- nil + return } } - p.transitionHandlers.Push(h); - }; - h.onErr = func(err os.Error) { ready <- err }; - p.transitionHandlers.Push(h); - return nil; - }); + p.transitionHandlers.Push(h) + } + h.onErr = func(err os.Error) { ready <- err } + p.transitionHandlers.Push(h) + return nil + }) if err != nil { return err } - return <-ready; + return <-ready } func (p *process) Stop() os.Error { - err := p.do(func() os.Error { return p.stopAsync() }); + err := p.do(func() os.Error { return p.stopAsync() }) if err != nil { return err } - return p.WaitStop(); + return p.WaitStop() } func (p *process) Detach() os.Error { @@ -1123,13 +1123,13 @@ func (p *process) Detach() os.Error { return err } } - t.setState(detached); - p.threads[pid] = nil, false; + t.setState(detached) + p.threads[pid] = nil, false } - return nil; - }); + return nil + }) // TODO(austin) Wait for monitor thread to exit? - return err; + return err } // newThread creates a new thread object and waits for its initial @@ -1138,11 +1138,11 @@ func (p *process) Detach() os.Error { // // Must be run from the monitor thread. func (p *process) newThread(tid int, signal int, cloned bool) (*thread, os.Error) { - t := &thread{tid: tid, proc: p, state: stopped}; + t := &thread{tid: tid, proc: p, state: stopped} // Get the signal from the thread // TODO(austin) Thread might already be stopped if we're attaching. - w, err := os.Wait(tid, syscall.WALL); + w, err := os.Wait(tid, syscall.WALL) if err != nil { return nil, err } @@ -1151,59 +1151,59 @@ func (p *process) newThread(tid int, signal int, cloned bool) (*thread, os.Error } if !cloned { - err = t.ptraceSetOptions(syscall.PTRACE_O_TRACECLONE | syscall.PTRACE_O_TRACEEXIT); + err = t.ptraceSetOptions(syscall.PTRACE_O_TRACECLONE | syscall.PTRACE_O_TRACEEXIT) if err != nil { return nil, err } } - p.threads[tid] = t; + p.threads[tid] = t - return t, nil; + return t, nil } // attachThread attaches a running thread to the process. // // Must NOT be run from the monitor thread. func (p *process) attachThread(tid int) (*thread, os.Error) { - p.logTrace("attaching to thread %d", tid); - var thr *thread; + p.logTrace("attaching to thread %d", tid) + var thr *thread err := p.do(func() os.Error { - errno := syscall.PtraceAttach(tid); + errno := syscall.PtraceAttach(tid) if errno != 0 { return os.NewSyscallError("ptrace(ATTACH)", errno) } - var err os.Error; - thr, err = p.newThread(tid, syscall.SIGSTOP, false); - return err; - }); - return thr, err; + var err os.Error + thr, err = p.newThread(tid, syscall.SIGSTOP, false) + return err + }) + return thr, err } // attachAllThreads attaches to all threads in a process. func (p *process) attachAllThreads() os.Error { - taskPath := "/proc/" + strconv.Itoa(p.pid) + "/task"; - taskDir, err := os.Open(taskPath, os.O_RDONLY, 0); + taskPath := "/proc/" + strconv.Itoa(p.pid) + "/task" + taskDir, err := os.Open(taskPath, os.O_RDONLY, 0) if err != nil { return err } - defer taskDir.Close(); + defer taskDir.Close() // We stop threads as we attach to them; however, because new // threads can appear while we're looping over all of them, we // have to repeatly scan until we know we're attached to all // of them. for again := true; again; { - again = false; + again = false - tids, err := taskDir.Readdirnames(-1); + tids, err := taskDir.Readdirnames(-1) if err != nil { return err } for _, tidStr := range tids { - tid, err := strconv.Atoi(tidStr); + tid, err := strconv.Atoi(tidStr) if err != nil { return err } @@ -1211,39 +1211,39 @@ func (p *process) attachAllThreads() os.Error { continue } - _, err = p.attachThread(tid); + _, err = p.attachThread(tid) if err != nil { // There could have been a race, or // this process could be a zobmie. - statFile, err2 := ioutil.ReadFile(taskPath + "/" + tidStr + "/stat"); + statFile, err2 := ioutil.ReadFile(taskPath + "/" + tidStr + "/stat") if err2 != nil { switch err2 := err2.(type) { case *os.PathError: if err2.Error == os.ENOENT { // Raced with thread exit - p.logTrace("raced with thread %d exit", tid); - continue; + p.logTrace("raced with thread %d exit", tid) + continue } } // Return the original error - return err; + return err } - statParts := strings.Split(string(statFile), " ", 4); + statParts := strings.Split(string(statFile), " ", 4) if len(statParts) > 2 && statParts[2] == "Z" { // tid is a zombie - p.logTrace("thread %d is a zombie", tid); - continue; + p.logTrace("thread %d is a zombie", tid) + continue } // Return the original error - return err; + return err } - again = true; + again = true } } - return nil; + return nil } // newProcess creates a new process object and starts its monitor thread. @@ -1257,37 +1257,37 @@ func newProcess(pid int) *process { debugReqs: make(chan *debugReq), stopReq: make(chan os.Error), transitionHandlers: new(vector.Vector), - }; + } - go p.monitor(); + go p.monitor() - return p; + return p } // Attach attaches to process pid and stops all of its threads. func Attach(pid int) (Process, os.Error) { - p := newProcess(pid); + p := newProcess(pid) // Attach to all threads - err := p.attachAllThreads(); + err := p.attachAllThreads() if err != nil { - p.Detach(); + p.Detach() // TODO(austin) Detach stopped the monitor already //p.stopMonitor(err); - return nil, err; + return nil, err } - return p, nil; + return p, nil } // ForkExec forks the current process and execs argv0, stopping the // new process after the exec syscall. See os.ForkExec for additional // details. func ForkExec(argv0 string, argv []string, envv []string, dir string, fd []*os.File) (Process, os.Error) { - p := newProcess(-1); + p := newProcess(-1) // Create array of integer (system) fds. - intfd := make([]int, len(fd)); + intfd := make([]int, len(fd)) for i, f := range fd { if f == nil { intfd[i] = -1 @@ -1298,20 +1298,20 @@ func ForkExec(argv0 string, argv []string, envv []string, dir string, fd []*os.F // Fork from the monitor thread so we get the right tracer pid. err := p.do(func() os.Error { - pid, errno := syscall.PtraceForkExec(argv0, argv, envv, dir, intfd); + pid, errno := syscall.PtraceForkExec(argv0, argv, envv, dir, intfd) if errno != 0 { return &os.PathError{"fork/exec", argv0, os.Errno(errno)} } - p.pid = pid; + p.pid = pid // The process will raise SIGTRAP when it reaches execve. - _, err := p.newThread(pid, syscall.SIGTRAP, false); - return err; - }); + _, err := p.newThread(pid, syscall.SIGTRAP, false) + return err + }) if err != nil { - p.stopMonitor(err); - return nil, err; + p.stopMonitor(err) + return nil, err } - return p, nil; + return p, nil } |