diff --git a/_scripts/gen-cli-docs.go b/_scripts/gen-cli-docs.go index d85e1eda..63b00c00 100644 --- a/_scripts/gen-cli-docs.go +++ b/_scripts/gen-cli-docs.go @@ -1,3 +1,4 @@ +//go:build ignore // +build ignore package main diff --git a/_scripts/gen-usage-docs.go b/_scripts/gen-usage-docs.go index 244e18d5..02c9b4a9 100644 --- a/_scripts/gen-usage-docs.go +++ b/_scripts/gen-usage-docs.go @@ -1,3 +1,4 @@ +//go:build ignore // +build ignore package main diff --git a/pkg/config/split.go b/pkg/config/split.go index 22fe18cb..05ca977e 100644 --- a/pkg/config/split.go +++ b/pkg/config/split.go @@ -12,7 +12,7 @@ import ( // SplitQuotedFields is like strings.Fields but ignores spaces inside areas surrounded // by the specified quote character. -// To specify a single quote use backslash to escape it: '\'' +// To specify a single quote use backslash to escape it: \' func SplitQuotedFields(in string, quote rune) []string { type stateEnum int const ( diff --git a/pkg/dwarf/godwarf/tree.go b/pkg/dwarf/godwarf/tree.go index e36c3a99..12008d9e 100644 --- a/pkg/dwarf/godwarf/tree.go +++ b/pkg/dwarf/godwarf/tree.go @@ -193,7 +193,9 @@ func max(a, b uint64) uint64 { } // fuseRanges fuses rngs2 into rngs1, it's the equivalent of -// normalizeRanges(append(rngs1, rngs2)) +// +// normalizeRanges(append(rngs1, rngs2)) +// // but more efficient. func fuseRanges(rngs1, rngs2 [][2]uint64) [][2]uint64 { if rangesContains(rngs1, rngs2) { diff --git a/pkg/dwarf/godwarf/type.go b/pkg/dwarf/godwarf/type.go index 5e257d28..af0e17f5 100644 --- a/pkg/dwarf/godwarf/type.go +++ b/pkg/dwarf/godwarf/type.go @@ -535,7 +535,7 @@ func (t *UnsupportedType) stringIntl(recCheck) string { func (t *UnsupportedType) String() string { return t.stringIntl(nil) } -// ReadType reads the type at off in the DWARF ``info'' section. +// ReadType reads the type at off in the DWARF “info” section. func ReadType(d *dwarf.Data, index int, off dwarf.Offset, typeCache map[dwarf.Offset]Type) (Type, error) { typ, err := readType(d, "info", d.Reader(), off, typeCache, nil) if typ != nil { diff --git a/pkg/locspec/doc.go b/pkg/locspec/doc.go index 1f75ac03..1e1560af 100644 --- a/pkg/locspec/doc.go +++ b/pkg/locspec/doc.go @@ -3,13 +3,14 @@ // // Location spec examples: // -// locStr ::= : | [:] | // | (+|-) | | *
-// * can be the full path of a file or just a suffix -// * ::= .. | .(*). | . | . | (*). | -// must be unambiguous -// * // will return a location for each function matched by regex -// * + returns a location for the line that is lines after the current line -// * - returns a location for the line that is lines before the current line -// * returns a location for a line in the current file -// * *
returns the location corresponding to the specified address +// locStr ::= : | [:] | // | (+|-) | | *
+// +// * can be the full path of a file or just a suffix +// * ::= .. | .(*). | . | . | (*). | +// must be unambiguous +// * // will return a location for each function matched by regex +// * + returns a location for the line that is lines after the current line +// * - returns a location for the line that is lines before the current line +// * returns a location for a line in the current file +// * *
returns the location corresponding to the specified address package locspec diff --git a/pkg/proc/bininfo.go b/pkg/proc/bininfo.go index 736a8dc6..d1eff8db 100644 --- a/pkg/proc/bininfo.go +++ b/pkg/proc/bininfo.go @@ -1337,7 +1337,7 @@ func loadBinaryInfoElf(bi *BinaryInfo, image *Image, path string, addr uint64, w return nil } -// _STT_FUNC is a code object, see /usr/include/elf.h for a full definition. +// _STT_FUNC is a code object, see /usr/include/elf.h for a full definition. const _STT_FUNC = 2 func (bi *BinaryInfo) loadSymbolName(image *Image, file *elf.File, wg *sync.WaitGroup) { @@ -1633,13 +1633,15 @@ func (bi *BinaryInfo) parseDebugFrameMacho(image *Image, exe *macho.File, debugI bi.parseDebugFrameGeneral(image, debugFrameBytes, "__debug_frame", debugFrameErr, ehFrameBytes, ehFrameAddr, "__eh_frame", frame.DwarfEndian(debugInfoBytes)) } -// macOSDebugFrameBugWorkaround applies a workaround for: -// https://github.com/golang/go/issues/25841 +// macOSDebugFrameBugWorkaround applies a workaround for [golang/go#25841] +// // It finds the Go function with the lowest entry point and the first // debug_frame FDE, calculates the difference between the start of the // function and the start of the FDE and sums it to all debug_frame FDEs. // A number of additional checks are performed to make sure we don't ruin // executables unaffected by this bug. +// +// [golang/go#25841]: https://github.com/golang/go/issues/25841 func (bi *BinaryInfo) macOSDebugFrameBugWorkaround() { //TODO: log extensively because of bugs in the field if bi.GOOS != "darwin" || bi.Arch.Name != "arm64" { @@ -1967,9 +1969,9 @@ func (bi *BinaryInfo) loadDebugInfoMaps(image *Image, debugInfoBytes, debugLineB // LookupGenericFunc returns a map that allows searching for instantiations of generic function by specificying a function name without type parameters. // For example the key "pkg.(*Receiver).Amethod" will find all instantiations of Amethod: -// - pkg.(*Receiver[.shape.int]).Amethod" -// - pkg.(*Receiver[.shape.*uint8]).Amethod" -// - etc. +// - pkg.(*Receiver[.shape.int]).Amethod +// - pkg.(*Receiver[.shape.*uint8]).Amethod +// - etc. func (bi *BinaryInfo) LookupGenericFunc() map[string][]*Function { if bi.lookupGenericFunc == nil { bi.lookupGenericFunc = make(map[string][]*Function) diff --git a/pkg/proc/core/core.go b/pkg/proc/core/core.go index 3efd765b..62a1fdeb 100644 --- a/pkg/proc/core/core.go +++ b/pkg/proc/core/core.go @@ -21,10 +21,12 @@ var ErrNoThreads = errors.New("no threads found in core file") // 0x0000000000400000 0x000000000044f000 0x0000000000000000 // but then it's partially overwritten with an RW mapping whose data is stored // in the core file: -// Type Offset VirtAddr PhysAddr -// FileSiz MemSiz Flags Align -// LOAD 0x0000000000004000 0x000000000049a000 0x0000000000000000 -// 0x0000000000002000 0x0000000000002000 RW 1000 +// +// Type Offset VirtAddr PhysAddr +// FileSiz MemSiz Flags Align +// LOAD 0x0000000000004000 0x000000000049a000 0x0000000000000000 +// 0x0000000000002000 0x0000000000002000 RW 1000 +// // This can be represented in a SplicedMemory by adding the original region, // then putting the RW mapping on top of it. type splicedMemory struct { diff --git a/pkg/proc/doc.go b/pkg/proc/doc.go index 60798871..8ffdd5c8 100644 --- a/pkg/proc/doc.go +++ b/pkg/proc/doc.go @@ -2,8 +2,8 @@ // the process we are debugging. // // proc implements all core functionality including: -// * creating / attaching to a process -// * process manipulation (step, next, continue, halt) -// * methods to explore the memory of the process // +// - creating / attaching to a process +// - process manipulation (step, next, continue, halt) +// - methods to explore the memory of the process package proc diff --git a/pkg/proc/eval.go b/pkg/proc/eval.go index 071e3763..24c5a6bd 100644 --- a/pkg/proc/eval.go +++ b/pkg/proc/eval.go @@ -338,17 +338,17 @@ func afterLastArgAddr(vars []*Variable) uint64 { } // setValue writes the value of srcv to dstv. -// * If srcv is a numerical literal constant and srcv is of a compatible type -// the necessary type conversion is performed. -// * If srcv is nil and dstv is of a nil'able type then dstv is nilled. -// * If srcv is the empty string and dstv is a string then dstv is set to the -// empty string. -// * If dstv is an "interface {}" and srcv is either an interface (possibly -// non-empty) or a pointer shaped type (map, channel, pointer or struct -// containing a single pointer field) the type conversion to "interface {}" -// is performed. -// * If srcv and dstv have the same type and are both addressable then the -// contents of srcv are copied byte-by-byte into dstv +// - If srcv is a numerical literal constant and srcv is of a compatible type +// the necessary type conversion is performed. +// - If srcv is nil and dstv is of a nil'able type then dstv is nilled. +// - If srcv is the empty string and dstv is a string then dstv is set to the +// empty string. +// - If dstv is an "interface {}" and srcv is either an interface (possibly +// non-empty) or a pointer shaped type (map, channel, pointer or struct +// containing a single pointer field) the type conversion to "interface {}" +// is performed. +// - If srcv and dstv have the same type and are both addressable then the +// contents of srcv are copied byte-by-byte into dstv func (scope *EvalScope) setValue(dstv, srcv *Variable, srcExpr string) error { srcv.loadValue(loadSingleValue) diff --git a/pkg/proc/gdbserial/rr.go b/pkg/proc/gdbserial/rr.go index f377fa49..e133b12b 100644 --- a/pkg/proc/gdbserial/rr.go +++ b/pkg/proc/gdbserial/rr.go @@ -2,7 +2,6 @@ package gdbserial import ( "bufio" - "bytes" "fmt" "io" "io/ioutil" @@ -12,8 +11,8 @@ import ( "strconv" "strings" "syscall" - "unicode" + "github.com/go-delve/delve/pkg/config" "github.com/go-delve/delve/pkg/proc" ) @@ -248,7 +247,7 @@ func (err *ErrMalformedRRGdbCommand) Error() string { func rrParseGdbCommand(line string) rrInit { port := "" - fields := splitQuotedFields(line) + fields := config.SplitQuotedFields(line, '\'') for i := 0; i < len(fields); i++ { switch fields[i] { case "-ex": @@ -279,63 +278,6 @@ func rrParseGdbCommand(line string) rrInit { return rrInit{port: port, exe: exe} } -// Like strings.Fields but ignores spaces inside areas surrounded -// by single quotes. -// To specify a single quote use backslash to escape it: '\'' -func splitQuotedFields(in string) []string { - type stateEnum int - const ( - inSpace stateEnum = iota - inField - inQuote - inQuoteEscaped - ) - state := inSpace - r := []string{} - var buf bytes.Buffer - - for _, ch := range in { - switch state { - case inSpace: - if ch == '\'' { - state = inQuote - } else if !unicode.IsSpace(ch) { - buf.WriteRune(ch) - state = inField - } - - case inField: - if ch == '\'' { - state = inQuote - } else if unicode.IsSpace(ch) { - r = append(r, buf.String()) - buf.Reset() - } else { - buf.WriteRune(ch) - } - - case inQuote: - if ch == '\'' { - state = inField - } else if ch == '\\' { - state = inQuoteEscaped - } else { - buf.WriteRune(ch) - } - - case inQuoteEscaped: - buf.WriteRune(ch) - state = inQuote - } - } - - if buf.Len() != 0 { - r = append(r, buf.String()) - } - - return r -} - // RecordAndReplay acts like calling Record and then Replay. func RecordAndReplay(cmd []string, wd string, quiet bool, debugInfoDirs []string, redirects [3]string) (*proc.Target, string, error) { tracedir, err := Record(cmd, wd, quiet, redirects) diff --git a/pkg/proc/native/ptrace_linux_386.go b/pkg/proc/native/ptrace_linux_386.go index b31f0a7f..1c1039b5 100644 --- a/pkg/proc/native/ptrace_linux_386.go +++ b/pkg/proc/native/ptrace_linux_386.go @@ -47,12 +47,13 @@ func ptraceGetRegset(tid int) (regset amd64util.AMD64Xstate, err error) { // ptraceGetTls return the addr of tls by PTRACE_GET_THREAD_AREA for specify thread. // See http://man7.org/linux/man-pages/man2/ptrace.2.html for detail about PTRACE_GET_THREAD_AREA. // struct user_desc at https://golang.org/src/runtime/sys_linux_386.s -// type UserDesc struct { -// EntryNumber uint32 -// BaseAddr uint32 -// Limit uint32 -// Flag uint32 -// } +// +// type UserDesc struct { +// EntryNumber uint32 +// BaseAddr uint32 +// Limit uint32 +// Flag uint32 +// } func ptraceGetTls(gs int32, tid int) (uint32, error) { ud := [4]uint32{} diff --git a/pkg/proc/native/threads_linux_arm64.go b/pkg/proc/native/threads_linux_arm64.go index 43caea68..151cbe0c 100644 --- a/pkg/proc/native/threads_linux_arm64.go +++ b/pkg/proc/native/threads_linux_arm64.go @@ -65,9 +65,10 @@ func (wpstate *watchpointState) set(idx uint8, addr, ctrl uint64) { // The format of this register set is described by user_hwdebug_state in // arch/arm64/include/uapi/asm/ptrace.h. // It consists of one 64bit word containing: -// * 1byte number of watchpoints -// * 1byte debug architecture version (the 4 least significant bits of ID_AA64DFR0_EL1) -// * 6bytes padding +// - 1byte number of watchpoints +// - 1byte debug architecture version (the 4 least significant bits of ID_AA64DFR0_EL1) +// - 6bytes padding +// // Followed by 2 64bit words for each watchpoint, up to a maximum of 16 // watchpoints. The first word contains the address at which the watchpoint // is set (DBGWVRn_EL1), the second word is the control register for the diff --git a/pkg/proc/scope_test.go b/pkg/proc/scope_test.go index f95a3711..a477281e 100644 --- a/pkg/proc/scope_test.go +++ b/pkg/proc/scope_test.go @@ -42,26 +42,26 @@ func TestScopeWithEscapedVariable(t *testing.T) { } // TestScope will: -// - run _fixtures/scopetest.go -// - set a breakpoint on all lines containing a comment -// - continue until the program ends -// - every time a breakpoint is hit it will check that -// scope.FunctionArguments+scope.LocalVariables and scope.EvalExpression -// return what the corresponding comment describes they should return and -// removes the breakpoint. +// - run _fixtures/scopetest.go +// - set a breakpoint on all lines containing a comment +// - continue until the program ends +// - every time a breakpoint is hit it will check that +// scope.FunctionArguments+scope.LocalVariables and scope.EvalExpression +// return what the corresponding comment describes they should return and +// removes the breakpoint. // // Each comment is a comma separated list of variable declarations, with // each variable declaration having the following format: // -// name type = initialvalue +// name type = initialvalue // // the = and the initial value are optional and can only be specified if the // type is an integer type, float32, float64 or bool. // // If multiple variables with the same name are specified: -// 1. LocalVariables+FunctionArguments should return them in the same order and -// every variable except the last one should be marked as shadowed -// 2. EvalExpression should return the last one. +// 1. LocalVariables+FunctionArguments should return them in the same order and +// every variable except the last one should be marked as shadowed +// 2. EvalExpression should return the last one. func TestScope(t *testing.T) { if ver, _ := goversion.Parse(runtime.Version()); ver.Major >= 0 && !ver.AfterOrEqual(goversion.GoVersion{Major: 1, Minor: 9, Rev: -1}) { return diff --git a/pkg/proc/target_exec.go b/pkg/proc/target_exec.go index 9f3b1e6b..e5bd28aa 100644 --- a/pkg/proc/target_exec.go +++ b/pkg/proc/target_exec.go @@ -221,9 +221,9 @@ func conditionErrors(threads []Thread) error { } // pick a new dbp.currentThread, with the following priority: -// - a thread with an active stepping breakpoint -// - a thread with an active breakpoint, prioritizing trapthread -// - trapthread +// - a thread with an active stepping breakpoint +// - a thread with an active breakpoint, prioritizing trapthread +// - trapthread func pickCurrentThread(dbp *Target, trapthread Thread, threads []Thread) error { for _, th := range threads { if bp := th.Breakpoint(); bp.Active && bp.Stepping { @@ -445,14 +445,14 @@ func (dbp *Target) StepInstruction() (err error) { // once the CALL is reached. // // Regardless of stepInto the following breakpoints will be set: -// - a breakpoint on the first deferred function with NextDeferBreakpoint -// kind, the list of all the addresses to deferreturn calls in this function -// and condition checking that we remain on the same goroutine -// - a breakpoint on each line of the function, with a condition checking -// that we stay on the same stack frame and goroutine. -// - a breakpoint on the return address of the function, with a condition -// checking that we move to the previous stack frame and stay on the same -// goroutine. +// - a breakpoint on the first deferred function with NextDeferBreakpoint +// kind, the list of all the addresses to deferreturn calls in this function +// and condition checking that we remain on the same goroutine +// - a breakpoint on each line of the function, with a condition checking +// that we stay on the same stack frame and goroutine. +// - a breakpoint on the return address of the function, with a condition +// checking that we move to the previous stack frame and stay on the same +// goroutine. // // The breakpoint on the return address is *not* set if the current frame is // an inlined call. For inlined calls topframe.Current.Fn is the function @@ -957,12 +957,13 @@ func findCallInstrForRet(p Process, mem MemoryReadWriter, ret uint64, fn *Functi } // stepOutReverse sets a breakpoint on the CALL instruction that created the current frame, this is either: -// - the CALL instruction immediately preceding the return address of the -// current frame -// - the return address of the current frame if the current frame was -// created by a runtime.deferreturn run -// - the return address of the runtime.gopanic frame if the current frame -// was created by a panic +// - the CALL instruction immediately preceding the return address of the +// current frame +// - the return address of the current frame if the current frame was +// created by a runtime.deferreturn run +// - the return address of the runtime.gopanic frame if the current frame +// was created by a panic +// // This function is used to implement reversed StepOut func stepOutReverse(p *Target, topframe, retframe Stackframe, sameGCond ast.Expr) error { curthread := p.CurrentThread() diff --git a/pkg/proc/test/support.go b/pkg/proc/test/support.go index e56b9075..71cf4452 100644 --- a/pkg/proc/test/support.go +++ b/pkg/proc/test/support.go @@ -263,20 +263,20 @@ func AllowRecording(t testing.TB) { // MustHaveRecordingAllowed skips this test if recording is not allowed // // Not all the tests can be run with a recording: -// - some fixtures never terminate independently (loopprog, -// testnextnethttp) and can not be recorded -// - some tests assume they can interact with the target process (for -// example TestIssue419, or anything changing the value of a variable), -// which we can't do on with a recording -// - some tests assume that the Pid returned by the process is valid, but -// it won't be at replay time -// - some tests will start the fixture but not never execute a single -// instruction, for some reason rr doesn't like this and will print an -// error if it happens -// - many tests will assume that we can return from a runtime.Breakpoint, -// with a recording this is not possible because when the fixture ran it -// wasn't attached to a debugger and in those circumstances a -// runtime.Breakpoint leads directly to a crash +// - some fixtures never terminate independently (loopprog, +// testnextnethttp) and can not be recorded +// - some tests assume they can interact with the target process (for +// example TestIssue419, or anything changing the value of a variable), +// which we can't do on with a recording +// - some tests assume that the Pid returned by the process is valid, but +// it won't be at replay time +// - some tests will start the fixture but not never execute a single +// instruction, for some reason rr doesn't like this and will print an +// error if it happens +// - many tests will assume that we can return from a runtime.Breakpoint, +// with a recording this is not possible because when the fixture ran it +// wasn't attached to a debugger and in those circumstances a +// runtime.Breakpoint leads directly to a crash // // Some of the tests using runtime.Breakpoint (anything involving variable // evaluation and TestWorkDir) have been adapted to work with a recording. diff --git a/pkg/proc/types.go b/pkg/proc/types.go index b52914ac..1cc1d6be 100644 --- a/pkg/proc/types.go +++ b/pkg/proc/types.go @@ -112,13 +112,13 @@ func (ctxt *loadDebugInfoMapsContext) lookupAbstractOrigin(bi *BinaryInfo, off d // runtimeTypeToDIE returns the DIE corresponding to the runtime._type. // This is done in three different ways depending on the version of go. -// * Before go1.7 the type name is retrieved directly from the runtime._type -// and looked up in debug_info -// * After go1.7 the runtime._type struct is read recursively to reconstruct -// the name of the type, and then the type's name is used to look up -// debug_info -// * After go1.11 the runtimeTypeToDIE map is used to look up the address of -// the type and map it drectly to a DIE. +// - Before go1.7 the type name is retrieved directly from the runtime._type +// and looked up in debug_info +// - After go1.7 the runtime._type struct is read recursively to reconstruct +// the name of the type, and then the type's name is used to look up +// debug_info +// - After go1.11 the runtimeTypeToDIE map is used to look up the address of +// the type and map it drectly to a DIE. func runtimeTypeToDIE(_type *Variable, dataAddr uint64) (typ godwarf.Type, kind int64, err error) { bi := _type.bi diff --git a/service/dap/server.go b/service/dap/server.go index f091fc2f..640e2950 100644 --- a/service/dap/server.go +++ b/service/dap/server.go @@ -1705,10 +1705,11 @@ func (s *Session) onThreadsRequest(request *dap.ThreadsRequest) { // onAttachRequest handles 'attach' request. // This is a mandatory request to support. // Attach debug sessions support the following modes: -// -- [DEFAULT] "local" -- attaches debugger to a local running process -// Required args: processID -// -- "remote" - attaches client to a debugger already attached to a process -// Required args: none (host/port are used externally to connect) +// +// - [DEFAULT] "local" -- attaches debugger to a local running process. +// Required args: processID +// - "remote" -- attaches client to a debugger already attached to a process. +// Required args: none (host/port are used externally to connect) func (s *Session) onAttachRequest(request *dap.AttachRequest) { var args AttachConfig = defaultAttachConfig // narrow copy for initializing non-zero default values if err := unmarshalLaunchAttachArgs(request.Arguments, &args); err != nil { @@ -2591,12 +2592,15 @@ func (s *Session) convertVariableWithOpts(v *proc.Variable, qualifiedNameOrExpr // onEvaluateRequest handles 'evalute' requests. // This is a mandatory request to support. // Support the following expressions: -// -- {expression} - evaluates the expression and returns the result as a variable -// -- call {function} - injects a function call and returns the result as a variable -// -- config {expression} - updates configuration parameters +// +// - {expression} - evaluates the expression and returns the result as a variable +// - call {function} - injects a function call and returns the result as a variable +// - config {expression} - updates configuration parameters +// // TODO(polina): users have complained about having to click to expand multi-level // variables, so consider also adding the following: -// -- print {expression} - return the result as a string like from dlv cli +// +// - print {expression} - return the result as a string like from dlv cli func (s *Session) onEvaluateRequest(request *dap.EvaluateRequest) { showErrorToUser := request.Arguments.Context != "watch" && request.Arguments.Context != "repl" && request.Arguments.Context != "hover" if s.debugger == nil { @@ -3301,7 +3305,8 @@ func (s *Session) getExprString(expr string, goroutineID, frame int) (string, er } // sendErrorResponseWithOpts offers configuration options. -// showUser - if true, the error will be shown to the user (e.g. via a visible pop-up) +// +// showUser - if true, the error will be shown to the user (e.g. via a visible pop-up) func (s *Session) sendErrorResponseWithOpts(request dap.Request, id int, summary, details string, showUser bool) { er := &dap.ErrorResponse{} er.Type = "response" @@ -3706,7 +3711,8 @@ type logMessage struct { } // parseLogPoint parses a log message according to the DAP spec: -// "Expressions within {} are interpolated." +// +// "Expressions within {} are interpolated." func parseLogPoint(msg string) (bool, *logMessage, error) { // Note: All braces *must* come in pairs, even those within an // expression to be interpolated. diff --git a/service/dap/server_test.go b/service/dap/server_test.go index e610f67b..2216bb03 100644 --- a/service/dap/server_test.go +++ b/service/dap/server_test.go @@ -321,37 +321,39 @@ func TestForceStopWhileStopping(t *testing.T) { // TestLaunchStopOnEntry emulates the message exchange that can be observed with // VS Code for the most basic launch debug session with "stopOnEntry" enabled: -// - User selects "Start Debugging": 1 >> initialize -// : 1 << initialize -// : 2 >> launch -// : << initialized event -// : 2 << launch -// : 3 >> setBreakpoints (empty) -// : 3 << setBreakpoints -// : 4 >> setExceptionBreakpoints (empty) -// : 4 << setExceptionBreakpoints -// : 5 >> configurationDone -// - Program stops upon launching : << stopped event -// : 5 << configurationDone -// : 6 >> threads -// : 6 << threads (Dummy) -// : 7 >> threads -// : 7 << threads (Dummy) -// : 8 >> stackTrace -// : 8 << error (Unable to produce stack trace) -// : 9 >> stackTrace -// : 9 << error (Unable to produce stack trace) -// - User evaluates bad expression : 10 >> evaluate -// : 10 << error (unable to find function context) -// - User evaluates good expression: 11 >> evaluate -// : 11 << evaluate -// - User selects "Continue" : 12 >> continue -// : 12 << continue -// - Program runs to completion : << terminated event -// : 13 >> disconnect -// : << output event (Process exited) -// : << output event (Detaching) -// : 13 << disconnect +// +// User selects "Start Debugging": 1 >> initialize +// : 1 << initialize +// : 2 >> launch +// : << initialized event +// : 2 << launch +// : 3 >> setBreakpoints (empty) +// : 3 << setBreakpoints +// : 4 >> setExceptionBreakpoints (empty) +// : 4 << setExceptionBreakpoints +// : 5 >> configurationDone +// Program stops upon launching : << stopped event +// : 5 << configurationDone +// : 6 >> threads +// : 6 << threads (Dummy) +// : 7 >> threads +// : 7 << threads (Dummy) +// : 8 >> stackTrace +// : 8 << error (Unable to produce stack trace) +// : 9 >> stackTrace +// : 9 << error (Unable to produce stack trace) +// User evaluates bad expression : 10 >> evaluate +// : 10 << error (unable to find function context) +// User evaluates good expression: 11 >> evaluate +// : 11 << evaluate +// User selects "Continue" : 12 >> continue +// : 12 << continue +// Program runs to completion : << terminated event +// : 13 >> disconnect +// : << output event (Process exited) +// : << output event (Detaching) +// : 13 << disconnect +// // This test exhaustively tests Seq and RequestSeq on all messages from the // server. Other tests do not necessarily need to repeat all these checks. func TestLaunchStopOnEntry(t *testing.T) { @@ -801,11 +803,12 @@ func TestPreSetBreakpoint(t *testing.T) { } // checkStackFramesExact is a helper for verifying the values within StackTraceResponse. -// wantStartName - name of the first returned frame (ignored if "") -// wantStartLine - file line of the first returned frame (ignored if <0). -// wantStartID - id of the first frame returned (ignored if wantFrames is 0). -// wantFrames - number of frames returned (length of StackTraceResponse.Body.StackFrames array). -// wantTotalFrames - total number of stack frames available (StackTraceResponse.Body.TotalFrames). +// +// wantStartName - name of the first returned frame (ignored if "") +// wantStartLine - file line of the first returned frame (ignored if <0). +// wantStartID - id of the first frame returned (ignored if wantFrames is 0). +// wantFrames - number of frames returned (length of StackTraceResponse.Body.StackFrames array). +// wantTotalFrames - total number of stack frames available (StackTraceResponse.Body.TotalFrames). func checkStackFramesExact(t *testing.T, got *dap.StackTraceResponse, wantStartName string, wantStartLine, wantStartID, wantFrames, wantTotalFrames int) { t.Helper() @@ -956,9 +959,10 @@ func checkStackFramesNamed(testName string, t *testing.T, got *dap.StackTraceRes } // checkScope is a helper for verifying the values within a ScopesResponse. -// i - index of the scope within ScopesRespose.Body.Scopes array -// name - name of the scope -// varRef - reference to retrieve variables of this scope. If varRef is negative, the reference is not checked. +// +// i - index of the scope within ScopesRespose.Body.Scopes array +// name - name of the scope +// varRef - reference to retrieve variables of this scope. If varRef is negative, the reference is not checked. func checkScope(t *testing.T, got *dap.ScopesResponse, i int, name string, varRef int) { t.Helper() if len(got.Body.Scopes) <= i { @@ -971,8 +975,9 @@ func checkScope(t *testing.T, got *dap.ScopesResponse, i int, name string, varRe } // checkChildren is a helper for verifying the number of variables within a VariablesResponse. -// parentName - pseudoname of the enclosing variable or scope (used for error message only) -// numChildren - number of variables/fields/elements of this variable +// +// parentName - pseudoname of the enclosing variable or scope (used for error message only) +// numChildren - number of variables/fields/elements of this variable func checkChildren(t *testing.T, got *dap.VariablesResponse, parentName string, numChildren int) { t.Helper() if got.Body.Variables == nil { @@ -984,13 +989,14 @@ func checkChildren(t *testing.T, got *dap.VariablesResponse, parentName string, } // checkVar is a helper for verifying the values within a VariablesResponse. -// i - index of the variable within VariablesRespose.Body.Variables array (-1 will search all vars for a match) -// name - name of the variable -// evalName - fully qualified variable name or alternative expression to load this variable -// value - the value of the variable -// useExactMatch - true if name, evalName and value are to be compared to exactly, false if to be used as regex -// hasRef - true if the variable should have children and therefore a non-0 variable reference -// ref - reference to retrieve children of this variable (0 if none) +// +// i - index of the variable within VariablesRespose.Body.Variables array (-1 will search all vars for a match) +// name - name of the variable +// evalName - fully qualified variable name or alternative expression to load this variable +// value - the value of the variable +// useExactMatch - true if name, evalName and value are to be compared to exactly, false if to be used as regex +// hasRef - true if the variable should have children and therefore a non-0 variable reference +// ref - reference to retrieve children of this variable (0 if none) func checkVar(t *testing.T, got *dap.VariablesResponse, i int, name, evalName, value, typ string, useExactMatch, hasRef bool, indexed, named int) (ref int) { t.Helper() if len(got.Body.Variables) <= i { @@ -3756,9 +3762,10 @@ func TestWorkingDir(t *testing.T) { } // checkEval is a helper for verifying the values within an EvaluateResponse. -// value - the value of the evaluated expression -// hasRef - true if the evaluated expression should have children and therefore a non-0 variable reference -// ref - reference to retrieve children of this evaluated expression (0 if none) +// +// value - the value of the evaluated expression +// hasRef - true if the evaluated expression should have children and therefore a non-0 variable reference +// ref - reference to retrieve children of this evaluated expression (0 if none) func checkEval(t *testing.T, got *dap.EvaluateResponse, value string, hasRef bool) (ref int) { t.Helper() if got.Body.Result != value || (got.Body.VariablesReference > 0) != hasRef { @@ -3768,9 +3775,10 @@ func checkEval(t *testing.T, got *dap.EvaluateResponse, value string, hasRef boo } // checkEvalIndexed is a helper for verifying the values within an EvaluateResponse. -// value - the value of the evaluated expression -// hasRef - true if the evaluated expression should have children and therefore a non-0 variable reference -// ref - reference to retrieve children of this evaluated expression (0 if none) +// +// value - the value of the evaluated expression +// hasRef - true if the evaluated expression should have children and therefore a non-0 variable reference +// ref - reference to retrieve children of this evaluated expression (0 if none) func checkEvalIndexed(t *testing.T, got *dap.EvaluateResponse, value string, hasRef bool, indexed, named int) (ref int) { t.Helper() if got.Body.Result != value || (got.Body.VariablesReference > 0) != hasRef || got.Body.IndexedVariables != indexed || got.Body.NamedVariables != named { @@ -5089,14 +5097,15 @@ type onBreakpoint struct { // runDebugSessionWithBPs is a helper for executing the common init and shutdown // sequences for a program that does not stop on entry // while specifying breakpoints and unique launch/attach criteria via parameters. -// cmd - "launch" or "attach" -// cmdRequest - a function that sends a launch or attach request, -// so the test author has full control of its arguments. -// Note that he rest of the test sequence assumes that -// stopOnEntry is false. -// source - source file path, needed to set breakpoints, "" if none to be set. -// breakpoints - list of lines, where breakpoints are to be set -// onBPs - list of test sequences to execute at each of the set breakpoints. +// +// cmd - "launch" or "attach" +// cmdRequest - a function that sends a launch or attach request, +// so the test author has full control of its arguments. +// Note that he rest of the test sequence assumes that +// stopOnEntry is false. +// source - source file path, needed to set breakpoints, "" if none to be set. +// breakpoints - list of lines, where breakpoints are to be set +// onBPs - list of test sequences to execute at each of the set breakpoints. func runDebugSessionWithBPs(t *testing.T, client *daptest.Client, cmd string, cmdRequest func(), source string, breakpoints []int, onBPs []onBreakpoint) { client.InitializeRequest() client.ExpectInitializeResponseAndCapabilities(t) diff --git a/service/dap/types.go b/service/dap/types.go index e078b500..27978f43 100644 --- a/service/dap/types.go +++ b/service/dap/types.go @@ -7,22 +7,32 @@ import ( ) // Launch debug sessions support the following modes: -// -- [DEFAULT] "debug" - builds and launches debugger for specified program (similar to 'dlv debug') -// Required args: program -// Optional args with default: output, cwd, noDebug -// Optional args: buildFlags, args -// -- "test" - builds and launches debugger for specified test (similar to 'dlv test') -// same args as above -// -- "exec" - launches debugger for precompiled binary (similar to 'dlv exec') -// Required args: program -// Optional args with default: cwd, noDebug -// Optional args: args -// -- "replay" - replays a trace generated by mozilla rr. Mozilla rr must be installed. -// Required args: traceDirPath -// Optional args: args -// -- "core" - examines a core dump (only supports linux and windows core dumps). -// Required args: program, coreFilePath -// Optional args: args +// +// -- [DEFAULT] "debug" - builds and launches debugger for specified program (similar to 'dlv debug') +// +// Required args: program +// Optional args with default: output, cwd, noDebug +// Optional args: buildFlags, args +// +// -- "test" - builds and launches debugger for specified test (similar to 'dlv test') +// +// same args as above +// +// -- "exec" - launches debugger for precompiled binary (similar to 'dlv exec') +// +// Required args: program +// Optional args with default: cwd, noDebug +// Optional args: args +// +// -- "replay" - replays a trace generated by mozilla rr. Mozilla rr must be installed. +// +// Required args: traceDirPath +// Optional args: args +// +// -- "core" - examines a core dump (only supports linux and windows core dumps). +// +// Required args: program, coreFilePath +// Optional args: args // // TODO(hyangah): change this to 'validateLaunchMode' that checks // all the required/optional fields mentioned above. diff --git a/service/rpc2/server.go b/service/rpc2/server.go index ae642fbe..fc97c0a6 100644 --- a/service/rpc2/server.go +++ b/service/rpc2/server.go @@ -632,15 +632,21 @@ type ListGoroutinesOut struct { // If arg.Filters are specified the list of returned goroutines is filtered // applying the specified filters. // For example: -// ListGoroutinesFilter{ Kind: ListGoroutinesFilterUserLoc, Negated: false, Arg: "afile.go" } +// +// ListGoroutinesFilter{ Kind: ListGoroutinesFilterUserLoc, Negated: false, Arg: "afile.go" } +// // will only return goroutines whose UserLoc contains "afile.go" as a substring. // More specifically a goroutine matches a location filter if the specified // location, formatted like this: -// filename:lineno in function +// +// filename:lineno in function +// // contains Arg[0] as a substring. // // Filters can also be applied to goroutine labels: -// ListGoroutineFilter{ Kind: ListGoroutinesFilterLabel, Negated: false, Arg: "key=value" } +// +// ListGoroutineFilter{ Kind: ListGoroutinesFilterLabel, Negated: false, Arg: "key=value" } +// // this filter will only return goroutines that have a key=value label. // // If arg.GroupBy is not GoroutineFieldNone then the goroutines will @@ -700,15 +706,15 @@ type FindLocationOut struct { // FindLocation returns concrete location information described by a location expression. // -// loc ::= : | [:] | // | (+|-) | | *
-// * can be the full path of a file or just a suffix -// * ::= .. | .(*). | . | . | (*). | -// * must be unambiguous -// * // will return a location for each function matched by regex -// * + returns a location for the line that is lines after the current line -// * - returns a location for the line that is lines before the current line -// * returns a location for a line in the current file -// * *
returns the location corresponding to the specified address +// loc ::= : | [:] | // | (+|-) | | *
+// * can be the full path of a file or just a suffix +// * ::= .. | .(*). | . | . | (*). | +// must be unambiguous +// * // will return a location for each function matched by regex +// * + returns a location for the line that is lines after the current line +// * - returns a location for the line that is lines before the current line +// * returns a location for a line in the current file +// * *
returns the location corresponding to the specified address // // NOTE: this function does not actually set breakpoints. func (c *RPCServer) FindLocation(arg FindLocationIn, out *FindLocationOut) error { diff --git a/service/rpccommon/server.go b/service/rpccommon/server.go index 328885fc..a6889417 100644 --- a/service/rpccommon/server.go +++ b/service/rpccommon/server.go @@ -213,8 +213,9 @@ func isExportedOrBuiltinType(t reflect.Type) bool { // available through the RPC interface. // These are all the public methods of rcvr that have one of those // two signatures: -// func (rcvr ReceiverType) Method(in InputType, out *ReplyType) error -// func (rcvr ReceiverType) Method(in InputType, cb service.RPCCallback) +// +// func (rcvr ReceiverType) Method(in InputType, out *ReplyType) error +// func (rcvr ReceiverType) Method(in InputType, cb service.RPCCallback) func suitableMethods(rcvr interface{}, methods map[string]*methodType, log *logrus.Entry) { typ := reflect.TypeOf(rcvr) rcvrv := reflect.ValueOf(rcvr)