// Copyright 2009 The Go Authors.  All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package ptrace

import (
	"container/vector";
	"fmt";
	"io";
	"os";
	"runtime";
	"strconv";
	"strings";
	"sync";
	"syscall";
)

// This is an implementation of the process tracing interface using
// Linux's ptrace(2) interface.  The implementation is multi-threaded.
// Each attached process has an associated monitor thread, and each
// running attached thread has an associated "wait" thread.  The wait
// thread calls wait4 on the thread's TID and reports any wait events
// or errors via "debug events".  The monitor thread consumes these
// wait events and updates the internally maintained state of each
// thread.  All ptrace calls must run in the monitor thread, so the
// monitor executes closures received on the debugReq channel.
//
// As ptrace's documentation is somewhat light, this is heavily based
// on information gleaned from the implementation of ptrace found at
//   http://lxr.linux.no/linux+v2.6.30/kernel/ptrace.c
//   http://lxr.linux.no/linux+v2.6.30/arch/x86/kernel/ptrace.c#L854
// as well as experimentation and examination of gdb's behavior.

const (
	trace = false;
	traceIP = false;
	traceMem = false;
)

/*
 * Thread state
 */

// Each thread can be in one of the following set of states.
// Each state satisfies
//  isRunning() || isStopped() || isZombie() || isTerminal().
//
// Running threads can be sent signals and must be waited on, but they
// cannot be inspected using ptrace.
//
// Stopped threads can be inspected and continued, but cannot be
// meaningfully waited on.  They can be sent signals, but the signals
// will be queued until they are running again.
//
// Zombie threads cannot be inspected, continued, or sent signals (and
// therefore they cannot be stopped), but they must be waited on.
//
// Terminal threads no longer exist in the OS and thus you can't do
// anything with them.
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";
)

func (ts threadState) isRunning() bool {
	return ts == running || ts == singleStepping || ts == stopping;
}

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) isTerminal() bool {
	return ts == exited || ts == detached;
}

func (ts threadState) String() string {
	return string(ts);
}

/*
 * Basic types
 */

// A breakpoint stores information about a single breakpoint,
// including its program counter, the overwritten text if the
// breakpoint is installed.
type breakpoint struct {
	pc uintptr;
	olddata []byte;
}

func (bp *breakpoint) String() string {
	if bp == nil {
		return "<nil>";
	}
	return fmt.Sprintf("%#x", bp.pc);
}

// bpinst386 is the breakpoint instruction used on 386 and amd64.
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;
}

// A debugReq is a request to execute a closure in the monitor thread.
type debugReq struct {
	f func () os.Error;
	res chan os.Error;
}

// A transitionHandler specifies a function to be called when a thread
// changes state and a function to be called when an error occurs in
// the monitor.  Both run in the monitor thread.  Before the monitor
// 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);
}

// A process is a Linux process, which consists of a set of threads.
// Each running process has one monitor thread, which processes
// messages from the debugEvents, debugReqs, and stopReq channels and
// calls transition handlers.
type process struct {
	pid int;
	threads map[int] *thread;
	breakpoints map[uintptr] *breakpoint;
	debugEvents chan *debugEvent;
	debugReqs chan *debugReq;
	stopReq chan os.Error;
	transitionHandlers *vector.Vector;
}

// 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;
	// Whether to ignore the next SIGSTOP received by wait.
	ignoreNextSigstop bool;

	// Thread state.  Only modified via setState.
	state threadState;
	// If state == StoppedBreakpoint
	breakpoint *breakpoint;
	// If state == StoppedSignal or state == Exited
	signal int;
	// If state == StoppedThreadCreate
	newThread *thread;
	// If state == Exited
	exitStatus int;
}

/*
 * Errors
 */

type badState struct {
	thread *thread;
	message string;
	state threadState;
}

func (e *badState) String() string {
	return fmt.Sprintf("Thread %d %s from state %v", e.thread.tid, e.message, e.state);
}

type breakpointExistsError Word

func (e breakpointExistsError) String() string {
	return fmt.Sprintf("breakpoint already exists at PC %#x", e);
}

type noBreakpointError Word

func (e noBreakpointError) String() string {
	return fmt.Sprintf("no breakpoint at PC %#x", e);
}

