Beispiel #1
0
// AstCommand implements the debugger command: ast
//
// ast
//
// Prints AST for current function.
func AstCommand(args []string) {
	var syntax ast.Node
	var err error
	fr := gub.CurFrame()
	fn := fr.Fn()
	if len(args) > 1 {
		name := args[1]
		fn, err = gub.FuncLookup(name)
		if err != nil {
			gub.Errmsg(err.Error())
			return
		} else if fn == nil {
			gub.Errmsg("function '%s' not found", name)
			return
		} else {
			syntax = fn.Syntax()
		}
	} else {
		syntax = fn.Syntax()
		switch s := (*gub.Instr).(type) {
		case *ssa2.Trace:
			syntax = s.Syntax()
		}
	}
	if syntax != nil {
		ast.Print(fn.Prog.Fset, syntax)
		fmt.Println("")
	} else {
		gub.Msg("Sorry, we don't have an AST for this")
	}
}
Beispiel #2
0
func InfoScopeSubcmd(args []string) {
	fr := gub.CurFrame()
	scope := fr.Scope()
	if scope == nil {
		gub.Errmsg("No scope recorded here")
		return
	}
	count := 0
	if len(args) == 3 {
		var err error
		count, err = gub.GetInt(args[2],
			"count", 0, gub.MAXSTACKSHOW)
		if err != nil {
			return
		}
	}

	typescope := scope.Scope
	for i := 0; i < count; i++ {
		typescope = typescope.Parent()
		if typescope == nil {
			gub.Errmsg("There are only %d nested scopes", i)
			return
		}
		scope = fr.Fn().Pkg.TypeScope2Scope[typescope]
		if scope == nil {
			gub.Errmsg("No parent scope; There are only %d nested scopes", i)
			return
		}
	}
	gub.Section("scope number %d", scope.ScopeId())
	gub.Msg("%s", typescope)
}
Beispiel #3
0
// FormatCommand implements the debugger command: format
//
// format
//
// Formats AST and produces source text for function.
// FIXME: allow one to specify a function or package
func FormatCommand(args []string) {
	var syntax ast.Node
	var err error
	fr := gub.CurFrame()
	fn := fr.Fn()
	if len(args) > 1 {
		name := args[1]
		if name != "." {
			fn, err = gub.FuncLookup(name)
			if err != nil {
				gub.Errmsg(err.Error())
				return
			} else if fn == nil {
				gub.Errmsg("function '%s' not found", name)
				return
			}
		}
		syntax = fn.Syntax()
	} else {
		syntax = fn.Syntax()
		switch s := (*gub.Instr).(type) {
		case *ssa2.Trace:
			syntax = s.Syntax()
		}
	}
	// FIXME: Put this as a routine in parent gub and
	// use when showing locations
	if syntax != nil {
		gub.PrintSyntax(syntax, fn.Prog.Fset)
	} else {
		gub.Msg("Sorry, we don't have an AST for this")
	}
}
Beispiel #4
0
// InfoPackageCommand implements the command:
//    info package [*name* ]
// which show information about a package or lists all packages.
func InfoPackageSubcmd(args []string) {
	if len(args) > 2 {
		for _, pkg_name := range args[2:len(args)] {
			if pkg := gub.Program().PackagesByName[pkg_name]; pkg != nil {
				gub.Msg("Package %s: \"%s\"", pkg_name, pkg.Object.Path())
				gub.Section("Package members:")
				var names []string
				for k, _ := range pkg.Members {
					names = append(names, k)
				}
				sort.Strings(names)
				opts := columnize.DefaultOptions()
				opts.DisplayWidth = gub.Maxwidth
				opts.LinePrefix = "  "
				mems := strings.TrimRight(columnize.Columnize(names, opts),
					"\n")
				gub.Msg(mems)

			} else {
				gub.Errmsg("Package %s not imported", pkg_name)
			}
		}
	} else {
		pkgNames := []string{}
		for pkg := range gub.Program().PackagesByName {
			pkgNames = append(pkgNames, pkg)
		}
		gub.PrintSorted("All imported packages", pkgNames)
	}
}
Beispiel #5
0
func AliasCommand(args []string) {
	if len(args) == 1 {
		var names []string
		for k, _ := range gub.Aliases {
			names = append(names, k)
		}
		gub.Section("All aliases:")
		sort.Strings(names)
		opts := columnize.DefaultOptions()
		opts.DisplayWidth = gub.Maxwidth
		opts.LinePrefix = "  "
		mems := strings.TrimRight(columnize.Columnize(names, opts),
			"\n")
		gub.Msg(mems)
	} else {
		cmd := args[1]
		if info := gub.Cmds[cmd]; info != nil {
			if len(info.Aliases) > 0 {
				gub.Msg("Aliases for %s: %s",
					cmd, strings.Join(info.Aliases, ", "))
			} else {
				gub.Msg("No aliases for %s", cmd)
			}
		} else if realCmd := gub.Aliases[cmd]; realCmd != "" {
			gub.Msg("Alias %s is an alias for command %s", cmd, realCmd)

		} else {
			gub.Errmsg("Can't find command or alias %s", cmd)
		}
	}
}
Beispiel #6
0
// InfoBreakpointSubcmd implements the debugger command:
//   info breakpoint
//
// This command shows status of user-settable breakpoints. If no
// breakpoint numbers are given, the show all breakpoints. Otherwise
// only those breakpoints listed are shown and the order given.
//
// The "Disp" column contains one of "keep", "del", the disposition of
// the breakpoint after it gets hit.
//
// The "enb" column indicates whether the breakpoint is enabled.
//
// The "Where" column indicates where the breakpoint is located.
// Status of user-settable breakpoints.
func InfoBreakpointSubcmd(args []string) {
	if gub.IsBreakpointEmpty() {
		gub.Msg("No breakpoints set")
		return
	}
	bpLen := len(gub.Breakpoints)
	if bpLen-gub.BrkptsDeleted == 0 {
		gub.Msg("No breakpoints.")
	}
	if len(args) > 2 {
		headerShown := false
		for _, num := range args[2:] {
			if bpNum, err := gub.GetInt(num,
				"breakpoint number", 0, bpLen-1); err == nil {
				if bp := gub.BreakpointFindById(bpNum); bp != nil {
					if !headerShown {
						gub.Section("Num Type          Disp Enb Where")
						headerShown = true
					}
					gub.Bpprint(*bp)
				} else {
					gub.Errmsg("Breakpoint %d not found.", bpNum)
				}
			}
		}
	} else {
		gub.Section("Num Type          Disp Enb Where")
		for _, bp := range gub.Breakpoints {
			if bp.Deleted {
				continue
			}
			gub.Bpprint(*bp)
		}
	}
}
Beispiel #7
0
func DisassembleCommand(args []string) {
	fr := gub.CurFrame()
	myfn := fr.Fn()
	if len(args) > 1 {
		what := args[1]
		if what == "." {
			if block := gub.CurBlock(); block != nil {
				gub.DisasmBlock(myfn, block.Index, fr.PC())
			} else {
				gub.Errmsg("Can't get block info here")
			}
			return
		} else if what != "+" {
			if fn, err := gub.FuncLookup(what); err == nil && fn != nil {
				myfn = fn
			} else {
				bnum, err := gub.GetInt(args[1],
					"block number of function name", 0, len(myfn.Blocks)-1)
				if err == nil {
					lastBlock := len(myfn.Blocks) - 1
					if bnum <= lastBlock {
						b := myfn.Blocks[bnum]
						if len(args) == 3 {
							ic, err := gub.GetUInt(args[2],
								"instruction number", 0, uint64(len(b.Instrs)-1))
							if err == nil {
								gub.DisasmInst(myfn, bnum, ic)
							}
						} else {
							gub.DisasmBlock(myfn, bnum, -1)
						}
					} else {
						gub.Errmsg("Block number should be between 0 and %d; got %d",
							lastBlock, bnum)
					}
				}
				return
			}
		}
	} else {
		gub.DisasmCurrentInst()
		return
	}
	myfn.WriteTo(os.Stderr)
}
Beispiel #8
0
// DeleteCommand implements the debugger command:
//    delete [bpnum1 ... ]
// which deletes some breakpoints by breakpoint number
//
// See also "breakpoint", "info break", "enable", and "disable".
func DeleteCommand(args []string) {
	for i := 1; i < len(args); i++ {
		msg := fmt.Sprintf("breakpoint number for argument %d", i)
		bpnum, err := gub.GetInt(args[i], msg, 0, len(gub.Breakpoints)-1)
		if err != nil {
			continue
		}
		if gub.BreakpointExists(bpnum) {
			if gub.BreakpointDelete(bpnum) {
				gub.Msg(" Deleted breakpoint %d", bpnum)
			} else {
				gub.Errmsg("Trouble deleting breakpoint %d", bpnum)
			}
		} else {
			gub.Errmsg("Breakpoint %d doesn't exist", bpnum)
		}
	}
}
Beispiel #9
0
func InfoNodeSubcmd(args []string) {
	fr := gub.CurFrame()
	scope := fr.Scope()
	if scope == nil {
		gub.Errmsg("No scope recorded here")
		return
	}
	if scope.Node() != nil {
		ast.Print(fr.Fset(), scope.Node())
	}
}
Beispiel #10
0
func HelpCommand(args []string) {
	if len(args) == 1 {
		gub.Msg(gub.Cmds["help"].Help)
	} else {
		what := args[1]
		cmd := gub.LookupCmd(what)
		if what == "*" {
			var names []string
			for k, _ := range gub.Cmds {
				names = append(names, k)
			}
			gub.Section("All command names:")
			sort.Strings(names)
			opts := columnize.DefaultOptions()
			opts.DisplayWidth = gub.Maxwidth
			opts.LinePrefix = "  "
			mems := strings.TrimRight(columnize.Columnize(names, opts),
				"\n")
			gub.Msg(mems)
		} else if what == "categories" {
			gub.Section("Categories")
			for k, _ := range gub.Categories {
				gub.Msg("\t %s", k)
			}
		} else if info := gub.Cmds[cmd]; info != nil {
			if len(args) > 2 {
				if info.SubcmdMgr != nil {
					gub.HelpSubCommand(info.SubcmdMgr, args)
					return
				}
			}
			gub.Msg(info.Help)
			if len(info.Aliases) > 0 {
				gub.Msg("Aliases: %s",
					strings.Join(info.Aliases, ", "))
			}
		} else if cmds := gub.Categories[what]; len(cmds) > 0 {
			gub.Section("Commands in class: %s", what)
			sort.Strings(cmds)
			opts := columnize.DefaultOptions()
			opts.DisplayWidth = gub.Maxwidth
			mems := strings.TrimRight(columnize.Columnize(cmds, opts),
				"\n")
			gub.Msg(mems)
		} else {
			gub.Errmsg("Can't find help for %s", what)
		}
	}
}
Beispiel #11
0
func SetTraceSubcmd(args []string) {
	onoff := "on"
	if len(args) == 3 {
		onoff = args[2]
	}
	switch ParseOnOff(onoff) {
	case ONOFF_ON:
		if interp.InstTracing() {
			gub.Errmsg("Instruction tracing already on")
		} else {
			gub.Msg("Setting Instruction trace on")
			interp.SetInstTracing()
		}
	case ONOFF_OFF:
		if !interp.InstTracing() {
			gub.Errmsg("Instruction tracing already off")
		} else {
			gub.Msg("Setting Instruction trace off")
			interp.ClearInstTracing()
		}
	case ONOFF_UNKNOWN:
		gub.Errmsg("Expecting 'on' or 'off', got '%s'; nothing done", onoff)
	}
}
Beispiel #12
0
func SetHighlightSubcmd(args []string) {
	onoff := "on"
	if len(args) == 3 {
		onoff = args[2]
	}
	switch ParseOnOff(onoff) {
	case ONOFF_ON:
		if *gub.Highlight {
			gub.Errmsg("Highlight is already on")
		} else {
			gub.Msg("Setting highlight on")
			*gub.Highlight = true
		}
	case ONOFF_OFF:
		if !*gub.Highlight {
			gub.Errmsg("highight is already off")
		} else {
			gub.Msg("Setting highlight off")
			*gub.Highlight = false
		}
	case ONOFF_UNKNOWN:
		gub.Msg("Expecting 'on' or 'off', got '%s'; nothing done", onoff)
	}
}
Beispiel #13
0
func EnvironmentCommand(args []string) {
	if len(args) == 2 {
		name := args[1]
		nameVal, interpVal, scopeVal := gub.EnvLookup(gub.CurFrame(), name, gub.CurScope())
		if nameVal != nil {
			gub.PrintInEnvironment(gub.CurFrame(), name, nameVal, interpVal, scopeVal)
		} else {
			gub.Errmsg("%s is in not the environment", name)
		}
		return
	}
	for nameVal, interpVal := range gub.CurFrame().Env() {
		gub.PrintInEnvironment(gub.CurFrame(), nameVal.Name(), nameVal,
			interpVal, gub.CurScope())
	}
}
Beispiel #14
0
func InstructionCommand(args []string) {
	fr := gub.CurFrame()
	ic := uint64(fr.PC())
	if len(args) >= 2 {
		new_ic, ok := gub.GetUInt(args[1], "instruction number", 0,
			uint64(len(gub.CurFrame().Block().Instrs)))
		if ok == nil {
			ic = new_ic
		} else {
			gub.Errmsg("Expecting integer; got %s.", args[1])
			return
		}
		// if len(args) == 3 {
		// 	new_num, ok = strconv.Atoi(args[2])
		// 	if ok != nil {
		// 		gub.Errmsg("Expecting integer; got %s", args[2])
		// 		return
		// 	}
	}
	gub.DisasmInst(fr.Fn(), fr.Block().Index, ic)
	genericInstr := fr.Block().Instrs[ic]
	switch instr := genericInstr.(type) {
	case *ssa2.ChangeType:
		gub.Msg("%s: %s", instr.X.Name(), gub.Deref2Str(fr.Get(instr.X), nil))
	case *ssa2.Convert:
		gub.Msg("%s: %s", instr.X.Name(), gub.Deref2Str(fr.Get(instr.X), nil))
	case *ssa2.MakeInterface:
		gub.Msg("%s: %s", instr.X.Name(), gub.Deref2Str(fr.Get(instr.X), nil))
	case *ssa2.ChangeInterface:
		gub.Msg("%s: %s", instr.X.Name(), gub.Deref2Str(fr.Get(instr.X), nil))
	case *ssa2.Range:
		gub.Msg("%s: %s", instr.X.Name(), gub.Deref2Str(fr.Get(instr.X), nil))
	case *ssa2.UnOp:
		gub.Msg("%s: %s", instr.X.Name(), gub.Deref2Str(fr.Get(instr.X), nil))
	case *ssa2.Field:
		gub.Msg("%s: %s", instr.X.Name(), gub.Deref2Str(fr.Get(instr.X), nil))
	case *ssa2.BinOp:
		gub.Msg("%s: %s", instr.X.Name(), gub.Deref2Str(fr.Get(instr.X), nil))
		gub.Msg("%s: %s", instr.X.Name(), gub.Deref2Str(fr.Get(instr.Y), nil))
	case *ssa2.Trace:
	default:
		gub.Msg("Don't know how to deal with %s yet", instr)
	}
}
Beispiel #15
0
// QuitCommand implements the debugger command: quit
//
// quit [exit-code]
//
// Terminates program. If an exit code is given, that is the exit code
// for the program. Zero (normal termination) is used if no
// termintation code.
func QuitCommand(args []string) {
	rc := 0
	if len(args) == 2 {
		new_rc, ok := strconv.Atoi(args[1])
		if ok == nil {
			rc = new_rc
		} else {
			gub.Errmsg("Expecting integer return code; got %s. Ignoring",
				args[1])
		}
	}
	gub.Msg("gub: That's all folks...")

	// FIXME: determine under which conditions we've used term
	gnureadline.Rl_reset_terminal(gub.Term)

	os.Exit(rc)

}
Beispiel #16
0
// BreakpointCommand implements the debugger command:
//    breakpoint [*fn* | line [column]
// which sets a breakpoint.
//
// The target can either be a function name as fn pkg.fn
// or a line and and optional column number. Specifying a column number
// may be useful if there is more than one statement on a line or if you
// want to distinguish parts of a compound statement.
//
// See also "info break", "enable", and "disable" and "delete".
func BreakpointCommand(args []string) {
	if len(args) == 1 {
		InfoBreakpointSubcmd(args)
		return
	}
	name := args[1]
	fn := gub.GetFunction(name)
	if fn != nil {
		if ext := interp.Externals()[name]; ext != nil {
			gub.Msg("Sorry, %s is a built-in external function.", name)
			return
		}
		interp.SetFnBreakpoint(fn)
		bp := &gub.Breakpoint {
			Hits: 0,
			Id: gub.BreakpointNext(),
			Pos: fn.Pos(),
			EndP: fn.EndP(),
			Ignore: 0,
			Kind: "Function",
			Temp: false,
			Enabled: true,
		}
		bpnum := gub.BreakpointAdd(bp)
		gub.Msg(" Breakpoint %d set in function %s at %s", bpnum, name,
			ssa2.FmtRange(fn, fn.Pos(), fn.EndP()))
		return
	}
	line, ok := strconv.Atoi(args[1])
	if ok != nil {
		gub.Errmsg("Don't know yet how to deal with a break that doesn't start with a function or integer")
		return
	}

	column := -1
	if len(args) == 3 {
		foo, ok := strconv.Atoi(args[2])
		if ok != nil {
			gub.Errmsg("Don't know how to deal a non-int argument as 2nd parameter yet")
			return
		}
		column = foo
	}

	fn = gub.CurFrame().Fn()
	fset := gub.CurFrame().Fset()
	position := gub.CurFrame().Position()
	if position.IsValid() {
		filename := position.Filename
		for _, l := range fn.Pkg.Locs() {
			try := fset.Position(l.Pos())
			if try.Filename == filename && line == try.Line {
				if column == -1 || column == try.Column {
					bp := &gub.Breakpoint {
						Hits: 0,
						Id: gub.BreakpointNext(),
						Pos: l.Pos(),
						EndP: l.Pos(),
						Ignore: 0,
						Kind: "Statement",
						Temp: false,
						Enabled: true,
					}
					bpnum := gub.BreakpointAdd(bp)
					if l.Trace != nil {
						l.Trace.Breakpoint = true
					} else if l.Fn != nil {
						l.Fn.Breakpoint = true
						bp.Kind = "Function"
					} else {
						gub.Errmsg("Internal error setting in file %s line %d, column %d",
							bpnum, filename, line, try.Column)
						return
					}
					gub.Msg("Breakpoint %d set in file %s line %d, column %d", bpnum, filename, line, try.Column)
					return
				}
			}
		}
		suffix := ""
		if column != -1 { suffix = ", column " + args[2] }
		gub.Errmsg("Can't find statement in file %s at line %d%s", filename, line, suffix)
	}
}