Refactor: Modify command registraion on bootup

Benefits of this CL:

* Commands no longer rely on closured proc struct
* No two-step process for basic command initializaion
This commit is contained in:
Derek Parker
2014-06-25 14:58:45 -05:00
parent feec416b1a
commit 7fe2037ff1
3 changed files with 110 additions and 116 deletions

View File

@ -3,11 +3,17 @@
package command
import (
"debug/gosym"
"fmt"
"os"
"path/filepath"
"strconv"
"strings"
"github.com/derekparker/dbg/proctl"
)
type cmdfunc func(args ...string) error
type cmdfunc func(proc *proctl.DebuggedProcess, args ...string) error
type Commands struct {
cmds map[string]cmdfunc
@ -16,8 +22,12 @@ type Commands struct {
// Returns a Commands struct with default commands defined.
func DebugCommands() *Commands {
cmds := map[string]cmdfunc{
"exit": exitFunc,
"": nullCommand,
"exit": exitFunc,
"continue": cont,
"break": br,
"step": step,
"clear": clear,
"": nullCommand,
}
return &Commands{cmds}
@ -45,20 +55,101 @@ func (c *Commands) Find(cmdstr string) cmdfunc {
}
func CommandFunc(fn func() error) cmdfunc {
return func(args ...string) error {
return func(p *proctl.DebuggedProcess, args ...string) error {
return fn()
}
}
func noCmdAvailable(args ...string) error {
func noCmdAvailable(p *proctl.DebuggedProcess, ars ...string) error {
return fmt.Errorf("command not available")
}
func exitFunc(args ...string) error {
func exitFunc(p *proctl.DebuggedProcess, ars ...string) error {
os.Exit(0)
return nil
}
func nullCommand(args ...string) error {
func nullCommand(p *proctl.DebuggedProcess, ars ...string) error {
return nil
}
func cont(p *proctl.DebuggedProcess, ars ...string) error {
return p.Continue()
}
func step(p *proctl.DebuggedProcess, args ...string) error {
err := p.Step()
if err != nil {
return err
}
regs, err := p.Registers()
if err != nil {
return err
}
f, l, _ := p.GoSymTable.PCToLine(regs.PC())
fmt.Printf("Stopped at: %s:%d\n", f, l)
return nil
}
func clear(p *proctl.DebuggedProcess, args ...string) error {
fname := args[0]
fn := p.GoSymTable.LookupFunc(fname)
if fn == nil {
return fmt.Errorf("No function named %s", fname)
}
bp, err := p.Clear(fn.Entry)
if err != nil {
return err
}
fmt.Printf("Breakpoint cleared at %#v for %s %s:%d\n", bp.Addr, bp.FunctionName, bp.File, bp.Line)
return nil
}
func br(p *proctl.DebuggedProcess, args ...string) error {
var (
fn *gosym.Func
pc uint64
fname = args[0]
)
if strings.ContainsRune(fname, ':') {
fl := strings.Split(fname, ":")
f, err := filepath.Abs(fl[0])
if err != nil {
return err
}
l, err := strconv.Atoi(fl[1])
if err != nil {
return err
}
pc, fn, err = p.GoSymTable.LineToPC(f, l)
if err != nil {
return err
}
} else {
fn = p.GoSymTable.LookupFunc(fname)
pc = fn.Entry
}
if fn == nil {
return fmt.Errorf("No function named %s", fname)
}
bp, err := p.Break(uintptr(pc))
if err != nil {
return err
}
fmt.Printf("Breakpoint set at %#v for %s %s:%d\n", bp.Addr, bp.FunctionName, bp.File, bp.Line)
return nil
}