type newThreadError struct {
	*os.Waitmsg;
	wantPid int;
	wantSig int;
}

func (e *newThreadError) String() string {
	return fmt.Sprintf("newThread wait wanted pid %v and signal %v, got %v and %v", e.Pid, e.StopSignal(), e.wantPid, e.wantSig);
}

/*
 * Ptrace wrappers
 */

func (t *thread) ptracePeekText(addr uintptr, out []byte) (int, os.Error) {
	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);
}

func (t *thread) ptracePokeText(addr uintptr, out []byte) (int, os.Error) {
	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);
}

func (t *thread) ptraceGetRegs(regs *syscall.PtraceRegs) os.Error {
	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);
}

func (t *thread) ptraceSetOptions(options int) os.Error {
	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);
}

func (t *thread) ptraceCont() os.Error {
	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);
}

func (t *thread) ptraceStep() os.Error {
	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);
}

/*
 * Logging utilties
 */

var logLock sync.Mutex

func (t *thread) logTrace(format string, args ...) {
	if !trace {
		return;
	}
	logLock.Lock();
	defer logLock.Unlock();
	fmt.Fprintf(os.Stderr, "Thread %d", t.tid);
	if traceIP {
		var regs syscall.PtraceRegs;
		err := t.ptraceGetRegs(&regs);
		if err == nil {
			fmt.Fprintf(os.Stderr, "@%x", regs.Rip);
		}
	}
	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");
}

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");
}

/*
 * State utilities
 */

// someStoppedThread returns a stopped thread from the process.
// Returns nil if no threads are stopped.
//
// Must be called from the monitor thread.
func (p *process) someStoppedThread() *thread {
	for _, t := range p.threads {
		if t.state.isStopped() {
			return t;
		}
	}
	return nil;
}

// someRunningThread returns a running thread from the process.
// Returns nil if no threads are running.
//
// Must be called from the monitor thread.
func (p *process) someRunningThread() *thread {
	for _, t := range p.threads {
		if t.state.isRunning() {
			return t;
		}
	}
	return nil;
}

/*
 * Breakpoint utilities
 */

// installBreakpoints adds breakpoints to the attached process.
//
// Must be called from the monitor thread.
func (p *process) installBreakpoints() os.Error {
	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);
		if err != nil {
			b.olddata = nil;
			return err;
		}

		_, err = main.ptracePokeText(uintptr(b.pc), bpinst386);
		if err != nil {
			b.olddata = nil;
			return err;
		}
		n++;
	}
	if n > 0 {
		p.logTrace("installed %d/%d breakpoints", n, len(p.breakpoints));
	}

	return nil;
}

// uninstallBreakpoints removes the installed breakpoints from p.
//
// Must be called from the monitor thread.
func (p *process) uninstallBreakpoints() os.Error {
	if len(p.threads) == 0 {
		return nil;
	}
	n := 0;
	main := p.someStoppedThread();
	for _, b := range p.breakpoints {
		if b.olddata == nil {
			continue;
		}

		_, err := main.ptracePokeText(uintptr(b.pc), b.olddata);
		if err != nil {
			return err;
		}
		b.olddata = nil;
		n++;
	}
	if n > 0 {
		p.logTrace("uninstalled %d/%d breakpoints", n, len(p.breakpoints));
	}

	return nil;
}

/*
 * Debug event handling
 */

// wait waits for a wait event from this thread and sends it on the
// debug events channel for this thread's process.  This should be
// started in its own goroutine when the attached thread enters a
// running state.  The goroutine will exit as soon as it sends a debug
// event.
func (t *thread) wait() {
	for {
		var err os.Error;
		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();
			if err == nil {
				continue;
			}
			// If we failed to continue, just let
			// the stop go through so we can
			// update the thread's state.
		}
		t.proc.debugEvents <- &ev;
		break;
	}
}

