Пример #1
0
func restart(client service.Client, args ...string) error {
	if err := client.Restart(); err != nil {
		return err
	}
	fmt.Println("Process restarted with PID", client.ProcessPid())
	return nil
}
Пример #2
0
func findLocationHelper(t *testing.T, c service.Client, loc string, shouldErr bool, count int, checkAddr uint64) []uint64 {
	locs, err := c.FindLocation(api.EvalScope{-1, 0}, loc)
	t.Logf("FindLocation(\"%s\") → %v\n", loc, locs)

	if shouldErr {
		if err == nil {
			t.Fatalf("Resolving location <%s> didn't return an error: %v", loc, locs)
		}
	} else {
		if err != nil {
			t.Fatalf("Error resolving location <%s>: %v", loc, err)
		}
	}

	if (count >= 0) && (len(locs) != count) {
		t.Fatalf("Wrong number of breakpoints returned for location <%s> (got %d, expected %d)", loc, len(locs), count)
	}

	if checkAddr != 0 && checkAddr != locs[0].PC {
		t.Fatalf("Wrong address returned for location <%s> (got %v, epected %v)", loc, locs[0].PC, checkAddr)
	}

	addrs := make([]uint64, len(locs))
	for i := range locs {
		addrs[i] = locs[i].PC
	}
	return addrs
}
Пример #3
0
func locals(client service.Client, scope api.EvalScope, filter string) ([]string, error) {
	locals, err := client.ListLocalVariables(scope)
	if err != nil {
		return nil, err
	}
	return filterVariables(locals, filter), nil
}
Пример #4
0
func goroutine(client service.Client, args ...string) error {
	switch len(args) {
	case 0:
		return printscope(client)

	case 1:
		gid, err := strconv.Atoi(args[0])
		if err != nil {
			return err
		}

		oldState, err := client.GetState()
		if err != nil {
			return err
		}
		newState, err := client.SwitchGoroutine(gid)
		if err != nil {
			return err
		}

		fmt.Printf("Switched from %d to %d (thread %d)\n", oldState.SelectedGoroutine.ID, gid, newState.CurrentThread.ID)
		return nil

	default:
		return scopePrefix(client, "goroutine", args...)
	}
}
Пример #5
0
func breakpoints(client service.Client, args ...string) error {
	breakPoints, err := client.ListBreakpoints()
	if err != nil {
		return err
	}
	sort.Sort(ById(breakPoints))
	for _, bp := range breakPoints {
		thing := "Breakpoint"
		if bp.Tracepoint {
			thing = "Tracepoint"
		}
		fmt.Printf("%s %d at %#v %s:%d\n", thing, bp.ID, bp.Addr, shortenFilePath(bp.File), bp.Line)

		var attrs []string
		if bp.Stacktrace > 0 {
			attrs = append(attrs, "-stack")
			attrs = append(attrs, strconv.Itoa(bp.Stacktrace))
		}
		if bp.Goroutine {
			attrs = append(attrs, "-goroutine")
		}
		for i := range bp.Variables {
			attrs = append(attrs, bp.Variables[i])
		}
		if len(attrs) > 0 {
			fmt.Printf("\t%s\n", strings.Join(attrs, " "))
		}
	}
	return nil
}
Пример #6
0
func vars(client service.Client, filter string) ([]string, error) {
	vars, err := client.ListPackageVariables(filter)
	if err != nil {
		return nil, err
	}
	return filterVariables(vars, filter), nil
}
Пример #7
0
func setVar(client service.Client, scope api.EvalScope, args ...string) error {
	if len(args) != 2 {
		return fmt.Errorf("wrong number of arguments")
	}

	return client.SetVariable(scope, args[0], args[1])
}
Пример #8
0
func args(client service.Client, scope api.EvalScope, filter string) ([]string, error) {
	vars, err := client.ListFunctionArgs(scope)
	if err != nil {
		return nil, err
	}
	return filterVariables(vars, filter), nil
}
Пример #9
0
func threads(client service.Client, args ...string) error {
	threads, err := client.ListThreads()
	if err != nil {
		return err
	}
	state, err := client.GetState()
	if err != nil {
		return err
	}
	sort.Sort(byThreadID(threads))
	for _, th := range threads {
		prefix := "  "
		if state.CurrentThread != nil && state.CurrentThread.ID == th.ID {
			prefix = "* "
		}
		if th.Function != nil {
			fmt.Printf("%sThread %d at %#v %s:%d %s\n",
				prefix, th.ID, th.PC, shortenFilePath(th.File),
				th.Line, th.Function.Name)
		} else {
			fmt.Printf("%sThread %s\n", prefix, formatThread(th))
		}
	}
	return nil
}
Пример #10
0
func handleExit(client service.Client, t *Term) (error, int) {
	fullHistoryFile, err := getConfigFilePath(historyFile)
	if err != nil {
		fmt.Println("Error saving history file:", err)
	} else {
		if f, err := os.OpenFile(fullHistoryFile, os.O_RDWR, 0666); err == nil {
			_, err := t.line.WriteHistory(f)
			if err != nil {
				fmt.Println("readline history error: ", err)
			}
			f.Close()
		}
	}

	kill := true
	if client.AttachedToExistingProcess() {
		answer, err := t.line.Prompt("Would you like to kill the process? [Y/n] ")
		if err != nil {
			return io.EOF, 2
		}
		answer = strings.ToLower(strings.TrimSpace(answer))
		kill = (answer != "n" && answer != "no")
	}
	err = client.Detach(kill)
	if err != nil {
		return err, 1
	}
	return nil, 0
}
Пример #11
0
func stackCommand(client service.Client, args ...string) error {
	var err error

	goroutineid := -1
	depth := 10

	switch len(args) {
	case 0:
		// nothing to do
	case 2:
		goroutineid, err = strconv.Atoi(args[1])
		if err != nil {
			return fmt.Errorf("Wrong argument: expected integer")
		}
		fallthrough
	case 1:
		depth, err = strconv.Atoi(args[0])
		if err != nil {
			return fmt.Errorf("Wrong argument: expected integer")
		}

	default:
		return fmt.Errorf("Wrong number of arguments to stack")
	}

	stack, err := client.Stacktrace(goroutineid, depth)
	if err != nil {
		return err
	}
	printStack(stack, "")
	return nil
}
Пример #12
0
func breakpoint(client service.Client, args ...string) error {
	if len(args) != 1 {
		return fmt.Errorf("argument must be either a function name or <file:line>")
	}
	requestedBp := &api.Breakpoint{}
	tokens := strings.Split(args[0], ":")
	switch {
	case len(tokens) == 1:
		requestedBp.FunctionName = args[0]
	case len(tokens) == 2:
		file := tokens[0]
		line, err := strconv.Atoi(tokens[1])
		if err != nil {
			return err
		}
		requestedBp.File = file
		requestedBp.Line = line
	default:
		return fmt.Errorf("invalid line reference")
	}

	bp, err := client.CreateBreakpoint(requestedBp)
	if err != nil {
		return err
	}

	fmt.Printf("Breakpoint %d set at %#v for %s %s:%d\n", bp.ID, bp.Addr, bp.FunctionName, bp.File, bp.Line)
	return nil
}
Пример #13
0
func thread(client service.Client, args ...string) error {
	if len(args) == 0 {
		return fmt.Errorf("you must specify a thread")
	}
	tid, err := strconv.Atoi(args[0])
	if err != nil {
		return err
	}
	oldState, err := client.GetState()
	if err != nil {
		return err
	}
	newState, err := client.SwitchThread(tid)
	if err != nil {
		return err
	}

	oldThread := "<none>"
	newThread := "<none>"
	if oldState.CurrentThread != nil {
		oldThread = strconv.Itoa(oldState.CurrentThread.ID)
	}
	if newState.CurrentThread != nil {
		newThread = strconv.Itoa(newState.CurrentThread.ID)
	}
	fmt.Printf("Switched from %s to %s\n", oldThread, newThread)
	return nil
}
Пример #14
0
func regs(client service.Client, args ...string) error {
	regs, err := client.ListRegisters()
	if err != nil {
		return err
	}
	fmt.Println(regs)
	return nil
}
Пример #15
0
func next(client service.Client, args ...string) error {
	state, err := client.Next()
	if err != nil {
		return err
	}
	printcontext(state)
	return nil
}
Пример #16
0
func printscope(client service.Client) error {
	state, err := client.GetState()
	if err != nil {
		return err
	}

	fmt.Printf("Thread %s\nGoroutine %s\n", formatThread(state.CurrentThread), formatGoroutine(state.SelectedGoroutine))
	return nil
}
Пример #17
0
func cont(client service.Client, args ...string) error {
	stateChan := client.Continue()
	for state := range stateChan {
		if state.Err != nil {
			return state.Err
		}
		printcontext(state)
	}
	return nil
}
Пример #18
0
func goroutines(client service.Client, args ...string) error {
	gs, err := client.ListGoroutines()
	if err != nil {
		return err
	}
	fmt.Printf("[%d goroutines]\n", len(gs))
	for _, g := range gs {
		fmt.Printf("Goroutine %s\n", formatGoroutine(g))
	}
	return nil
}
Пример #19
0
func printVar(client service.Client, scope api.EvalScope, args ...string) error {
	if len(args) == 0 {
		return fmt.Errorf("not enough arguments")
	}
	val, err := client.EvalVariable(scope, args[0])
	if err != nil {
		return err
	}
	fmt.Println(val.Value)
	return nil
}
Пример #20
0
func setBreakpoint(client service.Client, tracepoint bool, args ...string) error {
	if len(args) < 1 {
		return fmt.Errorf("address required, specify either a function name or <file:line>")
	}

	requestedBp := &api.Breakpoint{}
	tokens := strings.Split(args[0], ":")
	switch {
	case len(tokens) == 1:
		requestedBp.FunctionName = args[0]
	case len(tokens) == 2:
		file := tokens[0]
		line, err := strconv.Atoi(tokens[1])
		if err != nil {
			return err
		}
		requestedBp.File = file
		requestedBp.Line = line
	default:
		return fmt.Errorf("invalid line reference")
	}

	for i := 1; i < len(args); i++ {
		switch args[i] {
		case "-stack":
			i++
			n, err := strconv.Atoi(args[i])
			if err != nil {
				return fmt.Errorf("argument of -stack must be a number")
			}
			requestedBp.Stacktrace = n
		case "-goroutine":
			requestedBp.Goroutine = true
		default:
			requestedBp.Variables = append(requestedBp.Variables, args[i])
		}
	}

	requestedBp.Tracepoint = tracepoint

	bp, err := client.CreateBreakpoint(requestedBp)
	if err != nil {
		return err
	}

	thing := "Breakpoint"
	if tracepoint {
		thing = "Tracepoint"
	}

	fmt.Printf("%s %d set at %#v for %s %s:%d\n", thing, bp.ID, bp.Addr, bp.FunctionName, bp.File, bp.Line)
	return nil
}
Пример #21
0
func breakpoints(client service.Client, args ...string) error {
	breakPoints, err := client.ListBreakpoints()
	if err != nil {
		return err
	}
	sort.Sort(ById(breakPoints))
	for _, bp := range breakPoints {
		fmt.Printf("Breakpoint %d at %#v %s:%d\n", bp.ID, bp.Addr, bp.File, bp.Line)
	}

	return nil
}
Пример #22
0
func clearAll(client service.Client, args ...string) error {
	breakPoints, err := client.ListBreakpoints()
	if err != nil {
		return err
	}
	for _, bp := range breakPoints {
		_, err := client.ClearBreakpoint(bp.ID)
		if err != nil {
			fmt.Printf("Couldn't delete breakpoint %d at %#v %s:%d: %s\n", bp.ID, bp.Addr, shortenFilePath(bp.File), bp.Line, err)
		}
		fmt.Printf("Breakpoint %d cleared at %#v for %s %s:%d\n", bp.ID, bp.Addr, bp.FunctionName, shortenFilePath(bp.File), bp.Line)
	}
	return nil
}
Пример #23
0
func goroutines(client service.Client, args ...string) error {
	gs, err := client.ListGoroutines()
	if err != nil {
		return err
	}
	fmt.Printf("[%d goroutines]\n", len(gs))
	for _, g := range gs {
		var fname string
		if g.Function != nil {
			fname = g.Function.Name
		}
		fmt.Printf("Goroutine %d - %s:%d %s (%#v)\n", g.ID, g.File, g.Line, fname, g.PC)
	}
	return nil
}
Пример #24
0
func clear(client service.Client, args ...string) error {
	if len(args) == 0 {
		return fmt.Errorf("not enough arguments")
	}
	id, err := strconv.Atoi(args[0])
	if err != nil {
		return err
	}
	bp, err := client.ClearBreakpoint(id)
	if err != nil {
		return err
	}
	fmt.Printf("Breakpoint %d cleared at %#v for %s %s:%d\n", bp.ID, bp.Addr, bp.FunctionName, shortenFilePath(bp.File), bp.Line)
	return nil
}
Пример #25
0
func setBreakpoint(client service.Client, tracepoint bool, args ...string) error {
	if len(args) < 1 {
		return fmt.Errorf("address required, specify either a function name or <file:line>")
	}

	requestedBp := &api.Breakpoint{}

	for i := 1; i < len(args); i++ {
		switch args[i] {
		case "-stack":
			i++
			n, err := strconv.Atoi(args[i])
			if err != nil {
				return fmt.Errorf("argument of -stack must be a number")
			}
			requestedBp.Stacktrace = n
		case "-goroutine":
			requestedBp.Goroutine = true
		default:
			requestedBp.Variables = append(requestedBp.Variables, args[i])
		}
	}

	requestedBp.Tracepoint = tracepoint

	locs, err := client.FindLocation(args[0])
	if err != nil {
		return err
	}

	thing := "Breakpoint"
	if tracepoint {
		thing = "Tracepoint"
	}

	for _, loc := range locs {
		requestedBp.Addr = loc.PC

		bp, err := client.CreateBreakpoint(requestedBp)
		if err != nil {
			return err
		}

		fmt.Printf("%s %d set at %#v for %s %s:%d\n", thing, bp.ID, bp.Addr, bp.FunctionName, bp.File, bp.Line)
	}

	return nil
}
Пример #26
0
func stackCommand(client service.Client, args ...string) error {
	var (
		err         error
		goroutineid = -1
	)
	depth, full, err := parseStackArgs(args)
	if err != nil {
		return err
	}
	stack, err := client.Stacktrace(goroutineid, depth, full)
	if err != nil {
		return err
	}
	printStack(stack, "")
	return nil
}
Пример #27
0
func goroutines(client service.Client, args ...string) error {
	state, err := client.GetState()
	if err != nil {
		return err
	}
	gs, err := client.ListGoroutines()
	if err != nil {
		return err
	}
	fmt.Printf("[%d goroutines]\n", len(gs))
	for _, g := range gs {
		prefix := "  "
		if g.ID == state.SelectedGoroutine.ID {
			prefix = "* "
		}
		fmt.Printf("%sGoroutine %s\n", prefix, formatGoroutine(g))
	}
	return nil
}
Пример #28
0
func listCommand(client service.Client, args ...string) error {
	if len(args) == 0 {
		state, err := client.GetState()
		if err != nil {
			return err
		}
		printcontext(state)
		return nil
	}

	locs, err := client.FindLocation(api.EvalScope{-1, 0}, args[0])
	if err != nil {
		return err
	}
	if len(locs) > 1 {
		return debugger.AmbiguousLocationError{Location: args[0], CandidatesLocation: locs}
	}
	printfile(locs[0].File, locs[0].Line, false)
	return nil
}
Пример #29
0
func stackCommand(client service.Client, args ...string) error {
	var err error

	goroutineid := -1
	depth := 10

	switch len(args) {
	case 0:
		// nothing to do
	case 2:
		goroutineid, err = strconv.Atoi(args[1])
		if err != nil {
			return fmt.Errorf("Wrong argument: expected integer")
		}
		fallthrough
	case 1:
		depth, err = strconv.Atoi(args[0])
		if err != nil {
			return fmt.Errorf("Wrong argument: expected integer")
		}

	default:
		return fmt.Errorf("Wrong number of arguments to stack")
	}

	stack, err := client.Stacktrace(goroutineid, depth)
	if err != nil {
		return err
	}
	for i := range stack {
		name := "(nil)"
		if stack[i].Function != nil {
			name = stack[i].Function.Name
		}
		fmt.Printf("%d. %s\n\t%s:%d (%#v)\n", i, name, stack[i].File, stack[i].Line, stack[i].PC)
	}
	return nil
}
Пример #30
0
func funcs(client service.Client, filter string) ([]string, error) {
	return client.ListFunctions(filter)
}