// 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/ioutil"
	"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 ...interface{}) {
	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 ...interface{}) {
	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 ...interface{}) {
	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(fmt.Sprint("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(newState threadState) {
	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
		go t.wait()
	}

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

	t.proc.transitionHandlers = new(vector.Vector)
	for _, h := range handlers.Data() {
		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)
}

// 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 := 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
						}
					}
					// 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: new(vector.Vector),
	}

	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
}