// setState sets this thread's state, starts a wait thread if
// necessary, and invokes state transition handlers.
//
// Must be called from the monitor thread.
func (t *thread) setState(new threadState) {
	old := t.state;
	t.state = new;
	t.logTrace("state %v -> %v", old, new);

	if !old.isRunning() && (new.isRunning() || new.isZombie()) {
		// Start waiting on this thread
		go t.wait();
	}

	// Invoke state change handlers
	handlers := t.proc.transitionHandlers;
	if handlers.Len() == 0 {
		return;
	}

	t.proc.transitionHandlers = vector.New(0);
	for _, h := range handlers.Data() {
		h := h.(*transitionHandler);
		h.handle(t, old, new);
	}
}

// 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);
}

// stopAsync sends SIGSTOP to all threads in state 'running'.
//
// Must be called from the monitor thread.
func (p *process) stopAsync() os.Error {
	for _, t := range p.threads {
		if t.state == running {
			err := t.sendSigstop();
			if err != nil {
				return err;
			}
			t.setState(stopping);
		}
	}
	return nil;
}

// doTrap handles SIGTRAP debug events with a cause of 0.  These can
// be caused either by an installed breakpoint, a breakpoint in the
// program text, or by single stepping.
//
// TODO(austin) I think we also get this on an execve syscall.
func (ev *debugEvent) doTrap() (threadState, os.Error) {
	t := ev.t;

	if t.state == singleStepping {
		return stopped, nil;
	}

	// 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(&regs);
	if err != nil {
		return stopped, err;
	}

	b, ok := t.proc.breakpoints[uintptr(regs.Rip)-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
		// re-execute the breakpoint instruction.  Expose the
		// fact that we stopped with a SIGTRAP.
		return stoppedSignal, nil;
	}

	t.breakpoint = b;
	t.logTrace("at breakpoint %v, backing up PC from %#x", b, regs.Rip);

	regs.Rip = uint64(b.pc);
	err = t.ptraceSetRegs(&regs);
	if err != nil {
		return stopped, err;
	}
	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;

	// Get the TID of the new thread
	tid, err := t.ptraceGetEventMsg();
	if err != nil {
		return stopped, err;
	}

	nt, err := t.proc.newThread(int(tid), syscall.SIGSTOP, true);
	if err != nil {
		return stopped, err;
	}

	// Remember the thread
	t.newThread = nt;

	return stoppedThreadCreate, nil;
}

// doPtraceExit handles SIGTRAP debug events with a PTRACE_EVENT_EXIT
// cause.  It sets up the thread's state, but does not remove it from
// the process.  A later WIFEXITED debug event will remove it from the
// process.
func (ev *debugEvent) doPtraceExit() (threadState, os.Error) {
	t := ev.t;

	// Get exit status
	exitStatus, err := t.ptraceGetEventMsg();
	if err != nil {
		return stopped, err;
	}
	ws := syscall.WaitStatus(exitStatus);
	t.logTrace("exited with %v", ws);
	switch {
	case ws.Exited():
		t.exitStatus = ws.ExitStatus();
	case ws.Signaled():
		t.signal = ws.Signal();
	}

	// We still need to continue this thread and wait on this
	// thread's WIFEXITED event.  We'll delete it then.
	return stoppedExiting, nil;
}

// process handles a debug event.  It modifies any thread or process
// state as necessary, uninstalls breakpoints if necessary, and stops
// any running threads.
func (ev *debugEvent) process() os.Error {
	if ev.err != nil {
		return ev.err;
	}

	t := ev.t;
	t.exitStatus = -1;
	t.signal = -1;

	// Decode wait status.
	var state threadState;
	switch {
	case ev.Stopped():
		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;
			switch cause := ev.TrapCause(); cause {
			case 0:
				// Breakpoint or single stepping
				state, err = ev.doTrap();

			case syscall.PTRACE_EVENT_CLONE:
				state, err = ev.doPtraceClone();

			case syscall.PTRACE_EVENT_EXIT:
				state, err = ev.doPtraceExit();

			default:
				t.warn("Unknown trap cause %d", cause);
			}

			if err != nil {
				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);
		// We should have gotten the exit status in
		// PTRACE_EVENT_EXIT, but just in case.
		t.exitStatus = ev.ExitStatus();

	case ev.Signaled():
		state = exited;
		t.proc.threads[t.tid] = nil, false;
		t.logTrace("signaled %v", ev);
		// Again, this should be redundant.
		t.signal = ev.Signal();

	default:
		panic(fmt.Sprintf("Unexpected wait status %v", ev.Waitmsg));
	}

	// If we sent a SIGSTOP to the thread (indicated by state
	// Stopping), we might have raced with a different type of
	// stop.  If we didn't get the stop we expected, then the
	// SIGSTOP we sent is now queued up, so we should ignore the
	// next one we get.
	if t.state == stopping && ev.StopSignal() != syscall.SIGSTOP {
		t.ignoreNextSigstop = true;
	}

	// TODO(austin) If we're in state stopping and get a SIGSTOP,
	// set state stopped instead of stoppedSignal.

	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();
}

