// 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 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";
	"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.
//
// To send a message to the monitor thread, first receive from the
// ready channel.  If the ready channel returns true, the monitor is
// still running and will accept a message.  If the ready channel
// 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;
}

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

type ProcessExited struct{}

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);
	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.PC());
		}
	}
	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 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.
		}
		if !<-t.proc.ready {
			// The monitor exited
			break;
		}
		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.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
		// 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.PC());

	regs.SetPC(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.
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 err == nil {
		p.ready <- true;
		select {
		case event := <-p.debugEvents:
			err = event.process();

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

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

		if len(p.threads) == 0 {
			if err == nil && hadThreads {
				p.logTrace("no more threads; monitor exiting");
				err = ProcessExited{};
			}
		} else {
			hadThreads = true;
		}
	}

	// Abort waiting handlers
	// TODO(austin) How do I stop the wait threads?
	for _, h := range p.transitionHandlers.Data() {
		h := h.(*transitionHandler);
		h.onErr(err);
	}

	// Indicate that the monitor cannot receive any more messages
	p.err = err;
	close(p.ready);
}

// 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 {
	if !<-p.ready {
		return p.err;
	}
	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) {
	if err == nil {
		panic("cannot stop the monitor with no error");
	}
	if <-p.ready {
		p.stopReq <- err;
	}
}

/*
 * 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.PC())]; 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;
			}

			_, 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),
		ready: make(chan bool, 1),
		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.
		_, err := p.newThread(pid, syscall.SIGTRAP, false);
		return err;
	});
	if err != nil {
		p.stopMonitor(err);
		return nil, err;
	}

	return p, nil;
}