// onStop adds a handler for state transitions from running to
// non-running states.  The handler will be called from the monitor
// thread.
//
// Must be called from the monitor thread.
func (t *thread) onStop(handle func (), onErr func (os.Error)) {
	// TODO(austin) This is rather inefficient for things like
	// 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.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);
}

/*
 * Event monitor
 */

// monitor handles debug events and debug requests for p, exiting when
// there are no threads left in p.
//
// TODO(austin) When an unrecoverable error occurs, abort the monitor
// and record this error so all future calls to do will return it
// immediately.
func (p *process) monitor() {
	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();

	hadThreads := false;
	for {
		select {
		case event := <-p.debugEvents:
			err = event.process();
			if err != nil {
				break;
			}

		case req := <-p.debugReqs:
			req.res <- req.f();

		case err = <-p.stopReq:
			break;
		}

		if len(p.threads) == 0 {
			if hadThreads {
				p.logTrace("no more threads; monitor exiting");
				// TODO(austin) Use a real error do
				// future operations will fail
				err = nil;
				break;
			}
		} else {
			hadThreads = true;
		}
	}

	// Abort waiting handlers
	for _, h := range p.transitionHandlers.Data() {
		h := h.(*transitionHandler);
		h.onErr(err);
	}

	// TODO(austin) How do I stop the wait threads?
	if err != nil {
		panic(err.String());
	}
}

// do executes f in the monitor thread (and, thus, atomically with
// respect to thread state changes).  f must not block.
//
// Must NOT be called from the monitor thread.
func (p *process) do(f func () os.Error) os.Error {
	// TODO(austin) If monitor is stopped, return error.
	req := &debugReq{f, make(chan os.Error)};
	p.debugReqs <- req;
	return <-req.res;
}

// stopMonitor stops the monitor with the given error.  If the monitor
// is already stopped, does nothing.
func (p *process) stopMonitor(err os.Error) {
	doNotBlock := p.stopReq <- err;
	// TODO(austin) Wait until monitor has exited?
}

/*
 * Public thread interface
 */

func (t *thread) Regs() (Regs, os.Error) {
	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(&regs);
	});
	if err != nil {
		return nil, err;
	}

	setter := func (r *syscall.PtraceRegs) os.Error {
		return t.proc.do(func () os.Error {
			if !t.state.isStopped() {
				return &badState{t, "cannot get registers", t.state};
			}
			return t.ptraceSetRegs(r);
		});
	};
	return newRegs(&regs, setter), nil;
}

func (t *thread) Peek(addr Word, out []byte) (int, os.Error) {
	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;
	});

	return c, err;
}

func (t *thread) Poke(addr Word, out []byte) (int, os.Error) {
	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;
	});

	return c, err;
}

// stepAsync starts this thread single stepping.  When the single step
// is complete, it will send nil on the given channel.  If an error
// occurs while setting up the single step, it returns that error.  If
// an error occurs while waiting for the single step to complete, it
// sends that error on the channel.
func (t *thread) stepAsync(ready chan os.Error) os.Error {
	if err := t.ptraceStep(); err != nil {
		return err;
	}
	t.setState(singleStepping);
	t.onStop(func () {
			ready <- nil;
		},
		func (err os.Error) {
			ready <- err;
		});
	return nil;
}

func (t *thread) Step() os.Error {
	t.logTrace("Step {");
	defer t.logTrace("}");

	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);
	});
	if err != nil {
		return err;
	}

	err = <-ready;
	return err;
}

// TODO(austin) We should probably get this via C's strsignal.
var sigNames = [...]string {
	"SIGEXIT", "SIGHUP", "SIGINT", "SIGQUIT", "SIGILL",
	"SIGTRAP", "SIGABRT", "SIGBUS", "SIGFPE", "SIGKILL",
	"SIGUSR1", "SIGSEGV", "SIGUSR2", "SIGPIPE", "SIGALRM",
	"SIGTERM", "SIGSTKFLT", "SIGCHLD", "SIGCONT", "SIGSTOP",
	"SIGTSTP", "SIGTTIN", "SIGTTOU", "SIGURG", "SIGXCPU",
	"SIGXFSZ", "SIGVTALRM", "SIGPROF", "SIGWINCH", "SIGPOLL",
	"SIGPWR", "SIGSYS"
}

// sigName returns the symbolic name for the given signal number.  If
// the signal number is invalid, returns "<invalid>".
func sigName(signal int) string {
	if signal < 0 || signal >= len(sigNames) {
		return "<invalid>";
	}
	return sigNames[signal];
}

func (t *thread) Stopped() (Cause, os.Error) {
	var c Cause;
	err := t.proc.do(func() os.Error {
		switch t.state {
		case stopped:
			c = Stopped{};

		case stoppedBreakpoint:
			c = Breakpoint(t.breakpoint.pc);

		case stoppedSignal:
			c = Signal(sigName(t.signal));

		case stoppedThreadCreate:
			c = &ThreadCreate{t.newThread};

		case stoppedExiting, exiting, exited:
			if t.signal == -1 {
				c = &ThreadExit{t.exitStatus, ""};
			} else {
				c = &ThreadExit{t.exitStatus, sigName(t.signal)};
			}

		default:
			return &badState{t, "cannot get stop cause", t.state};
		}
		return nil;
	});
	if err != nil {
		return nil, err;
	}

	return c, nil;
}

func (p *process) Threads() []Thread {
	var res []Thread;

	p.do(func () os.Error {
		res = make([]Thread, len(p.threads));
		i := 0;
		for _, t := range p.threads {
			// Exclude zombie threads.
			st := t.state;
			if st == exiting || st == exited || st == detached {
				continue;
			}

			res[i] = t;
			i++;
		}
		res = res[0:i];
		return nil;
	});
	return res;
}

func (p *process) AddBreakpoint(pc Word) os.Error {
	return p.do(func () os.Error {
		if t := p.someRunningThread(); t != nil {
			return &badState{t, "cannot add breakpoint", t.state};
		}
		if _, ok := p.breakpoints[uintptr(pc)]; ok {
			return breakpointExistsError(pc);
		}
		p.breakpoints[uintptr(pc)] = &breakpoint{pc: uintptr(pc)};
		return nil;
	});
}

func (p *process) RemoveBreakpoint(pc Word) os.Error {
	return p.do(func () os.Error {
		if t := p.someRunningThread(); t != nil {
			return &badState{t, "cannot remove breakpoint", t.state};
		}
		if _, ok := p.breakpoints[uintptr(pc)]; !ok {
			return noBreakpointError(pc);
		}
		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;

	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));

		for _, t := range p.threads {
			if !t.state.isStopped() {
				continue;
			}

			// We use the breakpoint map directly here
			// instead of checking the stop cause because
			// 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(&regs);
			if err != nil {
				return err;
			}
			if b, ok := p.breakpoints[uintptr(regs.Rip)]; ok {
				t.logTrace("stepping over breakpoint %v", b);
				if err := t.stepAsync(ready); err != nil {
					return err;
				}
				count++;
			}
		}
		return nil;
	});
	if err != nil {
		p.stopMonitor(err);
		return err;
	}

	// Wait for single stepping threads
	for count > 0 {
		err = <-ready;
		if err != nil {
			p.stopMonitor(err);
			return err;
		}
		count--;
	}

	// Continue all threads
	err = p.do(func () os.Error {
		if err := p.installBreakpoints(); err != nil {
			return err;
		}

		for _, t := range p.threads {
			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);

			default:
				t.logTrace("continuing");
				err = t.ptraceCont();
			}
			if err != nil {
				return err;
			}
			if t.state == stoppedExiting {
				t.setState(exiting);
			} else {
				t.setState(running);
			}
		}
		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;
	}

	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);

	err := p.do(func () os.Error {
		// Are all of the threads already stopped?
		if p.someRunningThread() == nil {
			ready <- nil;
			return nil;
		}

		// Monitor state transitions
		h := &transitionHandler{};
		h.handle = func (st *thread, old, new threadState) {
			if !new.isRunning() {
				if p.someRunningThread() == nil {
					ready <- nil;
					return;
				}
			}
			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;
}

func (p *process) Stop() os.Error {
	err := p.do(func () os.Error {
		return p.stopAsync();
	});
	if err != nil {
		return err;
	}

	return p.WaitStop();
}

func (p *process) Detach() os.Error {
	if err := p.Stop(); err != nil {
		return err;
	}

	err := p.do(func () os.Error {
		if err := p.uninstallBreakpoints(); err != nil {
			return err;
		}

		for pid, t := range p.threads {
			if t.state.isStopped() {
				// We can't detach from zombies.
				if err := t.ptraceDetach(); err != nil {
					return err;
				}
			}
			t.setState(detached);
			p.threads[pid] = nil, false;
		}
		return nil;
	});
	// TODO(austin) Wait for monitor thread to exit?
	return err;
}

// newThread creates a new thread object and waits for its initial
// signal.  If cloned is true, this thread was cloned from a thread we
// are already attached to.
//
// 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};

	// Get the signal from the thread
	// TODO(austin) Thread might already be stopped if we're attaching.
	w, err := os.Wait(tid, syscall.WALL);
	if err != nil {
		return nil, err;
	}
	if w.Pid != tid || w.StopSignal() != signal {
		return nil, &newThreadError{w, tid, signal};
	}

	if !cloned {
		err = t.ptraceSetOptions(syscall.PTRACE_O_TRACECLONE | syscall.PTRACE_O_TRACEEXIT);
		if err != nil {
			return nil, err;
		}
	}

	p.threads[tid] = t;

	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;
	err := p.do(func () os.Error {
		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;
}

// 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);
	if err != nil {
		return err;
	}
	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;

		tids, err := taskDir.Readdirnames(-1);
		if err != nil {
			return err;
		}

		for _, tidStr := range tids {
			tid, err := strconv.Atoi(tidStr);
			if err != nil {
				return err;
			}
			if _, ok := p.threads[tid]; ok {
				continue;
			}

			t, err := p.attachThread(tid);
			if err != nil {
				// There could have been a race, or
				// this process could be a zobmie.
				statFile, err2 := io.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;
						}
					}
					// Return the original error
					return err;
				}

				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;
				}

				// Return the original error
				return err;
			}
			again = true;
		}
	}

	return nil;
}

// newProcess creates a new process object and starts its monitor thread.
func newProcess(pid int) *process {
	p := &process{
		pid: pid,
		threads: make(map[int] *thread),
		breakpoints: make(map[uintptr] *breakpoint),
		debugEvents: make(chan *debugEvent),
		debugReqs: make(chan *debugReq),
		stopReq: make(chan os.Error),
		transitionHandlers: vector.New(0)
	};

	go p.monitor();

	return p;
}

// Attach attaches to process pid and stops all of its threads.
func Attach(pid int) (Process, os.Error) {
	p := newProcess(pid);

	// Attach to all threads
	err := p.attachAllThreads();
	if err != nil {
		p.Detach();
		// TODO(austin) Detach stopped the monitor already
		//p.stopMonitor(err);
		return nil, err;
	}

	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);

	// Create array of integer (system) fds.
	intfd := make([]int, len(fd));
	for i, f := range fd {
		if f == nil {
			intfd[i] = -1;
		} else {
			intfd[i] = f.Fd();
		}
	}

	// 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);
		if errno != 0 {
			return &os.PathError{"fork/exec", argv0, os.Errno(errno)};
		}
		p.pid = pid;

		// The process will raise SIGTRAP when it reaches execve.
		t, err := p.newThread(pid, syscall.SIGTRAP, false);
		return err;
	});
	if err != nil {
		p.stopMonitor(err);
		return nil, err;
	}

	return p, nil;
}
