Repository: go-delve/delve
Pull request #3408 (2023-06-08 22:06:57)

pkg/proc: enable basic debug functionality for stripped ELF binaries
We used to parse the .gopclntab section but removed support in favor of
simply using DWARF debug information, due to lack of C symbols among
other reasons. This makes it impossible to debug stripped binaries,
which some distrubutions ship by default.

Add back in basic support for .gopclntab which survives if the binary
is stripped, allowing for rudimentary debugging such as basic
program navigation, tracing, etc...


Patch:
diff --git a/.teamcity/settings.kts b/.teamcity/settings.kts
index d1b912db..3ef170be 100644
--- a/.teamcity/settings.kts
+++ b/.teamcity/settings.kts
@@ -198,7 +198,7 @@ class TestBuild(val os: String, val arch: String, version: String, buildId: Abso
                         --env TEAMCITY_VERSION=${'$'}TEAMCITY_VERSION
                         --env CI=true
                         --privileged
-                        --platform linux/$dockerArch
+                        --platform linux/$dockerPlatformArch
                         $dockerArch/ubuntu:20.04
                         /delve/_scripts/test_linux.sh ${"go$version"} $arch
                     """.trimIndent()
diff --git a/_scripts/gen-starlark-bindings.go b/_scripts/gen-starlark-bindings.go
index 25d4c8d5..7c24e235 100644
--- a/_scripts/gen-starlark-bindings.go
+++ b/_scripts/gen-starlark-bindings.go
@@ -3,6 +3,7 @@ package main
 import (
 	"bytes"
 	"fmt"
+	"go/ast"
 	"go/format"
 	"go/token"
 	"go/types"
@@ -99,9 +100,11 @@ type binding struct {
 
 	argNames []string
 	argTypes []string
+
+	docStr string
 }
 
-func processServerMethods(serverMethods []*types.Func) []binding {
+func processServerMethods(serverMethods []*types.Func, funcDeclByPos map[token.Pos]*ast.FuncDecl) []binding {
 	bindings := make([]binding, len(serverMethods))
 	for i, fn := range serverMethods {
 		sig, _ := fn.Type().(*types.Signature)
@@ -133,6 +136,22 @@ func processServerMethods(serverMethods []*types.Func) []binding {
 			retType = "rpc2.StateOut"
 		}
 
+		docStr := ""
+
+		if decl := funcDeclByPos[fn.Pos()]; decl != nil && decl.Doc != nil {
+			docs := []string{}
+			for _, cmnt := range decl.Doc.List {
+				docs = append(docs, strings.TrimPrefix(strings.TrimPrefix(cmnt.Text, "//"), " "))
+			}
+
+			// fix name of the function in the first line of the documentation
+			if fields := strings.SplitN(docs[0], " ", 2); len(fields) == 2 && fields[0] == fn.Name() {
+				docs[0] = name + " " + fields[1]
+			}
+
+			docStr = strings.Join(docs, "\n")
+		}
+
 		bindings[i] = binding{
 			name:     name,
 			fn:       fn,
@@ -140,6 +159,7 @@ func processServerMethods(serverMethods []*types.Func) []binding {
 			retType:  retType,
 			argNames: argNames,
 			argTypes: argTypes,
+			docStr:   docStr,
 		}
 	}
 	return bindings
@@ -159,8 +179,9 @@ func genMapping(bindings []binding) []byte {
 	fmt.Fprintf(buf, "// DO NOT EDIT: auto-generated using _scripts/gen-starlark-bindings.go\n\n")
 	fmt.Fprintf(buf, "package starbind\n\n")
 	fmt.Fprintf(buf, "import ( \"go.starlark.net/starlark\" \n \"github.com/go-delve/delve/service/api\" \n \"github.com/go-delve/delve/service/rpc2\" \n \"fmt\" )\n\n")
-	fmt.Fprintf(buf, "func (env *Env) starlarkPredeclare() starlark.StringDict {\n")
-	fmt.Fprintf(buf, "r := starlark.StringDict{}\n\n")
+	fmt.Fprintf(buf, "func (env *Env) starlarkPredeclare() (starlark.StringDict, map[string]string) {\n")
+	fmt.Fprintf(buf, "r := starlark.StringDict{}\n")
+	fmt.Fprintf(buf, "doc := make(map[string]string)\n\n")
 
 	for _, binding := range bindings {
 		fmt.Fprintf(buf, "r[%q] = starlark.NewBuiltin(%q, func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {", binding.name, binding.name)
@@ -209,9 +230,24 @@ func genMapping(bindings []binding) []byte {
 		fmt.Fprintf(buf, "return env.interfaceToStarlarkValue(rpcRet), nil\n")
 
 		fmt.Fprintf(buf, "})\n")
+
+		// builtin documentation
+		docstr := new(strings.Builder)
+		fmt.Fprintf(docstr, "builtin %s(", binding.name)
+		for i, argname := range binding.argNames {
+			if i != 0 {
+				fmt.Fprintf(docstr, ", ")
+			}
+			fmt.Fprintf(docstr, argname)
+		}
+		fmt.Fprintf(docstr, ")")
+		if binding.docStr != "" {
+			fmt.Fprintf(docstr, "\n\n%s", binding.docStr)
+		}
+		fmt.Fprintf(buf, "doc[%q] = %q\n", binding.name, docstr.String())
 	}
 
-	fmt.Fprintf(buf, "return r\n")
+	fmt.Fprintf(buf, "return r, doc\n")
 	fmt.Fprintf(buf, "}\n")
 
 	return buf.Bytes()
@@ -301,14 +337,23 @@ func main() {
 	}
 
 	var serverMethods []*types.Func
+	funcDeclByPos := make(map[token.Pos]*ast.FuncDecl)
 	packages.Visit(pkgs, func(pkg *packages.Package) bool {
 		if pkg.PkgPath == "github.com/go-delve/delve/service/rpc2" {
 			serverMethods = getSuitableMethods(pkg.Types, "RPCServer")
 		}
+		for _, file := range pkg.Syntax {
+			ast.Inspect(file, func(n ast.Node) bool {
+				if n, ok := n.(*ast.FuncDecl); ok {
+					funcDeclByPos[n.Name.Pos()] = n
+				}
+				return true
+			})
+		}
 		return true
 	}, nil)
 
-	bindings := processServerMethods(serverMethods)
+	bindings := processServerMethods(serverMethods, funcDeclByPos)
 
 	switch kind {
 	case "go":
diff --git a/go.mod b/go.mod
index 2be8c4d5..9385f2d4 100644
--- a/go.mod
+++ b/go.mod
@@ -8,7 +8,7 @@ require (
 	github.com/creack/pty v1.1.9
 	github.com/derekparker/trie v0.0.0-20221213183930-4c74548207f4
 	github.com/go-delve/liner v1.2.3-0.20220127212407-d32d89dd2a5d
-	github.com/google/go-dap v0.7.0
+	github.com/google/go-dap v0.9.1
 	github.com/hashicorp/golang-lru v0.5.4
 	github.com/mattn/go-colorable v0.0.9
 	github.com/mattn/go-isatty v0.0.3
diff --git a/go.sum b/go.sum
index af05495e..9cf8af0c 100644
--- a/go.sum
+++ b/go.sum
@@ -89,8 +89,8 @@ github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
 github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M=
 github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
-github.com/google/go-dap v0.7.0 h1:088PdKBUkxAxrXrnY8FREUJXpS6Y6jhAyZIuJv3OGOM=
-github.com/google/go-dap v0.7.0/go.mod h1:5q8aYQFnHOAZEMP+6vmq25HKYAEwE+LF5yh7JKrrhSQ=
+github.com/google/go-dap v0.9.1 h1:d8dETjgHMR9/xs+Xza+NrZmB7jxIS5OtM2uRsyJVA/c=
+github.com/google/go-dap v0.9.1/go.mod h1:HAeyoSd2WIfTfg+0GRXcFrb+RnojAtGNh+k+XTIxJDE=
 github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
 github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
 github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
diff --git a/pkg/proc/bininfo.go b/pkg/proc/bininfo.go
index 4cd41dc4..3deafc67 100644
--- a/pkg/proc/bininfo.go
+++ b/pkg/proc/bininfo.go
@@ -4,6 +4,7 @@ import (
 	"bytes"
 	"debug/dwarf"
 	"debug/elf"
+	"debug/gosym"
 	"debug/macho"
 	"debug/pe"
 	"encoding/binary"
@@ -332,7 +333,7 @@ func FindFunctionLocation(p Process, funcName string, lineOffset int) ([]uint64,
 
 	if lineOffset > 0 {
 		fn := origfns[0]
-		filename, lineno := fn.cu.lineInfo.PCToLine(fn.Entry, fn.Entry)
+		filename, lineno := bi.EntryLineForFunc(fn)
 		return FindFileLocation(p, filename, lineno+lineOffset)
 	}
 
@@ -364,14 +365,16 @@ func FindFunctionLocation(p Process, funcName string, lineOffset int) ([]uint64,
 // If sameline is set FirstPCAfterPrologue will always return an
 // address associated with the same line as fn.Entry.
 func FirstPCAfterPrologue(p Process, fn *Function, sameline bool) (uint64, error) {
-	pc, _, line, ok := fn.cu.lineInfo.PrologueEndPC(fn.Entry, fn.End)
-	if ok {
-		if !sameline {
-			return pc, nil
-		}
-		_, entryLine := fn.cu.lineInfo.PCToLine(fn.Entry, fn.Entry)
-		if entryLine == line {
-			return pc, nil
+	if fn.cu.lineInfo != nil {
+		pc, _, line, ok := fn.cu.lineInfo.PrologueEndPC(fn.Entry, fn.End)
+		if ok {
+			if !sameline {
+				return pc, nil
+			}
+			_, entryLine := p.BinInfo().EntryLineForFunc(fn)
+			if entryLine == line {
+				return pc, nil
+			}
 		}
 	}
 
@@ -380,7 +383,7 @@ func FirstPCAfterPrologue(p Process, fn *Function, sameline bool) (uint64, error
 		return fn.Entry, err
 	}
 
-	if pc == fn.Entry {
+	if pc == fn.Entry && fn.cu.lineInfo != nil {
 		// Look for the first instruction with the stmt flag set, so that setting a
 		// breakpoint with file:line and with the function name always result on
 		// the same instruction being selected.
@@ -601,6 +604,25 @@ func (fn *Function) PrologueEndPC() uint64 {
 	return pc
 }
 
+func (fn *Function) AllPCs(excludeFile string, excludeLine int) ([]uint64, error) {
+	if !fn.cu.image.Stripped() {
+		return fn.cu.lineInfo.AllPCsBetween(fn.Entry, fn.End-1, excludeFile, excludeLine)
+	}
+	var pcs []uint64
+	fnFile, lastLine, _ := fn.cu.image.symTable.PCToLine(fn.Entry)
+	for pc := fn.Entry; pc < fn.End; pc++ {
+		f, line, pcfn := fn.cu.image.symTable.PCToLine(pc)
+		if pcfn == nil {
+			continue
+		}
+		if f == fnFile && line > lastLine {
+			lastLine = line
+			pcs = append(pcs, pc)
+		}
+	}
+	return pcs, nil
+}
+
 // From $GOROOT/src/runtime/traceback.go:597
 // exportedRuntime reports whether the function is an exported runtime function.
 // It is only for runtime functions, so ASCII A-Z is fine.
@@ -719,6 +741,9 @@ func (bi *BinaryInfo) LastModified() time.Time {
 
 // DwarfReader returns a reader for the dwarf data
 func (so *Image) DwarfReader() *reader.Reader {
+	if so.dwarf == nil {
+		return nil
+	}
 	return reader.New(so.dwarf)
 }
 
@@ -731,13 +756,26 @@ func (bi *BinaryInfo) Types() ([]string, error) {
 	return types, nil
 }
 
+func (bi *BinaryInfo) EntryLineForFunc(fn *Function) (string, int) {
+	return bi.pcToLine(fn, fn.Entry)
+}
+
+func (bi *BinaryInfo) pcToLine(fn *Function, pc uint64) (string, int) {
+	if fn.cu.lineInfo == nil {
+		f, l, _ := fn.cu.image.symTable.PCToLine(pc)
+		return f, l
+	}
+	f, l := fn.cu.lineInfo.PCToLine(fn.Entry, pc)
+	return f, l
+}
+
 // PCToLine converts an instruction address to a file/line/function.
 func (bi *BinaryInfo) PCToLine(pc uint64) (string, int, *Function) {
 	fn := bi.PCToFunc(pc)
 	if fn == nil {
 		return "", 0, nil
 	}
-	f, ln := fn.cu.lineInfo.PCToLine(fn.Entry, pc)
+	f, ln := bi.pcToLine(fn, pc)
 	return f, ln, fn
 }
 
@@ -810,6 +848,8 @@ type Image struct {
 	debugAddr    *godwarf.DebugAddrSection
 	debugLineStr []byte
 
+	symTable *gosym.Table
+
 	typeCache map[dwarf.Offset]godwarf.Type
 
 	compileUnits []*compileUnit // compileUnits is sorted by increasing DWARF offset
@@ -835,6 +875,10 @@ func (image *Image) registerRuntimeTypeToDIE(entry *dwarf.Entry, ardr *reader.Re
 	}
 }
 
+func (image *Image) Stripped() bool {
+	return image.dwarf == nil
+}
+
 // AddImage adds the specified image to bi, loading data asynchronously.
 // Addr is the relocated entry point for the executable and staticBase (i.e.
 // the relocation offset) for all other images.
@@ -1405,7 +1449,22 @@ func loadBinaryInfoElf(bi *BinaryInfo, image *Image, path string, addr uint64, w
 		var serr error
 		sepFile, dwarfFile, serr = bi.openSeparateDebugInfo(image, elfFile, bi.DebugInfoDirectories)
 		if serr != nil {
-			return serr
+			fmt.Fprintln(os.Stderr, "Warning: no debug info found, some functionality will be missing such as stack traces and variable evaluation.")
+			symTable, err := readPcLnTableElf(elfFile, path)
+			if err != nil {
+				return fmt.Errorf("could not create symbol table from  %s ", path)
+			}
+			image.symTable = symTable
+			for _, f := range image.symTable.Funcs {
+				cu := &compileUnit{}
+				cu.image = image
+				fn := Function{Name: f.Name, Entry: f.Entry, End: f.End, cu: cu}
+				bi.Functions = append(bi.Functions, fn)
+			}
+			for f := range image.symTable.Files {
+				bi.Sources = append(bi.Sources, f)
+			}
+			return nil
 		}
 		image.sepDebugCloser = sepFile
 		image.dwarf, err = dwarfFile.DWARF()
diff --git a/pkg/proc/breakpoints.go b/pkg/proc/breakpoints.go
index 2e7cdf72..c5910e31 100644
--- a/pkg/proc/breakpoints.go
+++ b/pkg/proc/breakpoints.go
@@ -554,7 +554,7 @@ func (t *Target) setEBPFTracepointOnFunc(fn *Function, goidOffset int64) error {
 	if t.BinInfo().Producer() != "" && goversion.ProducerAfterOrEqual(t.BinInfo().Producer(), 1, 15) {
 		variablesFlags |= reader.VariablesTrustDeclLine
 	}
-	_, l, _ := t.BinInfo().PCToLine(fn.Entry)
+	_, l := t.BinInfo().EntryLineForFunc(fn)
 
 	var args []ebpf.UProbeArgMap
 	varEntries := reader.Variables(dwarfTree, fn.Entry, l, variablesFlags)
diff --git a/pkg/proc/fncall.go b/pkg/proc/fncall.go
index bd0df515..a1b94a72 100644
--- a/pkg/proc/fncall.go
+++ b/pkg/proc/fncall.go
@@ -1053,7 +1053,7 @@ func readStackVariable(t *Target, thread Thread, regs Registers, off uint64, typ
 func fakeFunctionEntryScope(scope *EvalScope, fn *Function, cfa int64, sp uint64) error {
 	scope.PC = fn.Entry
 	scope.Fn = fn
-	scope.File, scope.Line, _ = scope.BinInfo.PCToLine(fn.Entry)
+	scope.File, scope.Line = scope.BinInfo.EntryLineForFunc(fn)
 
 	scope.Regs.CFA = cfa
 	scope.Regs.Reg(scope.Regs.SPRegNum).Uint64Val = sp
diff --git a/pkg/proc/goroutine_cache.go b/pkg/proc/goroutine_cache.go
index 70e7f61c..4020dad0 100644
--- a/pkg/proc/goroutine_cache.go
+++ b/pkg/proc/goroutine_cache.go
@@ -12,6 +12,9 @@ func (gcache *goroutineCache) init(bi *BinaryInfo) {
 
 	exeimage := bi.Images[0]
 	rdr := exeimage.DwarfReader()
+	if rdr == nil {
+		return
+	}
 
 	gcache.allglenAddr, _ = rdr.AddrFor("runtime.allglen", exeimage.StaticBase, bi.Arch.PtrSize())
 
diff --git a/pkg/proc/pclntab.go b/pkg/proc/pclntab.go
new file mode 100644
index 00000000..34515332
--- /dev/null
+++ b/pkg/proc/pclntab.go
@@ -0,0 +1,75 @@
+package proc
+
+import (
+	"bytes"
+	"debug/buildinfo"
+	"debug/elf"
+	"debug/gosym"
+	"encoding/binary"
+	"fmt"
+	"strings"
+)
+
+// From go/src/debug/gosym/pclntab.go
+const (
+	go12magic  = 0xfffffffb
+	go116magic = 0xfffffffa
+	go118magic = 0xfffffff0
+	go120magic = 0xfffffff1
+)
+
+// Select the magic number based on the Go version
+func magicNumber(goVersion string) []byte {
+	bs := make([]byte, 4)
+	var magic uint32
+	if strings.Compare(goVersion, "go1.20") >= 0 {
+		magic = go120magic
+	} else if strings.Compare(goVersion, "go1.18") >= 0 {
+		magic = go118magic
+	} else if strings.Compare(goVersion, "go1.16") >= 0 {
+		magic = go116magic
+	} else {
+		magic = go12magic
+	}
+	binary.LittleEndian.PutUint32(bs, magic)
+	return bs
+}
+
+func readPcLnTableElf(exe *elf.File, path string) (*gosym.Table, error) {
+	// Default section label is .gopclntab
+	sectionLabel := ".gopclntab"
+
+	section := exe.Section(sectionLabel)
+	if section == nil {
+		// binary may be built with -pie
+		sectionLabel = ".data.rel.ro"
+		section = exe.Section(sectionLabel)
+		if section == nil {
+			return nil, fmt.Errorf("could not read section .gopclntab")
+		}
+	}
+	tableData, err := section.Data()
+	if err != nil {
+		return nil, fmt.Errorf("found section but could not read .gopclntab")
+	}
+
+	bi, err := buildinfo.ReadFile(path)
+	if err != nil {
+		return nil, err
+	}
+
+	// Find .gopclntab by magic number even if there is no section label
+	magic := magicNumber(bi.GoVersion)
+	pclntabIndex := bytes.Index(tableData, magic)
+	if pclntabIndex < 0 {
+		return nil, fmt.Errorf("could not find magic number in %s ", path)
+	}
+	tableData = tableData[pclntabIndex:]
+	addr := exe.Section(".text").Addr
+	lineTable := gosym.NewLineTable(tableData, addr)
+	symTable, err := gosym.NewTable([]byte{}, lineTable)
+	if err != nil {
+		return nil, fmt.Errorf("could not create symbol table from  %s ", path)
+	}
+	return symTable, nil
+}
diff --git a/pkg/proc/stack.go b/pkg/proc/stack.go
index 9fdcb93e..d4791df8 100644
--- a/pkg/proc/stack.go
+++ b/pkg/proc/stack.go
@@ -253,6 +253,9 @@ func (it *stackIterator) Err() error {
 // frameBase calculates the frame base pseudo-register for DWARF for fn and
 // the current frame.
 func (it *stackIterator) frameBase(fn *Function) int64 {
+	if fn.cu.image.Stripped() {
+		return 0
+	}
 	dwarfTree, err := fn.cu.image.getDwarfTree(fn.offset)
 	if err != nil {
 		return 0
@@ -695,6 +698,6 @@ func (d *Defer) DeferredFunc(p *Target) (file string, line int, fn *Function) {
 	if fn == nil {
 		return "", 0, nil
 	}
-	file, line = fn.cu.lineInfo.PCToLine(fn.Entry, fn.Entry)
+	file, line = bi.EntryLineForFunc(fn)
 	return file, line, fn
 }
diff --git a/pkg/proc/target_exec.go b/pkg/proc/target_exec.go
index ed9da60e..64734294 100644
--- a/pkg/proc/target_exec.go
+++ b/pkg/proc/target_exec.go
@@ -392,7 +392,7 @@ func stepInstructionOut(dbp *Target, curthread Thread, fnname1, fnname2 string)
 		}
 		loc, err := curthread.Location()
 		var locFnName string
-		if loc.Fn != nil {
+		if loc.Fn != nil && !loc.Fn.cu.image.Stripped() {
 			locFnName = loc.Fn.Name
 			// Calls to runtime.Breakpoint are inlined in some versions of Go when
 			// inlining is enabled. Here we attempt to resolve any inlining.
@@ -677,7 +677,7 @@ func next(dbp *Target, stepInto, inlinedStepOut bool) error {
 		}
 	}
 
-	if !backward {
+	if !backward && !topframe.Current.Fn.cu.image.Stripped() {
 		_, err = setDeferBreakpoint(dbp, text, topframe, sameGCond, stepInto)
 		if err != nil {
 			return err
@@ -685,7 +685,7 @@ func next(dbp *Target, stepInto, inlinedStepOut bool) error {
 	}
 
 	// Add breakpoints on all the lines in the current function
-	pcs, err := topframe.Current.Fn.cu.lineInfo.AllPCsBetween(topframe.Current.Fn.Entry, topframe.Current.Fn.End-1, topframe.Current.File, topframe.Current.Line)
+	pcs, err := topframe.Current.Fn.AllPCs(topframe.Current.File, topframe.Current.Line)
 	if err != nil {
 		return err
 	}
@@ -865,6 +865,11 @@ func FindDeferReturnCalls(text []AsmInstruction) []uint64 {
 // If includeCurrentFn is true it will also remove all instructions
 // belonging to the current function.
 func removeInlinedCalls(pcs []uint64, topframe Stackframe) ([]uint64, error) {
+	// TODO(derekparker) it should be possible to still use some internal
+	// runtime information to do this.
+	if topframe.Call.Fn == nil || topframe.Call.Fn.cu.image.Stripped() {
+		return pcs, nil
+	}
 	dwarfTree, err := topframe.Call.Fn.cu.image.getDwarfTree(topframe.Call.Fn.offset)
 	if err != nil {
 		return pcs, err
@@ -1061,7 +1066,7 @@ func skipAutogeneratedWrappersOut(g *G, thread Thread, startTopframe, startRetfr
 		if frame.Current.Fn == nil {
 			return
 		}
-		file, line := frame.Current.Fn.cu.lineInfo.PCToLine(frame.Current.Fn.Entry, frame.Current.Fn.Entry)
+		file, line := g.Thread.BinInfo().EntryLineForFunc(frame.Current.Fn)
 		if !isAutogeneratedOrDeferReturn(Location{File: file, Line: line, Fn: frame.Current.Fn}) {
 			return &frames[i-1], &frames[i]
 		}
diff --git a/pkg/proc/variables.go b/pkg/proc/variables.go
index 65f5040d..26b4fb71 100644
--- a/pkg/proc/variables.go
+++ b/pkg/proc/variables.go
@@ -535,7 +535,7 @@ func (g *G) StartLoc(tgt *Target) Location {
 	if fn == nil {
 		return Location{PC: g.StartPC}
 	}
-	f, l := fn.cu.lineInfo.PCToLine(fn.Entry, fn.Entry)
+	f, l := tgt.BinInfo().EntryLineForFunc(fn)
 	return Location{PC: fn.Entry, File: f, Line: l, Fn: fn}
 }
 
diff --git a/pkg/terminal/starbind/starlark.go b/pkg/terminal/starbind/starlark.go
index f34335b0..2e2360af 100644
--- a/pkg/terminal/starbind/starlark.go
+++ b/pkg/terminal/starbind/starlark.go
@@ -6,6 +6,7 @@ import (
 	"io"
 	"io/ioutil"
 	"runtime"
+	"sort"
 	"strings"
 	"sync"
 
@@ -28,6 +29,7 @@ const (
 	dlvContextName               = "dlv_context"
 	curScopeBuiltinName          = "cur_scope"
 	defaultLoadConfigBuiltinName = "default_load_config"
+	helpBuiltinName              = "help"
 )
 
 func init() {
@@ -71,7 +73,13 @@ func New(ctx Context, out EchoWriter) *Env {
 	// Make the "time" module available to Starlark scripts.
 	starlark.Universe["time"] = startime.Module
 
-	env.env = env.starlarkPredeclare()
+	var doc map[string]string
+	env.env, doc = env.starlarkPredeclare()
+
+	builtindoc := func(name, args, descr string) {
+		doc[name] = name + args + "\n\n" + name + " " + descr
+	}
+
 	env.env[dlvCommandBuiltinName] = starlark.NewBuiltin(dlvCommandBuiltinName, func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
 		if err := isCancelled(thread); err != nil {
 			return starlark.None, err
@@ -90,6 +98,8 @@ func New(ctx Context, out EchoWriter) *Env {
 		}
 		return starlark.None, decorateError(thread, err)
 	})
+	builtindoc(dlvCommandBuiltinName, "(Command)", "interrupts, continues and steps through the program.")
+
 	env.env[readFileBuiltinName] = starlark.NewBuiltin(readFileBuiltinName, func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
 		if len(args) != 1 {
 			return nil, decorateError(thread, fmt.Errorf("wrong number of arguments"))
@@ -104,6 +114,8 @@ func New(ctx Context, out EchoWriter) *Env {
 		}
 		return starlark.String(string(buf)), nil
 	})
+	builtindoc(readFileBuiltinName, "(Path)", "reads a file.")
+
 	env.env[writeFileBuiltinName] = starlark.NewBuiltin(writeFileBuiltinName, func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
 		if len(args) != 2 {
 			return nil, decorateError(thread, fmt.Errorf("wrong number of arguments"))
@@ -115,12 +127,56 @@ func New(ctx Context, out EchoWriter) *Env {
 		err := ioutil.WriteFile(string(path), []byte(args[1].String()), 0640)
 		return starlark.None, decorateError(thread, err)
 	})
+	builtindoc(writeFileBuiltinName, "(Path, Text)", "writes text to the specified file.")
+
 	env.env[curScopeBuiltinName] = starlark.NewBuiltin(curScopeBuiltinName, func(_ *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
 		return env.interfaceToStarlarkValue(env.ctx.Scope()), nil
 	})
+	builtindoc(curScopeBuiltinName, "()", "returns the current scope.")
+
 	env.env[defaultLoadConfigBuiltinName] = starlark.NewBuiltin(defaultLoadConfigBuiltinName, func(_ *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
 		return env.interfaceToStarlarkValue(env.ctx.LoadConfig()), nil
 	})
+	builtindoc(defaultLoadConfigBuiltinName, "()", "returns the default load configuration.")
+
+	env.env[helpBuiltinName] = starlark.NewBuiltin(helpBuiltinName, func(_ *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
+		switch len(args) {
+		case 0:
+			fmt.Fprintln(env.out, "Available builtins:")
+			bins := make([]string, 0, len(env.env))
+			for name, value := range env.env {
+				switch value.(type) {
+				case *starlark.Builtin:
+					bins = append(bins, name)
+				}
+			}
+			sort.Strings(bins)
+			for _, bin := range bins {
+				fmt.Fprintf(env.out, "\t%s\n", bin)
+			}
+		case 1:
+			switch x := args[0].(type) {
+			case *starlark.Builtin:
+				if doc[x.Name()] != "" {
+					fmt.Fprintf(env.out, "%s\n", doc[x.Name()])
+				} else {
+					fmt.Fprintf(env.out, "no help for builtin %s\n", x.Name())
+				}
+			case *starlark.Function:
+				fmt.Fprintf(env.out, "user defined function %s\n", x.Name())
+				if doc := x.Doc(); doc != "" {
+					fmt.Fprintln(env.out, doc)
+				}
+			default:
+				fmt.Fprintf(env.out, "no help for object of type %T\n", args[0])
+			}
+		default:
+			fmt.Fprintln(env.out, "wrong number of arguments ", len(args))
+		}
+		return starlark.None, nil
+	})
+	builtindoc(helpBuiltinName, "(Object)", "prints help for Object.")
+
 	return env
 }
 
diff --git a/pkg/terminal/starbind/starlark_mapping.go b/pkg/terminal/starbind/starlark_mapping.go
index ce87f61b..b2f9d1d5 100644
--- a/pkg/terminal/starbind/starlark_mapping.go
+++ b/pkg/terminal/starbind/starlark_mapping.go
@@ -9,8 +9,9 @@ import (
 	"go.starlark.net/starlark"
 )
 
-func (env *Env) starlarkPredeclare() starlark.StringDict {
+func (env *Env) starlarkPredeclare() (starlark.StringDict, map[string]string) {
 	r := starlark.StringDict{}
+	doc := make(map[string]string)
 
 	r["amend_breakpoint"] = starlark.NewBuiltin("amend_breakpoint", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
 		if err := isCancelled(thread); err != nil {
@@ -42,6 +43,7 @@ func (env *Env) starlarkPredeclare() starlark.StringDict {
 		}
 		return env.interfaceToStarlarkValue(rpcRet), nil
 	})
+	doc["amend_breakpoint"] = "builtin amend_breakpoint(Breakpoint)\n\namend_breakpoint allows user to update an existing breakpoint\nfor example to change the information retrieved when the\nbreakpoint is hit or to change, add or remove the break condition.\n\narg.Breakpoint.ID must be a valid breakpoint ID"
 	r["ancestors"] = starlark.NewBuiltin("ancestors", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
 		if err := isCancelled(thread); err != nil {
 			return starlark.None, decorateError(thread, err)
@@ -88,6 +90,7 @@ func (env *Env) starlarkPredeclare() starlark.StringDict {
 		}
 		return env.interfaceToStarlarkValue(rpcRet), nil
 	})
+	doc["ancestors"] = "builtin ancestors(GoroutineID, NumAncestors, Depth)\n\nancestors returns the stacktraces for the ancestors of a goroutine."
 	r["attached_to_existing_process"] = starlark.NewBuiltin("attached_to_existing_process", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
 		if err := isCancelled(thread); err != nil {
 			return starlark.None, decorateError(thread, err)
@@ -100,6 +103,7 @@ func (env *Env) starlarkPredeclare() starlark.StringDict {
 		}
 		return env.interfaceToStarlarkValue(rpcRet), nil
 	})
+	doc["attached_to_existing_process"] = "builtin attached_to_existing_process()\n\nattached_to_existing_process returns whether we attached to a running process or not"
 	r["build_id"] = starlark.NewBuiltin("build_id", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
 		if err := isCancelled(thread); err != nil {
 			return starlark.None, decorateError(thread, err)
@@ -112,6 +116,7 @@ func (env *Env) starlarkPredeclare() starlark.StringDict {
 		}
 		return env.interfaceToStarlarkValue(rpcRet), nil
 	})
+	doc["build_id"] = "builtin build_id()"
 	r["cancel_next"] = starlark.NewBuiltin("cancel_next", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
 		if err := isCancelled(thread); err != nil {
 			return starlark.None, decorateError(thread, err)
@@ -124,6 +129,7 @@ func (env *Env) starlarkPredeclare() starlark.StringDict {
 		}
 		return env.interfaceToStarlarkValue(rpcRet), nil
 	})
+	doc["cancel_next"] = "builtin cancel_next()"
 	r["checkpoint"] = starlark.NewBuiltin("checkpoint", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
 		if err := isCancelled(thread); err != nil {
 			return starlark.None, decorateError(thread, err)
@@ -154,6 +160,7 @@ func (env *Env) starlarkPredeclare() starlark.StringDict {
 		}
 		return env.interfaceToStarlarkValue(rpcRet), nil
 	})
+	doc["checkpoint"] = "builtin checkpoint(Where)"
 	r["clear_breakpoint"] = starlark.NewBuiltin("clear_breakpoint", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
 		if err := isCancelled(thread); err != nil {
 			return starlark.None, decorateError(thread, err)
@@ -192,6 +199,7 @@ func (env *Env) starlarkPredeclare() starlark.StringDict {
 		}
 		return env.interfaceToStarlarkValue(rpcRet), nil
 	})
+	doc["clear_breakpoint"] = "builtin clear_breakpoint(Id, Name)\n\nclear_breakpoint deletes a breakpoint by Name (if Name is not an\nempty string) or by ID."
 	r["clear_checkpoint"] = starlark.NewBuiltin("clear_checkpoint", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
 		if err := isCancelled(thread); err != nil {
 			return starlark.None, decorateError(thread, err)
@@ -222,6 +230,7 @@ func (env *Env) starlarkPredeclare() starlark.StringDict {
 		}
 		return env.interfaceToStarlarkValue(rpcRet), nil
 	})
+	doc["clear_checkpoint"] = "builtin clear_checkpoint(ID)"
 	r["raw_command"] = starlark.NewBuiltin("raw_command", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
 		if err := isCancelled(thread); err != nil {
 			return starlark.None, decorateError(thread, err)
@@ -295,6 +304,7 @@ func (env *Env) starlarkPredeclare() starlark.StringDict {
 		}
 		return env.interfaceToStarlarkValue(rpcRet), nil
 	})
+	doc["raw_command"] = "builtin raw_command(Name, ThreadID, GoroutineID, ReturnInfoLoadConfig, Expr, UnsafeCall)\n\nraw_command interrupts, continues and steps through the program."
 	r["create_breakpoint"] = starlark.NewBuiltin("create_breakpoint", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
 		if err := isCancelled(thread); err != nil {
 			return starlark.None, decorateError(thread, err)
@@ -349,6 +359,7 @@ func (env *Env) starlarkPredeclare() starlark.StringDict {
 		}
 		return env.interfaceToStarlarkValue(rpcRet), nil
 	})
+	doc["create_breakpoint"] = "builtin create_breakpoint(Breakpoint, LocExpr, SubstitutePathRules, Suspended)\n\ncreate_breakpoint creates a new breakpoint. The client is expected to populate `CreateBreakpointIn`\nwith an `api.Breakpoint` struct describing where to set the breakpoint. For more information on\nhow to properly request a breakpoint via the `api.Breakpoint` struct see the documentation for\n`debugger.CreateBreakpoint` here: https://pkg.go.dev/github.com/go-delve/delve/service/debugger#Debugger.CreateBreakpoint."
 	r["create_ebpf_tracepoint"] = starlark.NewBuiltin("create_ebpf_tracepoint", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
 		if err := isCancelled(thread); err != nil {
 			return starlark.None, decorateError(thread, err)
@@ -379,6 +390,7 @@ func (env *Env) starlarkPredeclare() starlark.StringDict {
 		}
 		return env.interfaceToStarlarkValue(rpcRet), nil
 	})
+	doc["create_ebpf_tracepoint"] = "builtin create_ebpf_tracepoint(FunctionName)"
 	r["create_watchpoint"] = starlark.NewBuiltin("create_watchpoint", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
 		if err := isCancelled(thread); err != nil {
 			return starlark.None, decorateError(thread, err)
@@ -427,6 +439,7 @@ func (env *Env) starlarkPredeclare() starlark.StringDict {
 		}
 		return env.interfaceToStarlarkValue(rpcRet), nil
 	})
+	doc["create_watchpoint"] = "builtin create_watchpoint(Scope, Expr, Type)"
 	r["debug_info_directories"] = starlark.NewBuiltin("debug_info_directories", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
 		if err := isCancelled(thread); err != nil {
 			return starlark.None, decorateError(thread, err)
@@ -465,6 +478,7 @@ func (env *Env) starlarkPredeclare() starlark.StringDict {
 		}
 		return env.interfaceToStarlarkValue(rpcRet), nil
 	})
+	doc["debug_info_directories"] = "builtin debug_info_directories(Set, List)"
 	r["detach"] = starlark.NewBuiltin("detach", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
 		if err := isCancelled(thread); err != nil {
 			return starlark.None, decorateError(thread, err)
@@ -495,6 +509,7 @@ func (env *Env) starlarkPredeclare() starlark.StringDict {
 		}
 		return env.interfaceToStarlarkValue(rpcRet), nil
 	})
+	doc["detach"] = "builtin detach(Kill)\n\ndetach detaches the debugger, optionally killing the process."
 	r["disassemble"] = starlark.NewBuiltin("disassemble", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
 		if err := isCancelled(thread); err != nil {
 			return starlark.None, decorateError(thread, err)
@@ -551,6 +566,7 @@ func (env *Env) starlarkPredeclare() starlark.StringDict {
 		}
 		return env.interfaceToStarlarkValue(rpcRet), nil
 	})
+	doc["disassemble"] = "builtin disassemble(Scope, StartPC, EndPC, Flavour)\n\ndisassemble code.\n\nIf both StartPC and EndPC are non-zero the specified range will be disassembled, otherwise the function containing StartPC will be disassembled.\n\nScope is used to mark the instruction the specified goroutine is stopped at.\n\nDisassemble will also try to calculate the destination address of an absolute indirect CALL if it happens to be the instruction the selected goroutine is stopped at."
 	r["dump_cancel"] = starlark.NewBuiltin("dump_cancel", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
 		if err := isCancelled(thread); err != nil {
 			return starlark.None, decorateError(thread, err)
@@ -563,6 +579,7 @@ func (env *Env) starlarkPredeclare() starlark.StringDict {
 		}
 		return env.interfaceToStarlarkValue(rpcRet), nil
 	})
+	doc["dump_cancel"] = "builtin dump_cancel()\n\ndump_cancel cancels the core dump."
 	r["dump_start"] = starlark.NewBuiltin("dump_start", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
 		if err := isCancelled(thread); err != nil {
 			return starlark.None, decorateError(thread, err)
@@ -593,6 +610,7 @@ func (env *Env) starlarkPredeclare() starlark.StringDict {
 		}
 		return env.interfaceToStarlarkValue(rpcRet), nil
 	})
+	doc["dump_start"] = "builtin dump_start(Destination)\n\ndump_start starts a core dump to arg.Destination."
 	r["dump_wait"] = starlark.NewBuiltin("dump_wait", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
 		if err := isCancelled(thread); err != nil {
 			return starlark.None, decorateError(thread, err)
@@ -623,6 +641,7 @@ func (env *Env) starlarkPredeclare() starlark.StringDict {
 		}
 		return env.interfaceToStarlarkValue(rpcRet), nil
 	})
+	doc["dump_wait"] = "builtin dump_wait(Wait)\n\ndump_wait waits for the core dump to finish or for arg.Wait milliseconds.\nWait == 0 means return immediately.\nReturns the core dump status"
 	r["eval"] = starlark.NewBuiltin("eval", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
 		if err := isCancelled(thread); err != nil {
 			return starlark.None, decorateError(thread, err)
@@ -674,6 +693,7 @@ func (env *Env) starlarkPredeclare() starlark.StringDict {
 		}
 		return env.interfaceToStarlarkValue(rpcRet), nil
 	})
+	doc["eval"] = "builtin eval(Scope, Expr, Cfg)\n\neval returns a variable in the specified context.\n\nSee https://github.com/go-delve/delve/blob/master/Documentation/cli/expr.md\nfor a description of acceptable values of arg.Expr."
 	r["examine_memory"] = starlark.NewBuiltin("examine_memory", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
 		if err := isCancelled(thread); err != nil {
 			return starlark.None, decorateError(thread, err)
@@ -712,6 +732,7 @@ func (env *Env) starlarkPredeclare() starlark.StringDict {
 		}
 		return env.interfaceToStarlarkValue(rpcRet), nil
 	})
+	doc["examine_memory"] = "builtin examine_memory(Address, Length)"
 	r["find_location"] = starlark.NewBuiltin("find_location", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
 		if err := isCancelled(thread); err != nil {
 			return starlark.None, decorateError(thread, err)
@@ -768,6 +789,7 @@ func (env *Env) starlarkPredeclare() starlark.StringDict {
 		}
 		return env.interfaceToStarlarkValue(rpcRet), nil
 	})
+	doc["find_location"] = "builtin find_location(Scope, Loc, IncludeNonExecutableLines, SubstitutePathRules)\n\nfind_location returns concrete location information described by a location expression.\n\n\tloc ::= <filename>:<line> | <function>[:<line>] | /<regex>/ | (+|-)<offset> | <line> | *<address>\n\t* <filename> can be the full path of a file or just a suffix\n\t* <function> ::= <package>.<receiver type>.<name> | <package>.(*<receiver type>).<name> | <receiver type>.<name> | <package>.<name> | (*<receiver type>).<name> | <name>\n\t  <function> must be unambiguous\n\t* /<regex>/ will return a location for each function matched by regex\n\t* +<offset> returns a location for the line that is <offset> lines after the current line\n\t* -<offset> returns a location for the line that is <offset> lines before the current line\n\t* <line> returns a location for a line in the current file\n\t* *<address> returns the location corresponding to the specified address\n\nNOTE: this function does not actually set breakpoints."
 	r["follow_exec"] = starlark.NewBuiltin("follow_exec", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
 		if err := isCancelled(thread); err != nil {
 			return starlark.None, decorateError(thread, err)
@@ -806,6 +828,7 @@ func (env *Env) starlarkPredeclare() starlark.StringDict {
 		}
 		return env.interfaceToStarlarkValue(rpcRet), nil
 	})
+	doc["follow_exec"] = "builtin follow_exec(Enable, Regex)\n\nfollow_exec enables or disables follow exec mode."
 	r["follow_exec_enabled"] = starlark.NewBuiltin("follow_exec_enabled", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
 		if err := isCancelled(thread); err != nil {
 			return starlark.None, decorateError(thread, err)
@@ -818,6 +841,7 @@ func (env *Env) starlarkPredeclare() starlark.StringDict {
 		}
 		return env.interfaceToStarlarkValue(rpcRet), nil
 	})
+	doc["follow_exec_enabled"] = "builtin follow_exec_enabled()\n\nfollow_exec_enabled returns true if follow exec mode is enabled."
 	r["function_return_locations"] = starlark.NewBuiltin("function_return_locations", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
 		if err := isCancelled(thread); err != nil {
 			return starlark.None, decorateError(thread, err)
@@ -848,6 +872,7 @@ func (env *Env) starlarkPredeclare() starlark.StringDict {
 		}
 		return env.interfaceToStarlarkValue(rpcRet), nil
 	})
+	doc["function_return_locations"] = "builtin function_return_locations(FnName)\n\nfunction_return_locations is the implements the client call of the same name. Look at client documentation for more information."
 	r["get_breakpoint"] = starlark.NewBuiltin("get_breakpoint", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
 		if err := isCancelled(thread); err != nil {
 			return starlark.None, decorateError(thread, err)
@@ -886,6 +911,7 @@ func (env *Env) starlarkPredeclare() starlark.StringDict {
 		}
 		return env.interfaceToStarlarkValue(rpcRet), nil
 	})
+	doc["get_breakpoint"] = "builtin get_breakpoint(Id, Name)\n\nget_breakpoint gets a breakpoint by Name (if Name is not an empty string) or by ID."
 	r["get_buffered_tracepoints"] = starlark.NewBuiltin("get_buffered_tracepoints", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
 		if err := isCancelled(thread); err != nil {
 			return starlark.None, decorateError(thread, err)
@@ -898,6 +924,7 @@ func (env *Env) starlarkPredeclare() starlark.StringDict {
 		}
 		return env.interfaceToStarlarkValue(rpcRet), nil
 	})
+	doc["get_buffered_tracepoints"] = "builtin get_buffered_tracepoints()"
 	r["get_thread"] = starlark.NewBuiltin("get_thread", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
 		if err := isCancelled(thread); err != nil {
 			return starlark.None, decorateError(thread, err)
@@ -928,6 +955,7 @@ func (env *Env) starlarkPredeclare() starlark.StringDict {
 		}
 		return env.interfaceToStarlarkValue(rpcRet), nil
 	})
+	doc["get_thread"] = "builtin get_thread(Id)\n\nget_thread gets a thread by its ID."
 	r["is_multiclient"] = starlark.NewBuiltin("is_multiclient", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
 		if err := isCancelled(thread); err != nil {
 			return starlark.None, decorateError(thread, err)
@@ -940,6 +968,7 @@ func (env *Env) starlarkPredeclare() starlark.StringDict {
 		}
 		return env.interfaceToStarlarkValue(rpcRet), nil
 	})
+	doc["is_multiclient"] = "builtin is_multiclient()"
 	r["last_modified"] = starlark.NewBuiltin("last_modified", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
 		if err := isCancelled(thread); err != nil {
 			return starlark.None, decorateError(thread, err)
@@ -952,6 +981,7 @@ func (env *Env) starlarkPredeclare() starlark.StringDict {
 		}
 		return env.interfaceToStarlarkValue(rpcRet), nil
 	})
+	doc["last_modified"] = "builtin last_modified()"
 	r["breakpoints"] = starlark.NewBuiltin("breakpoints", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
 		if err := isCancelled(thread); err != nil {
 			return starlark.None, decorateError(thread, err)
@@ -982,6 +1012,7 @@ func (env *Env) starlarkPredeclare() starlark.StringDict {
 		}
 		return env.interfaceToStarlarkValue(rpcRet), nil
 	})
+	doc["breakpoints"] = "builtin breakpoints(All)\n\nbreakpoints gets all breakpoints."
 	r["checkpoints"] = starlark.NewBuiltin("checkpoints", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
 		if err := isCancelled(thread); err != nil {
 			return starlark.None, decorateError(thread, err)
@@ -994,6 +1025,7 @@ func (env *Env) starlarkPredeclare() starlark.StringDict {
 		}
 		return env.interfaceToStarlarkValue(rpcRet), nil
 	})
+	doc["checkpoints"] = "builtin checkpoints()"
 	r["dynamic_libraries"] = starlark.NewBuiltin("dynamic_libraries", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
 		if err := isCancelled(thread); err != nil {
 			return starlark.None, decorateError(thread, err)
@@ -1006,6 +1038,7 @@ func (env *Env) starlarkPredeclare() starlark.StringDict {
 		}
 		return env.interfaceToStarlarkValue(rpcRet), nil
 	})
+	doc["dynamic_libraries"] = "builtin dynamic_libraries()"
 	r["function_args"] = starlark.NewBuiltin("function_args", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
 		if err := isCancelled(thread); err != nil {
 			return starlark.None, decorateError(thread, err)
@@ -1048,6 +1081,7 @@ func (env *Env) starlarkPredeclare() starlark.StringDict {
 		}
 		return env.interfaceToStarlarkValue(rpcRet), nil
 	})
+	doc["function_args"] = "builtin function_args(Scope, Cfg)\n\nfunction_args lists all arguments to the current function"
 	r["functions"] = starlark.NewBuiltin("functions", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
 		if err := isCancelled(thread); err != nil {
 			return starlark.None, decorateError(thread, err)
@@ -1078,6 +1112,7 @@ func (env *Env) starlarkPredeclare() starlark.StringDict {
 		}
 		return env.interfaceToStarlarkValue(rpcRet), nil
 	})
+	doc["functions"] = "builtin functions(Filter)\n\nfunctions lists all functions in the process matching filter."
 	r["goroutines"] = starlark.NewBuiltin("goroutines", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
 		if err := isCancelled(thread); err != nil {
 			return starlark.None, decorateError(thread, err)
@@ -1132,6 +1167,7 @@ func (env *Env) starlarkPredeclare() starlark.StringDict {
 		}
 		return env.interfaceToStarlarkValue(rpcRet), nil
 	})
+	doc["goroutines"] = "builtin goroutines(Start, Count, Filters, GoroutineGroupingOptions)\n\ngoroutines lists all goroutines.\nIf Count is specified ListGoroutines will return at the first Count\ngoroutines and an index in Nextg, that can be passed as the Start\nparameter, to get more goroutines from ListGoroutines.\nPassing a value of Start that wasn't returned by ListGoroutines will skip\nan undefined number of goroutines.\n\nIf arg.Filters are specified the list of returned goroutines is filtered\napplying the specified filters.\nFor example:\n\n\tListGoroutinesFilter{ Kind: ListGoroutinesFilterUserLoc, Negated: false, Arg: \"afile.go\" }\n\nwill only return goroutines whose UserLoc contains \"afile.go\" as a substring.\nMore specifically a goroutine matches a location filter if the specified\nlocation, formatted like this:\n\n\tfilename:lineno in function\n\ncontains Arg[0] as a substring.\n\nFilters can also be applied to goroutine labels:\n\n\tListGoroutineFilter{ Kind: ListGoroutinesFilterLabel, Negated: false, Arg: \"key=value\" }\n\nthis filter will only return goroutines that have a key=value label.\n\nIf arg.GroupBy is not GoroutineFieldNone then the goroutines will\nbe grouped with the specified criterion.\nIf the value of arg.GroupBy is GoroutineLabel goroutines will\nbe grouped by the value of the label with key GroupByKey.\nFor each group a maximum of MaxExamples example goroutines are\nreturned, as well as the total number of goroutines in the group."
 	r["local_vars"] = starlark.NewBuiltin("local_vars", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
 		if err := isCancelled(thread); err != nil {
 			return starlark.None, decorateError(thread, err)
@@ -1174,6 +1210,7 @@ func (env *Env) starlarkPredeclare() starlark.StringDict {
 		}
 		return env.interfaceToStarlarkValue(rpcRet), nil
 	})
+	doc["local_vars"] = "builtin local_vars(Scope, Cfg)\n\nlocal_vars lists all local variables in scope."
 	r["package_vars"] = starlark.NewBuiltin("package_vars", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
 		if err := isCancelled(thread); err != nil {
 			return starlark.None, decorateError(thread, err)
@@ -1214,6 +1251,7 @@ func (env *Env) starlarkPredeclare() starlark.StringDict {
 		}
 		return env.interfaceToStarlarkValue(rpcRet), nil
 	})
+	doc["package_vars"] = "builtin package_vars(Filter, Cfg)\n\npackage_vars lists all package variables in the context of the current thread."
 	r["packages_build_info"] = starlark.NewBuiltin("packages_build_info", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
 		if err := isCancelled(thread); err != nil {
 			return starlark.None, decorateError(thread, err)
@@ -1244,6 +1282,7 @@ func (env *Env) starlarkPredeclare() starlark.StringDict {
 		}
 		return env.interfaceToStarlarkValue(rpcRet), nil
 	})
+	doc["packages_build_info"] = "builtin packages_build_info(IncludeFiles)\n\npackages_build_info returns the list of packages used by the program along with\nthe directory where each package was compiled and optionally the list of\nfiles constituting the package.\nNote that the directory path is a best guess and may be wrong is a tool\nother than cmd/go is used to perform the build."
 	r["registers"] = starlark.NewBuiltin("registers", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
 		if err := isCancelled(thread); err != nil {
 			return starlark.None, decorateError(thread, err)
@@ -1293,6 +1332,7 @@ func (env *Env) starlarkPredeclare() starlark.StringDict {
 		}
 		return env.interfaceToStarlarkValue(rpcRet), nil
 	})
+	doc["registers"] = "builtin registers(ThreadID, IncludeFp, Scope)\n\nregisters lists registers and their values.\nIf ListRegistersIn.Scope is not nil the registers of that eval scope will\nbe returned, otherwise ListRegistersIn.ThreadID will be used."
 	r["sources"] = starlark.NewBuiltin("sources", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
 		if err := isCancelled(thread); err != nil {
 			return starlark.None, decorateError(thread, err)
@@ -1323,6 +1363,7 @@ func (env *Env) starlarkPredeclare() starlark.StringDict {
 		}
 		return env.interfaceToStarlarkValue(rpcRet), nil
 	})
+	doc["sources"] = "builtin sources(Filter)\n\nsources lists all source files in the process matching filter."
 	r["targets"] = starlark.NewBuiltin("targets", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
 		if err := isCancelled(thread); err != nil {
 			return starlark.None, decorateError(thread, err)
@@ -1335,6 +1376,7 @@ func (env *Env) starlarkPredeclare() starlark.StringDict {
 		}
 		return env.interfaceToStarlarkValue(rpcRet), nil
 	})
+	doc["targets"] = "builtin targets()\n\ntargets returns the list of targets we are currently attached to."
 	r["threads"] = starlark.NewBuiltin("threads", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
 		if err := isCancelled(thread); err != nil {
 			return starlark.None, decorateError(thread, err)
@@ -1347,6 +1389,7 @@ func (env *Env) starlarkPredeclare() starlark.StringDict {
 		}
 		return env.interfaceToStarlarkValue(rpcRet), nil
 	})
+	doc["threads"] = "builtin threads()\n\nthreads lists all threads."
 	r["types"] = starlark.NewBuiltin("types", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
 		if err := isCancelled(thread); err != nil {
 			return starlark.None, decorateError(thread, err)
@@ -1377,6 +1420,7 @@ func (env *Env) starlarkPredeclare() starlark.StringDict {
 		}
 		return env.interfaceToStarlarkValue(rpcRet), nil
 	})
+	doc["types"] = "builtin types(Filter)\n\ntypes lists all types in the process matching filter."
 	r["process_pid"] = starlark.NewBuiltin("process_pid", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
 		if err := isCancelled(thread); err != nil {
 			return starlark.None, decorateError(thread, err)
@@ -1389,6 +1433,7 @@ func (env *Env) starlarkPredeclare() starlark.StringDict {
 		}
 		return env.interfaceToStarlarkValue(rpcRet), nil
 	})
+	doc["process_pid"] = "builtin process_pid()\n\nprocess_pid returns the pid of the process we are debugging."
 	r["recorded"] = starlark.NewBuiltin("recorded", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
 		if err := isCancelled(thread); err != nil {
 			return starlark.None, decorateError(thread, err)
@@ -1401,6 +1446,7 @@ func (env *Env) starlarkPredeclare() starlark.StringDict {
 		}
 		return env.interfaceToStarlarkValue(rpcRet), nil
 	})
+	doc["recorded"] = "builtin recorded()"
 	r["restart"] = starlark.NewBuiltin("restart", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
 		if err := isCancelled(thread); err != nil {
 			return starlark.None, decorateError(thread, err)
@@ -1471,6 +1517,7 @@ func (env *Env) starlarkPredeclare() starlark.StringDict {
 		}
 		return env.interfaceToStarlarkValue(rpcRet), nil
 	})
+	doc["restart"] = "builtin restart(Position, ResetArgs, NewArgs, Rerecord, Rebuild, NewRedirects)\n\nrestart restarts program."
 	r["set_expr"] = starlark.NewBuiltin("set_expr", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
 		if err := isCancelled(thread); err != nil {
 			return starlark.None, decorateError(thread, err)
@@ -1519,6 +1566,7 @@ func (env *Env) starlarkPredeclare() starlark.StringDict {
 		}
 		return env.interfaceToStarlarkValue(rpcRet), nil
 	})
+	doc["set_expr"] = "builtin set_expr(Scope, Symbol, Value)\n\nset_expr sets the value of a variable. Only numerical types and\npointers are currently supported."
 	r["stacktrace"] = starlark.NewBuiltin("stacktrace", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
 		if err := isCancelled(thread); err != nil {
 			return starlark.None, decorateError(thread, err)
@@ -1589,6 +1637,7 @@ func (env *Env) starlarkPredeclare() starlark.StringDict {
 		}
 		return env.interfaceToStarlarkValue(rpcRet), nil
 	})
+	doc["stacktrace"] = "builtin stacktrace(Id, Depth, Full, Defers, Opts, Cfg)\n\nstacktrace returns stacktrace of goroutine Id up to the specified Depth.\n\nIf Full is set it will also the variable of all local variables\nand function arguments of all stack frames."
 	r["state"] = starlark.NewBuiltin("state", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
 		if err := isCancelled(thread); err != nil {
 			return starlark.None, decorateError(thread, err)
@@ -1619,6 +1668,7 @@ func (env *Env) starlarkPredeclare() starlark.StringDict {
 		}
 		return env.interfaceToStarlarkValue(rpcRet), nil
 	})
+	doc["state"] = "builtin state(NonBlocking)\n\nstate returns the current debugger state."
 	r["toggle_breakpoint"] = starlark.NewBuiltin("toggle_breakpoint", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
 		if err := isCancelled(thread); err != nil {
 			return starlark.None, decorateError(thread, err)
@@ -1657,5 +1707,6 @@ func (env *Env) starlarkPredeclare() starlark.StringDict {
 		}
 		return env.interfaceToStarlarkValue(rpcRet), nil
 	})
-	return r
+	doc["toggle_breakpoint"] = "builtin toggle_breakpoint(Id, Name)\n\ntoggle_breakpoint toggles on or off a breakpoint by Name (if Name is not an\nempty string) or by ID."
+	return r, doc
 }
diff --git a/service/dap/server.go b/service/dap/server.go
index f6e1b1f7..80ad6570 100644
--- a/service/dap/server.go
+++ b/service/dap/server.go
@@ -1128,7 +1128,7 @@ func (s *Session) onDisconnectRequest(request *dap.DisconnectRequest) {
 	s.mu.Lock()
 	defer s.mu.Unlock()
 
-	if s.debugger != nil && s.config.AcceptMulti && !request.Arguments.TerminateDebuggee {
+	if s.debugger != nil && s.config.AcceptMulti && (request.Arguments == nil || !request.Arguments.TerminateDebuggee) {
 		// This is a multi-use server/debugger, so a disconnect request that doesn't
 		// terminate the debuggee should clean up only the client connection and pointer to debugger,
 		// but not the entire server.
@@ -1161,7 +1161,7 @@ func (s *Session) onDisconnectRequest(request *dap.DisconnectRequest) {
 		// In case of attach, we leave the program
 		// running by default, which can be
 		// overridden by an explicit request to terminate.
-		killProcess := s.debugger.AttachPid() == 0 || request.Arguments.TerminateDebuggee
+		killProcess := s.debugger.AttachPid() == 0 || (request.Arguments != nil && request.Arguments.TerminateDebuggee)
 		err = s.stopDebugSession(killProcess)
 	} else if s.noDebugProcess != nil {
 		s.stopNoDebugProcess()
@@ -1966,7 +1966,7 @@ func (s *Session) onStackTraceRequest(request *dap.StackTraceRequest) {
 		stackFrame := dap.StackFrame{Id: uniqueStackFrameID, Line: loc.Line, Name: fnName(loc), InstructionPointerReference: fmt.Sprintf("%#x", loc.PC)}
 		if loc.File != "<autogenerated>" {
 			clientPath := s.toClientPath(loc.File)
-			stackFrame.Source = dap.Source{Name: filepath.Base(clientPath), Path: clientPath}
+			stackFrame.Source = &dap.Source{Name: filepath.Base(clientPath), Path: clientPath}
 		}
 		stackFrame.Column = 0
 
@@ -3045,7 +3045,7 @@ func (s *Session) onDisassembleRequest(request *dap.DisassembleRequest) {
 		}
 		// Only set the location on the first instruction for a given line.
 		if instruction.Loc.File != lastFile || instruction.Loc.Line != lastLine {
-			instructions[i].Location = dap.Source{Path: instruction.Loc.File}
+			instructions[i].Location = &dap.Source{Path: instruction.Loc.File}
 			instructions[i].Line = instruction.Loc.Line
 			lastFile, lastLine = instruction.Loc.File, instruction.Loc.Line
 		}
@@ -3252,6 +3252,7 @@ func (s *Session) onExceptionInfoRequest(request *dap.ExceptionInfoRequest) {
 	}
 
 	if includeStackTrace {
+		body.Details = &dap.ExceptionDetails{}
 		frames, err := s.stacktrace(goroutineID, g)
 		if err != nil {
 			body.Details.StackTrace = fmt.Sprintf("Error getting stack trace: %s", err.Error())
@@ -3320,9 +3321,11 @@ func (s *Session) sendErrorResponseWithOpts(request dap.Request, id int, summary
 	er.RequestSeq = request.Seq
 	er.Success = false
 	er.Message = summary
-	er.Body.Error.Id = id
-	er.Body.Error.Format = fmt.Sprintf("%s: %s", summary, details)
-	er.Body.Error.ShowUser = showUser
+	er.Body.Error = &dap.ErrorMessage{
+		Id:       id,
+		Format:   fmt.Sprintf("%s: %s", summary, details),
+		ShowUser: showUser,
+	}
 	s.config.log.Debug(er.Body.Error.Format)
 	s.send(er)
 }
@@ -3346,8 +3349,10 @@ func (s *Session) sendInternalErrorResponse(seq int, details string) {
 	er.RequestSeq = seq
 	er.Success = false
 	er.Message = "Internal Error"
-	er.Body.Error.Id = InternalError
-	er.Body.Error.Format = fmt.Sprintf("%s: %s", er.Message, details)
+	er.Body.Error = &dap.ErrorMessage{
+		Id:     InternalError,
+		Format: fmt.Sprintf("%s: %s", er.Message, details),
+	}
 	s.config.log.Debug(er.Body.Error.Format)
 	s.send(er)
 }
@@ -3667,7 +3672,7 @@ func (s *Session) logBreakpointMessage(bp *api.Breakpoint, goid int64) bool {
 			Body: dap.OutputEventBody{
 				Category: "stdout",
 				Output:   fmt.Sprintf("> [Go %d]: %s\n", goid, msg),
-				Source: dap.Source{
+				Source: &dap.Source{
 					Path: s.toClientPath(bp.File),
 				},
 				Line: bp.Line,
diff --git a/service/debugger/debugger.go b/service/debugger/debugger.go
index 27441fba..4a100e9b 100644
--- a/service/debugger/debugger.go
+++ b/service/debugger/debugger.go
@@ -1315,6 +1315,13 @@ func (d *Debugger) collectBreakpointInformation(apiThread *api.Thread, thread pr
 
 	tgt := d.target.TargetForThread(thread.ThreadID())
 
+	// If we're dealing with a stripped binary don't attempt to load more
+	// information, we won't be able to.
+	img := tgt.BinInfo().PCToImage(bp.Addr)
+	if img != nil && img.Stripped() {
+		return nil
+	}
+
 	if bp.Goroutine {
 		g, err := proc.GetG(thread)
 		if err != nil {
diff --git a/vendor/github.com/google/go-dap/go.mod b/vendor/github.com/google/go-dap/go.mod
index 6a37a239..d90f6f0c 100644
--- a/vendor/github.com/google/go-dap/go.mod
+++ b/vendor/github.com/google/go-dap/go.mod
@@ -1,3 +1,5 @@
 module github.com/google/go-dap
 
 go 1.13
+
+retract v0.9.0
diff --git a/vendor/github.com/google/go-dap/schematypes.go b/vendor/github.com/google/go-dap/schematypes.go
index 3fd2770c..54200bc8 100644
--- a/vendor/github.com/google/go-dap/schematypes.go
+++ b/vendor/github.com/google/go-dap/schematypes.go
@@ -93,7 +93,7 @@ type Response struct {
 	Message    string `json:"message,omitempty"`
 }
 
-// ErrorResponse: On error (whenever 'success' is false), the body can provide more details.
+// ErrorResponse: On error (whenever `success` is false), the body can provide more details.
 type ErrorResponse struct {
 	Response
 
@@ -101,52 +101,51 @@ type ErrorResponse struct {
 }
 
 type ErrorResponseBody struct {
-	Error ErrorMessage `json:"error,omitempty"`
+	Error *ErrorMessage `json:"error,omitempty"`
 }
 
 func (r *ErrorResponse) GetResponse() *Response { return &r.Response }
 
-// CancelRequest: The 'cancel' request is used by the frontend in two situations:
+// CancelRequest: The `cancel` request is used by the client in two situations:
 // - to indicate that it is no longer interested in the result produced by a specific request issued earlier
-// - to cancel a progress sequence. Clients should only call this request if the capability 'supportsCancelRequest' is true.
-// This request has a hint characteristic: a debug adapter can only be expected to make a 'best effort' in honouring this request but there are no guarantees.
-// The 'cancel' request may return an error if it could not cancel an operation but a frontend should refrain from presenting this error to end users.
-// A frontend client should only call this request if the capability 'supportsCancelRequest' is true.
-// The request that got canceled still needs to send a response back. This can either be a normal result ('success' attribute true)
-// or an error response ('success' attribute false and the 'message' set to 'cancelled').
-// Returning partial results from a cancelled request is possible but please note that a frontend client has no generic way for detecting that a response is partial or not.
-//  The progress that got cancelled still needs to send a 'progressEnd' event back.
-//  A client should not assume that progress just got cancelled after sending the 'cancel' request.
+// - to cancel a progress sequence. Clients should only call this request if the corresponding capability `supportsCancelRequest` is true.
+// This request has a hint characteristic: a debug adapter can only be expected to make a 'best effort' in honoring this request but there are no guarantees.
+// The `cancel` request may return an error if it could not cancel an operation but a client should refrain from presenting this error to end users.
+// The request that got cancelled still needs to send a response back. This can either be a normal result (`success` attribute true) or an error response (`success` attribute false and the `message` set to `cancelled`).
+// Returning partial results from a cancelled request is possible but please note that a client has no generic way for detecting that a response is partial or not.
+// The progress that got cancelled still needs to send a `progressEnd` event back.
+//
+//	A client should not assume that progress just got cancelled after sending the `cancel` request.
 type CancelRequest struct {
 	Request
 
-	Arguments CancelArguments `json:"arguments,omitempty"`
+	Arguments *CancelArguments `json:"arguments,omitempty"`
 }
 
 func (r *CancelRequest) GetRequest() *Request { return &r.Request }
 
-// CancelArguments: Arguments for 'cancel' request.
+// CancelArguments: Arguments for `cancel` request.
 type CancelArguments struct {
 	RequestId  int    `json:"requestId,omitempty"`
 	ProgressId string `json:"progressId,omitempty"`
 }
 
-// CancelResponse: Response to 'cancel' request. This is just an acknowledgement, so no body field is required.
+// CancelResponse: Response to `cancel` request. This is just an acknowledgement, so no body field is required.
 type CancelResponse struct {
 	Response
 }
 
 func (r *CancelResponse) GetResponse() *Response { return &r.Response }
 
-// InitializedEvent: This event indicates that the debug adapter is ready to accept configuration requests (e.g. SetBreakpointsRequest, SetExceptionBreakpointsRequest).
-// A debug adapter is expected to send this event when it is ready to accept configuration requests (but not before the 'initialize' request has finished).
+// InitializedEvent: This event indicates that the debug adapter is ready to accept configuration requests (e.g. `setBreakpoints`, `setExceptionBreakpoints`).
+// A debug adapter is expected to send this event when it is ready to accept configuration requests (but not before the `initialize` request has finished).
 // The sequence of events/requests is as follows:
-// - adapters sends 'initialized' event (after the 'initialize' request has returned)
-// - frontend sends zero or more 'setBreakpoints' requests
-// - frontend sends one 'setFunctionBreakpoints' request (if capability 'supportsFunctionBreakpoints' is true)
-// - frontend sends a 'setExceptionBreakpoints' request if one or more 'exceptionBreakpointFilters' have been defined (or if 'supportsConfigurationDoneRequest' is not defined or false)
-// - frontend sends other future configuration requests
-// - frontend sends one 'configurationDone' request to indicate the end of the configuration.
+// - adapters sends `initialized` event (after the `initialize` request has returned)
+// - client sends zero or more `setBreakpoints` requests
+// - client sends one `setFunctionBreakpoints` request (if corresponding capability `supportsFunctionBreakpoints` is true)
+// - client sends a `setExceptionBreakpoints` request if one or more `exceptionBreakpointFilters` have been defined (or if `supportsConfigurationDoneRequest` is not true)
+// - client sends other future configuration requests
+// - client sends one `configurationDone` request to indicate the end of the configuration.
 type InitializedEvent struct {
 	Event
 }
@@ -154,7 +153,7 @@ type InitializedEvent struct {
 func (e *InitializedEvent) GetEvent() *Event { return &e.Event }
 
 // StoppedEvent: The event indicates that the execution of the debuggee has stopped due to some condition.
-// This can be caused by a break point previously set, a stepping request has completed, by executing a debugger statement etc.
+// This can be caused by a breakpoint previously set, a stepping request has completed, by executing a debugger statement etc.
 type StoppedEvent struct {
 	Event
 
@@ -174,8 +173,8 @@ type StoppedEventBody struct {
 func (e *StoppedEvent) GetEvent() *Event { return &e.Event }
 
 // ContinuedEvent: The event indicates that the execution of the debuggee has continued.
-// Please note: a debug adapter is not expected to send this event in response to a request that implies that execution continues, e.g. 'launch' or 'continue'.
-// It is only necessary to send a 'continued' event if there was no previous request that implied this.
+// Please note: a debug adapter is not expected to send this event in response to a request that implies that execution continues, e.g. `launch` or `continue`.
+// It is only necessary to send a `continued` event if there was no previous request that implied this.
 type ContinuedEvent struct {
 	Event
 
@@ -241,7 +240,7 @@ type OutputEventBody struct {
 	Output             string      `json:"output"`
 	Group              string      `json:"group,omitempty"`
 	VariablesReference int         `json:"variablesReference,omitempty"`
-	Source             Source      `json:"source,omitempty"`
+	Source             *Source     `json:"source,omitempty"`
 	Line               int         `json:"line,omitempty"`
 	Column             int         `json:"column,omitempty"`
 	Data               interface{} `json:"data,omitempty"`
@@ -309,8 +308,8 @@ type ProcessEventBody struct {
 func (e *ProcessEvent) GetEvent() *Event { return &e.Event }
 
 // CapabilitiesEvent: The event indicates that one or more capabilities have changed.
-// Since the capabilities are dependent on the frontend and its UI, it might not be possible to change that at random times (or too late).
-// Consequently this event has a hint characteristic: a frontend can only be expected to make a 'best effort' in honouring individual capabilities but there are no guarantees.
+// Since the capabilities are dependent on the client and its UI, it might not be possible to change that at random times (or too late).
+// Consequently this event has a hint characteristic: a client can only be expected to make a 'best effort' in honoring individual capabilities but there are no guarantees.
 // Only changed capabilities need to be included, all other capabilities keep their values.
 type CapabilitiesEvent struct {
 	Event
@@ -324,10 +323,9 @@ type CapabilitiesEventBody struct {
 
 func (e *CapabilitiesEvent) GetEvent() *Event { return &e.Event }
 
-// ProgressStartEvent: The event signals that a long running operation is about to start and
-// provides additional information for the client to set up a corresponding progress and cancellation UI.
+// ProgressStartEvent: The event signals that a long running operation is about to start and provides additional information for the client to set up a corresponding progress and cancellation UI.
 // The client is free to delay the showing of the UI in order to reduce flicker.
-// This event should only be sent if the client has passed the value true for the 'supportsProgressReporting' capability of the 'initialize' request.
+// This event should only be sent if the corresponding capability `supportsProgressReporting` is true.
 type ProgressStartEvent struct {
 	Event
 
@@ -345,9 +343,9 @@ type ProgressStartEventBody struct {
 
 func (e *ProgressStartEvent) GetEvent() *Event { return &e.Event }
 
-// ProgressUpdateEvent: The event signals that the progress reporting needs to updated with a new message and/or percentage.
+// ProgressUpdateEvent: The event signals that the progress reporting needs to be updated with a new message and/or percentage.
 // The client does not have to update the UI immediately, but the clients needs to keep track of the message and/or percentage values.
-// This event should only be sent if the client has passed the value true for the 'supportsProgressReporting' capability of the 'initialize' request.
+// This event should only be sent if the corresponding capability `supportsProgressReporting` is true.
 type ProgressUpdateEvent struct {
 	Event
 
@@ -362,8 +360,8 @@ type ProgressUpdateEventBody struct {
 
 func (e *ProgressUpdateEvent) GetEvent() *Event { return &e.Event }
 
-// ProgressEndEvent: The event signals the end of the progress reporting with an optional final message.
-// This event should only be sent if the client has passed the value true for the 'supportsProgressReporting' capability of the 'initialize' request.
+// ProgressEndEvent: The event signals the end of the progress reporting with a final message.
+// This event should only be sent if the corresponding capability `supportsProgressReporting` is true.
 type ProgressEndEvent struct {
 	Event
 
@@ -379,7 +377,7 @@ func (e *ProgressEndEvent) GetEvent() *Event { return &e.Event }
 
 // InvalidatedEvent: This event signals that some state in the debug adapter has changed and requires that the client needs to re-render the data snapshot previously requested.
 // Debug adapters do not have to emit this event for runtime changes like stopped or thread events because in that case the client refetches the new state anyway. But the event can be used for example to refresh the UI after rendering formatting has changed in the debug adapter.
-// This event should only be sent if the debug adapter has received a value true for the 'supportsInvalidatedEvent' capability of the 'initialize' request.
+// This event should only be sent if the corresponding capability `supportsInvalidatedEvent` is true.
 type InvalidatedEvent struct {
 	Event
 
@@ -394,9 +392,9 @@ type InvalidatedEventBody struct {
 
 func (e *InvalidatedEvent) GetEvent() *Event { return &e.Event }
 
-// MemoryEvent: This event indicates that some memory range has been updated. It should only be sent if the debug adapter has received a value true for the `supportsMemoryEvent` capability of the `initialize` request.
+// MemoryEvent: This event indicates that some memory range has been updated. It should only be sent if the corresponding capability `supportsMemoryEvent` is true.
 // Clients typically react to the event by re-issuing a `readMemory` request if they show the memory identified by the `memoryReference` and if the updated memory range overlaps the displayed range. Clients should not make assumptions how individual memory references relate to each other, so they should not assume that they are part of a single continuous address range and might overlap.
-// Debug adapters can use this event to indicate that the contents of a memory range has changed due to some other DAP request like `setVariable` or `setExpression`. Debug adapters are not expected to emit this event for each and every memory change of a running program, because that information is typically not available from debuggers and it would flood clients with too many events.
+// Debug adapters can use this event to indicate that the contents of a memory range has changed due to some other request like `setVariable` or `setExpression`. Debug adapters are not expected to emit this event for each and every memory change of a running program, because that information is typically not available from debuggers and it would flood clients with too many events.
 type MemoryEvent struct {
 	Event
 
@@ -411,9 +409,11 @@ type MemoryEventBody struct {
 
 func (e *MemoryEvent) GetEvent() *Event { return &e.Event }
 
-// RunInTerminalRequest: This optional request is sent from the debug adapter to the client to run a command in a terminal.
+// RunInTerminalRequest: This request is sent from the debug adapter to the client to run a command in a terminal.
 // This is typically used to launch the debuggee in a terminal provided by the client.
-// This request should only be called if the client has passed the value true for the 'supportsRunInTerminalRequest' capability of the 'initialize' request.
+// This request should only be called if the corresponding client capability `supportsRunInTerminalRequest` is true.
+// Client implementations of `runInTerminal` are free to run the command however they choose including issuing the command to a command line interpreter (aka 'shell'). Argument strings passed to the `runInTerminal` request must arrive verbatim in the command to be run. As a consequence, clients which use a shell are responsible for escaping any special shell characters in the argument strings to prevent them from being interpreted (and modified) by the shell.
+// Some users may wish to take advantage of shell processing in the argument strings. For clients which implement `runInTerminal` using an intermediary shell, the `argsCanBeInterpretedByShell` property can be set to true. In this case the client is requested not to escape any special shell characters in the argument strings.
 type RunInTerminalRequest struct {
 	Request
 
@@ -422,16 +422,17 @@ type RunInTerminalRequest struct {
 
 func (r *RunInTerminalRequest) GetRequest() *Request { return &r.Request }
 
-// RunInTerminalRequestArguments: Arguments for 'runInTerminal' request.
+// RunInTerminalRequestArguments: Arguments for `runInTerminal` request.
 type RunInTerminalRequestArguments struct {
-	Kind  string                 `json:"kind,omitempty"`
-	Title string                 `json:"title,omitempty"`
-	Cwd   string                 `json:"cwd"`
-	Args  []string               `json:"args"`
-	Env   map[string]interface{} `json:"env,omitempty"`
+	Kind                        string                 `json:"kind,omitempty"`
+	Title                       string                 `json:"title,omitempty"`
+	Cwd                         string                 `json:"cwd"`
+	Args                        []string               `json:"args"`
+	Env                         map[string]interface{} `json:"env,omitempty"`
+	ArgsCanBeInterpretedByShell bool                   `json:"argsCanBeInterpretedByShell,omitempty"`
 }
 
-// RunInTerminalResponse: Response to 'runInTerminal' request.
+// RunInTerminalResponse: Response to `runInTerminal` request.
 type RunInTerminalResponse struct {
 	Response
 
@@ -445,11 +446,34 @@ type RunInTerminalResponseBody struct {
 
 func (r *RunInTerminalResponse) GetResponse() *Response { return &r.Response }
 
-// InitializeRequest: The 'initialize' request is sent as the first request from the client to the debug adapter
-// in order to configure it with client capabilities and to retrieve capabilities from the debug adapter.
-// Until the debug adapter has responded to with an 'initialize' response, the client must not send any additional requests or events to the debug adapter.
-// In addition the debug adapter is not allowed to send any requests or events to the client until it has responded with an 'initialize' response.
-// The 'initialize' request may only be sent once.
+// StartDebuggingRequest: This request is sent from the debug adapter to the client to start a new debug session of the same type as the caller.
+// This request should only be sent if the corresponding client capability `supportsStartDebuggingRequest` is true.
+// A client implementation of `startDebugging` should start a new debug session (of the same type as the caller) in the same way that the caller's session was started. If the client supports hierarchical debug sessions, the newly created session can be treated as a child of the caller session.
+type StartDebuggingRequest struct {
+	Request
+
+	Arguments StartDebuggingRequestArguments `json:"arguments"`
+}
+
+func (r *StartDebuggingRequest) GetRequest() *Request { return &r.Request }
+
+// StartDebuggingRequestArguments: Arguments for `startDebugging` request.
+type StartDebuggingRequestArguments struct {
+	Configuration map[string]interface{} `json:"configuration"`
+	Request       string                 `json:"request"`
+}
+
+// StartDebuggingResponse: Response to `startDebugging` request. This is just an acknowledgement, so no body field is required.
+type StartDebuggingResponse struct {
+	Response
+}
+
+func (r *StartDebuggingResponse) GetResponse() *Response { return &r.Response }
+
+// InitializeRequest: The `initialize` request is sent as the first request from the client to the debug adapter in order to configure it with client capabilities and to retrieve capabilities from the debug adapter.
+// Until the debug adapter has responded with an `initialize` response, the client must not send any additional requests or events to the debug adapter.
+// In addition the debug adapter is not allowed to send any requests or events to the client until it has responded with an `initialize` response.
+// The `initialize` request may only be sent once.
 type InitializeRequest struct {
 	Request
 
@@ -458,25 +482,27 @@ type InitializeRequest struct {
 
 func (r *InitializeRequest) GetRequest() *Request { return &r.Request }
 
-// InitializeRequestArguments: Arguments for 'initialize' request.
+// InitializeRequestArguments: Arguments for `initialize` request.
 type InitializeRequestArguments struct {
-	ClientID                     string `json:"clientID,omitempty"`
-	ClientName                   string `json:"clientName,omitempty"`
-	AdapterID                    string `json:"adapterID"`
-	Locale                       string `json:"locale,omitempty"`
-	LinesStartAt1                bool   `json:"linesStartAt1"`
-	ColumnsStartAt1              bool   `json:"columnsStartAt1"`
-	PathFormat                   string `json:"pathFormat,omitempty"`
-	SupportsVariableType         bool   `json:"supportsVariableType,omitempty"`
-	SupportsVariablePaging       bool   `json:"supportsVariablePaging,omitempty"`
-	SupportsRunInTerminalRequest bool   `json:"supportsRunInTerminalRequest,omitempty"`
-	SupportsMemoryReferences     bool   `json:"supportsMemoryReferences,omitempty"`
-	SupportsProgressReporting    bool   `json:"supportsProgressReporting,omitempty"`
-	SupportsInvalidatedEvent     bool   `json:"supportsInvalidatedEvent,omitempty"`
-	SupportsMemoryEvent          bool   `json:"supportsMemoryEvent,omitempty"`
-}
-
-// InitializeResponse: Response to 'initialize' request.
+	ClientID                            string `json:"clientID,omitempty"`
+	ClientName                          string `json:"clientName,omitempty"`
+	AdapterID                           string `json:"adapterID"`
+	Locale                              string `json:"locale,omitempty"`
+	LinesStartAt1                       bool   `json:"linesStartAt1"`
+	ColumnsStartAt1                     bool   `json:"columnsStartAt1"`
+	PathFormat                          string `json:"pathFormat,omitempty"`
+	SupportsVariableType                bool   `json:"supportsVariableType,omitempty"`
+	SupportsVariablePaging              bool   `json:"supportsVariablePaging,omitempty"`
+	SupportsRunInTerminalRequest        bool   `json:"supportsRunInTerminalRequest,omitempty"`
+	SupportsMemoryReferences            bool   `json:"supportsMemoryReferences,omitempty"`
+	SupportsProgressReporting           bool   `json:"supportsProgressReporting,omitempty"`
+	SupportsInvalidatedEvent            bool   `json:"supportsInvalidatedEvent,omitempty"`
+	SupportsMemoryEvent                 bool   `json:"supportsMemoryEvent,omitempty"`
+	SupportsArgsCanBeInterpretedByShell bool   `json:"supportsArgsCanBeInterpretedByShell,omitempty"`
+	SupportsStartDebuggingRequest       bool   `json:"supportsStartDebuggingRequest,omitempty"`
+}
+
+// InitializeResponse: Response to `initialize` request.
 type InitializeResponse struct {
 	Response
 
@@ -485,29 +511,29 @@ type InitializeResponse struct {
 
 func (r *InitializeResponse) GetResponse() *Response { return &r.Response }
 
-// ConfigurationDoneRequest: This optional request indicates that the client has finished initialization of the debug adapter.
-// So it is the last request in the sequence of configuration requests (which was started by the 'initialized' event).
-// Clients should only call this request if the capability 'supportsConfigurationDoneRequest' is true.
+// ConfigurationDoneRequest: This request indicates that the client has finished initialization of the debug adapter.
+// So it is the last request in the sequence of configuration requests (which was started by the `initialized` event).
+// Clients should only call this request if the corresponding capability `supportsConfigurationDoneRequest` is true.
 type ConfigurationDoneRequest struct {
 	Request
 
-	Arguments ConfigurationDoneArguments `json:"arguments,omitempty"`
+	Arguments *ConfigurationDoneArguments `json:"arguments,omitempty"`
 }
 
 func (r *ConfigurationDoneRequest) GetRequest() *Request { return &r.Request }
 
-// ConfigurationDoneArguments: Arguments for 'configurationDone' request.
+// ConfigurationDoneArguments: Arguments for `configurationDone` request.
 type ConfigurationDoneArguments struct {
 }
 
-// ConfigurationDoneResponse: Response to 'configurationDone' request. This is just an acknowledgement, so no body field is required.
+// ConfigurationDoneResponse: Response to `configurationDone` request. This is just an acknowledgement, so no body field is required.
 type ConfigurationDoneResponse struct {
 	Response
 }
 
 func (r *ConfigurationDoneResponse) GetResponse() *Response { return &r.Response }
 
-// LaunchRequest: This launch request is sent from the client to the debug adapter to start the debuggee with or without debugging (if 'noDebug' is true).
+// LaunchRequest: This launch request is sent from the client to the debug adapter to start the debuggee with or without debugging (if `noDebug` is true).
 // Since launching is debugger/runtime specific, the arguments for this request are not part of this specification.
 type LaunchRequest struct {
 	Request
@@ -518,14 +544,14 @@ type LaunchRequest struct {
 func (r *LaunchRequest) GetRequest() *Request          { return &r.Request }
 func (r *LaunchRequest) GetArguments() json.RawMessage { return r.Arguments }
 
-// LaunchResponse: Response to 'launch' request. This is just an acknowledgement, so no body field is required.
+// LaunchResponse: Response to `launch` request. This is just an acknowledgement, so no body field is required.
 type LaunchResponse struct {
 	Response
 }
 
 func (r *LaunchResponse) GetResponse() *Response { return &r.Response }
 
-// AttachRequest: The attach request is sent from the client to the debug adapter to attach to a debuggee that is already running.
+// AttachRequest: The `attach` request is sent from the client to the debug adapter to attach to a debuggee that is already running.
 // Since attaching is debugger/runtime specific, the arguments for this request are not part of this specification.
 type AttachRequest struct {
 	Request
@@ -536,95 +562,95 @@ type AttachRequest struct {
 func (r *AttachRequest) GetRequest() *Request          { return &r.Request }
 func (r *AttachRequest) GetArguments() json.RawMessage { return r.Arguments }
 
-// AttachResponse: Response to 'attach' request. This is just an acknowledgement, so no body field is required.
+// AttachResponse: Response to `attach` request. This is just an acknowledgement, so no body field is required.
 type AttachResponse struct {
 	Response
 }
 
 func (r *AttachResponse) GetResponse() *Response { return &r.Response }
 
-// RestartRequest: Restarts a debug session. Clients should only call this request if the capability 'supportsRestartRequest' is true.
-// If the capability is missing or has the value false, a typical client will emulate 'restart' by terminating the debug adapter first and then launching it anew.
+// RestartRequest: Restarts a debug session. Clients should only call this request if the corresponding capability `supportsRestartRequest` is true.
+// If the capability is missing or has the value false, a typical client emulates `restart` by terminating the debug adapter first and then launching it anew.
 type RestartRequest struct {
 	Request
 
-	Arguments RestartArguments `json:"arguments,omitempty"`
+	Arguments *RestartArguments `json:"arguments,omitempty"`
 }
 
 func (r *RestartRequest) GetRequest() *Request { return &r.Request }
 
-// RestartArguments: Arguments for 'restart' request.
+// RestartArguments: Arguments for `restart` request.
 type RestartArguments struct {
 	Arguments interface{} `json:"arguments,omitempty"`
 }
 
-// RestartResponse: Response to 'restart' request. This is just an acknowledgement, so no body field is required.
+// RestartResponse: Response to `restart` request. This is just an acknowledgement, so no body field is required.
 type RestartResponse struct {
 	Response
 }
 
 func (r *RestartResponse) GetResponse() *Response { return &r.Response }
 
-// DisconnectRequest: The 'disconnect' request is sent from the client to the debug adapter in order to stop debugging.
-// It asks the debug adapter to disconnect from the debuggee and to terminate the debug adapter.
-// If the debuggee has been started with the 'launch' request, the 'disconnect' request terminates the debuggee.
-// If the 'attach' request was used to connect to the debuggee, 'disconnect' does not terminate the debuggee.
-// This behavior can be controlled with the 'terminateDebuggee' argument (if supported by the debug adapter).
+// DisconnectRequest: The `disconnect` request asks the debug adapter to disconnect from the debuggee (thus ending the debug session) and then to shut down itself (the debug adapter).
+// In addition, the debug adapter must terminate the debuggee if it was started with the `launch` request. If an `attach` request was used to connect to the debuggee, then the debug adapter must not terminate the debuggee.
+// This implicit behavior of when to terminate the debuggee can be overridden with the `terminateDebuggee` argument (which is only supported by a debug adapter if the corresponding capability `supportTerminateDebuggee` is true).
 type DisconnectRequest struct {
 	Request
 
-	Arguments DisconnectArguments `json:"arguments,omitempty"`
+	Arguments *DisconnectArguments `json:"arguments,omitempty"`
 }
 
 func (r *DisconnectRequest) GetRequest() *Request { return &r.Request }
 
-// DisconnectArguments: Arguments for 'disconnect' request.
+// DisconnectArguments: Arguments for `disconnect` request.
 type DisconnectArguments struct {
 	Restart           bool `json:"restart,omitempty"`
 	TerminateDebuggee bool `json:"terminateDebuggee,omitempty"`
 	SuspendDebuggee   bool `json:"suspendDebuggee,omitempty"`
 }
 
-// DisconnectResponse: Response to 'disconnect' request. This is just an acknowledgement, so no body field is required.
+// DisconnectResponse: Response to `disconnect` request. This is just an acknowledgement, so no body field is required.
 type DisconnectResponse struct {
 	Response
 }
 
 func (r *DisconnectResponse) GetResponse() *Response { return &r.Response }
 
-// TerminateRequest: The 'terminate' request is sent from the client to the debug adapter in order to give the debuggee a chance for terminating itself.
-// Clients should only call this request if the capability 'supportsTerminateRequest' is true.
+// TerminateRequest: The `terminate` request is sent from the client to the debug adapter in order to shut down the debuggee gracefully. Clients should only call this request if the capability `supportsTerminateRequest` is true.
+// Typically a debug adapter implements `terminate` by sending a software signal which the debuggee intercepts in order to clean things up properly before terminating itself.
+// Please note that this request does not directly affect the state of the debug session: if the debuggee decides to veto the graceful shutdown for any reason by not terminating itself, then the debug session just continues.
+// Clients can surface the `terminate` request as an explicit command or they can integrate it into a two stage Stop command that first sends `terminate` to request a graceful shutdown, and if that fails uses `disconnect` for a forceful shutdown.
 type TerminateRequest struct {
 	Request
 
-	Arguments TerminateArguments `json:"arguments,omitempty"`
+	Arguments *TerminateArguments `json:"arguments,omitempty"`
 }
 
 func (r *TerminateRequest) GetRequest() *Request { return &r.Request }
 
-// TerminateArguments: Arguments for 'terminate' request.
+// TerminateArguments: Arguments for `terminate` request.
 type TerminateArguments struct {
 	Restart bool `json:"restart,omitempty"`
 }
 
-// TerminateResponse: Response to 'terminate' request. This is just an acknowledgement, so no body field is required.
+// TerminateResponse: Response to `terminate` request. This is just an acknowledgement, so no body field is required.
 type TerminateResponse struct {
 	Response
 }
 
 func (r *TerminateResponse) GetResponse() *Response { return &r.Response }
 
-// BreakpointLocationsRequest: The 'breakpointLocations' request returns all possible locations for source breakpoints in a given range.
-// Clients should only call this request if the capability 'supportsBreakpointLocationsRequest' is true.
+// BreakpointLocationsRequest: The `breakpointLocations` request returns all possible locations for source breakpoints in a given range.
+// Clients should only call this request if the corresponding capability `supportsBreakpointLocationsRequest` is true.
 type BreakpointLocationsRequest struct {
 	Request
 
-	Arguments BreakpointLocationsArguments `json:"arguments,omitempty"`
+	Arguments *BreakpointLocationsArguments `json:"arguments,omitempty"`
 }
 
 func (r *BreakpointLocationsRequest) GetRequest() *Request { return &r.Request }
 
-// BreakpointLocationsArguments: Arguments for 'breakpointLocations' request.
+// BreakpointLocationsArguments: Arguments for `breakpointLocations` request.
 type BreakpointLocationsArguments struct {
 	Source    Source `json:"source"`
 	Line      int    `json:"line"`
@@ -633,7 +659,7 @@ type BreakpointLocationsArguments struct {
 	EndColumn int    `json:"endColumn,omitempty"`
 }
 
-// BreakpointLocationsResponse: Response to 'breakpointLocations' request.
+// BreakpointLocationsResponse: Response to `breakpointLocations` request.
 // Contains possible locations for source breakpoints.
 type BreakpointLocationsResponse struct {
 	Response
@@ -649,7 +675,7 @@ func (r *BreakpointLocationsResponse) GetResponse() *Response { return &r.Respon
 
 // SetBreakpointsRequest: Sets multiple breakpoints for a single source and clears all previous breakpoints in that source.
 // To clear all breakpoint for a source, specify an empty array.
-// When a breakpoint is hit, a 'stopped' event (with reason 'breakpoint') is generated.
+// When a breakpoint is hit, a `stopped` event (with reason `breakpoint`) is generated.
 type SetBreakpointsRequest struct {
 	Request
 
@@ -658,7 +684,7 @@ type SetBreakpointsRequest struct {
 
 func (r *SetBreakpointsRequest) GetRequest() *Request { return &r.Request }
 
-// SetBreakpointsArguments: Arguments for 'setBreakpoints' request.
+// SetBreakpointsArguments: Arguments for `setBreakpoints` request.
 type SetBreakpointsArguments struct {
 	Source         Source             `json:"source"`
 	Breakpoints    []SourceBreakpoint `json:"breakpoints,omitempty"`
@@ -666,11 +692,11 @@ type SetBreakpointsArguments struct {
 	SourceModified bool               `json:"sourceModified,omitempty"`
 }
 
-// SetBreakpointsResponse: Response to 'setBreakpoints' request.
+// SetBreakpointsResponse: Response to `setBreakpoints` request.
 // Returned is information about each breakpoint created by this request.
 // This includes the actual code location and whether the breakpoint could be verified.
-// The breakpoints returned are in the same order as the elements of the 'breakpoints'
-// (or the deprecated 'lines') array in the arguments.
+// The breakpoints returned are in the same order as the elements of the `breakpoints`
+// (or the deprecated `lines`) array in the arguments.
 type SetBreakpointsResponse struct {
 	Response
 
@@ -685,8 +711,8 @@ func (r *SetBreakpointsResponse) GetResponse() *Response { return &r.Response }
 
 // SetFunctionBreakpointsRequest: Replaces all existing function breakpoints with new function breakpoints.
 // To clear all function breakpoints, specify an empty array.
-// When a function breakpoint is hit, a 'stopped' event (with reason 'function breakpoint') is generated.
-// Clients should only call this request if the capability 'supportsFunctionBreakpoints' is true.
+// When a function breakpoint is hit, a `stopped` event (with reason `function breakpoint`) is generated.
+// Clients should only call this request if the corresponding capability `supportsFunctionBreakpoints` is true.
 type SetFunctionBreakpointsRequest struct {
 	Request
 
@@ -695,12 +721,12 @@ type SetFunctionBreakpointsRequest struct {
 
 func (r *SetFunctionBreakpointsRequest) GetRequest() *Request { return &r.Request }
 
-// SetFunctionBreakpointsArguments: Arguments for 'setFunctionBreakpoints' request.
+// SetFunctionBreakpointsArguments: Arguments for `setFunctionBreakpoints` request.
 type SetFunctionBreakpointsArguments struct {
 	Breakpoints []FunctionBreakpoint `json:"breakpoints"`
 }
 
-// SetFunctionBreakpointsResponse: Response to 'setFunctionBreakpoints' request.
+// SetFunctionBreakpointsResponse: Response to `setFunctionBreakpoints` request.
 // Returned is information about each breakpoint created by this request.
 type SetFunctionBreakpointsResponse struct {
 	Response
@@ -714,9 +740,9 @@ type SetFunctionBreakpointsResponseBody struct {
 
 func (r *SetFunctionBreakpointsResponse) GetResponse() *Response { return &r.Response }
 
-// SetExceptionBreakpointsRequest: The request configures the debuggers response to thrown exceptions.
-// If an exception is configured to break, a 'stopped' event is fired (with reason 'exception').
-// Clients should only call this request if the capability 'exceptionBreakpointFilters' returns one or more filters.
+// SetExceptionBreakpointsRequest: The request configures the debugger's response to thrown exceptions.
+// If an exception is configured to break, a `stopped` event is fired (with reason `exception`).
+// Clients should only call this request if the corresponding capability `exceptionBreakpointFilters` returns one or more filters.
 type SetExceptionBreakpointsRequest struct {
 	Request
 
@@ -725,17 +751,17 @@ type SetExceptionBreakpointsRequest struct {
 
 func (r *SetExceptionBreakpointsRequest) GetRequest() *Request { return &r.Request }
 
-// SetExceptionBreakpointsArguments: Arguments for 'setExceptionBreakpoints' request.
+// SetExceptionBreakpointsArguments: Arguments for `setExceptionBreakpoints` request.
 type SetExceptionBreakpointsArguments struct {
 	Filters          []string                 `json:"filters"`
 	FilterOptions    []ExceptionFilterOptions `json:"filterOptions,omitempty"`
 	ExceptionOptions []ExceptionOptions       `json:"exceptionOptions,omitempty"`
 }
 
-// SetExceptionBreakpointsResponse: Response to 'setExceptionBreakpoints' request.
-// The response contains an array of Breakpoint objects with information about each exception breakpoint or filter. The Breakpoint objects are in the same order as the elements of the 'filters', 'filterOptions', 'exceptionOptions' arrays given as arguments. If both 'filters' and 'filterOptions' are given, the returned array must start with 'filters' information first, followed by 'filterOptions' information.
-// The mandatory 'verified' property of a Breakpoint object signals whether the exception breakpoint or filter could be successfully created and whether the optional condition or hit count expressions are valid. In case of an error the 'message' property explains the problem. An optional 'id' property can be used to introduce a unique ID for the exception breakpoint or filter so that it can be updated subsequently by sending breakpoint events.
-// For backward compatibility both the 'breakpoints' array and the enclosing 'body' are optional. If these elements are missing a client will not be able to show problems for individual exception breakpoints or filters.
+// SetExceptionBreakpointsResponse: Response to `setExceptionBreakpoints` request.
+// The response contains an array of `Breakpoint` objects with information about each exception breakpoint or filter. The `Breakpoint` objects are in the same order as the elements of the `filters`, `filterOptions`, `exceptionOptions` arrays given as arguments. If both `filters` and `filterOptions` are given, the returned array must start with `filters` information first, followed by `filterOptions` information.
+// The `verified` property of a `Breakpoint` object signals whether the exception breakpoint or filter could be successfully created and whether the condition or hit count expressions are valid. In case of an error the `message` property explains the problem. The `id` property can be used to introduce a unique ID for the exception breakpoint or filter so that it can be updated subsequently by sending breakpoint events.
+// For backward compatibility both the `breakpoints` array and the enclosing `body` are optional. If these elements are missing a client is not able to show problems for individual exception breakpoints or filters.
 type SetExceptionBreakpointsResponse struct {
 	Response
 
@@ -749,7 +775,7 @@ type SetExceptionBreakpointsResponseBody struct {
 func (r *SetExceptionBreakpointsResponse) GetResponse() *Response { return &r.Response }
 
 // DataBreakpointInfoRequest: Obtains information on a possible data breakpoint that could be set on an expression or variable.
-// Clients should only call this request if the capability 'supportsDataBreakpoints' is true.
+// Clients should only call this request if the corresponding capability `supportsDataBreakpoints` is true.
 type DataBreakpointInfoRequest struct {
 	Request
 
@@ -758,13 +784,14 @@ type DataBreakpointInfoRequest struct {
 
 func (r *DataBreakpointInfoRequest) GetRequest() *Request { return &r.Request }
 
-// DataBreakpointInfoArguments: Arguments for 'dataBreakpointInfo' request.
+// DataBreakpointInfoArguments: Arguments for `dataBreakpointInfo` request.
 type DataBreakpointInfoArguments struct {
 	VariablesReference int    `json:"variablesReference,omitempty"`
 	Name               string `json:"name"`
+	FrameId            int    `json:"frameId,omitempty"`
 }
 
-// DataBreakpointInfoResponse: Response to 'dataBreakpointInfo' request.
+// DataBreakpointInfoResponse: Response to `dataBreakpointInfo` request.
 type DataBreakpointInfoResponse struct {
 	Response
 
@@ -782,8 +809,8 @@ func (r *DataBreakpointInfoResponse) GetResponse() *Response { return &r.Respons
 
 // SetDataBreakpointsRequest: Replaces all existing data breakpoints with new data breakpoints.
 // To clear all data breakpoints, specify an empty array.
-// When a data breakpoint is hit, a 'stopped' event (with reason 'data breakpoint') is generated.
-// Clients should only call this request if the capability 'supportsDataBreakpoints' is true.
+// When a data breakpoint is hit, a `stopped` event (with reason `data breakpoint`) is generated.
+// Clients should only call this request if the corresponding capability `supportsDataBreakpoints` is true.
 type SetDataBreakpointsRequest struct {
 	Request
 
@@ -792,12 +819,12 @@ type SetDataBreakpointsRequest struct {
 
 func (r *SetDataBreakpointsRequest) GetRequest() *Request { return &r.Request }
 
-// SetDataBreakpointsArguments: Arguments for 'setDataBreakpoints' request.
+// SetDataBreakpointsArguments: Arguments for `setDataBreakpoints` request.
 type SetDataBreakpointsArguments struct {
 	Breakpoints []DataBreakpoint `json:"breakpoints"`
 }
 
-// SetDataBreakpointsResponse: Response to 'setDataBreakpoints' request.
+// SetDataBreakpointsResponse: Response to `setDataBreakpoints` request.
 // Returned is information about each breakpoint created by this request.
 type SetDataBreakpointsResponse struct {
 	Response
@@ -811,10 +838,10 @@ type SetDataBreakpointsResponseBody struct {
 
 func (r *SetDataBreakpointsResponse) GetResponse() *Response { return &r.Response }
 
-// SetInstructionBreakpointsRequest: Replaces all existing instruction breakpoints. Typically, instruction breakpoints would be set from a diassembly window.
+// SetInstructionBreakpointsRequest: Replaces all existing instruction breakpoints. Typically, instruction breakpoints would be set from a disassembly window.
 // To clear all instruction breakpoints, specify an empty array.
-// When an instruction breakpoint is hit, a 'stopped' event (with reason 'instruction breakpoint') is generated.
-// Clients should only call this request if the capability 'supportsInstructionBreakpoints' is true.
+// When an instruction breakpoint is hit, a `stopped` event (with reason `instruction breakpoint`) is generated.
+// Clients should only call this request if the corresponding capability `supportsInstructionBreakpoints` is true.
 type SetInstructionBreakpointsRequest struct {
 	Request
 
@@ -823,12 +850,12 @@ type SetInstructionBreakpointsRequest struct {
 
 func (r *SetInstructionBreakpointsRequest) GetRequest() *Request { return &r.Request }
 
-// SetInstructionBreakpointsArguments: Arguments for 'setInstructionBreakpoints' request
+// SetInstructionBreakpointsArguments: Arguments for `setInstructionBreakpoints` request
 type SetInstructionBreakpointsArguments struct {
 	Breakpoints []InstructionBreakpoint `json:"breakpoints"`
 }
 
-// SetInstructionBreakpointsResponse: Response to 'setInstructionBreakpoints' request
+// SetInstructionBreakpointsResponse: Response to `setInstructionBreakpoints` request
 type SetInstructionBreakpointsResponse struct {
 	Response
 
@@ -841,7 +868,7 @@ type SetInstructionBreakpointsResponseBody struct {
 
 func (r *SetInstructionBreakpointsResponse) GetResponse() *Response { return &r.Response }
 
-// ContinueRequest: The request starts the debuggee to run again.
+// ContinueRequest: The request resumes execution of all threads. If the debug adapter supports single thread execution (see capability `supportsSingleThreadExecutionRequests`), setting the `singleThread` argument to true resumes only the specified thread. If not all threads were resumed, the `allThreadsContinued` attribute of the response should be set to false.
 type ContinueRequest struct {
 	Request
 
@@ -850,12 +877,13 @@ type ContinueRequest struct {
 
 func (r *ContinueRequest) GetRequest() *Request { return &r.Request }
 
-// ContinueArguments: Arguments for 'continue' request.
+// ContinueArguments: Arguments for `continue` request.
 type ContinueArguments struct {
-	ThreadId int `json:"threadId"`
+	ThreadId     int  `json:"threadId"`
+	SingleThread bool `json:"singleThread,omitempty"`
 }
 
-// ContinueResponse: Response to 'continue' request.
+// ContinueResponse: Response to `continue` request.
 type ContinueResponse struct {
 	Response
 
@@ -868,8 +896,9 @@ type ContinueResponseBody struct {
 
 func (r *ContinueResponse) GetResponse() *Response { return &r.Response }
 
-// NextRequest: The request starts the debuggee to run again for one step.
-// The debug adapter first sends the response and then a 'stopped' event (with reason 'step') after the step has completed.
+// NextRequest: The request executes one step (in the given granularity) for the specified thread and allows all other threads to run freely by resuming them.
+// If the debug adapter supports single thread execution (see capability `supportsSingleThreadExecutionRequests`), setting the `singleThread` argument to true prevents other suspended threads from resuming.
+// The debug adapter first sends the response and then a `stopped` event (with reason `step`) after the step has completed.
 type NextRequest struct {
 	Request
 
@@ -878,25 +907,27 @@ type NextRequest struct {
 
 func (r *NextRequest) GetRequest() *Request { return &r.Request }
 
-// NextArguments: Arguments for 'next' request.
+// NextArguments: Arguments for `next` request.
 type NextArguments struct {
-	ThreadId    int                 `json:"threadId"`
-	Granularity SteppingGranularity `json:"granularity,omitempty"`
+	ThreadId     int                 `json:"threadId"`
+	SingleThread bool                `json:"singleThread,omitempty"`
+	Granularity  SteppingGranularity `json:"granularity,omitempty"`
 }
 
-// NextResponse: Response to 'next' request. This is just an acknowledgement, so no body field is required.
+// NextResponse: Response to `next` request. This is just an acknowledgement, so no body field is required.
 type NextResponse struct {
 	Response
 }
 
 func (r *NextResponse) GetResponse() *Response { return &r.Response }
 
-// StepInRequest: The request starts the debuggee to step into a function/method if possible.
-// If it cannot step into a target, 'stepIn' behaves like 'next'.
-// The debug adapter first sends the response and then a 'stopped' event (with reason 'step') after the step has completed.
+// StepInRequest: The request resumes the given thread to step into a function/method and allows all other threads to run freely by resuming them.
+// If the debug adapter supports single thread execution (see capability `supportsSingleThreadExecutionRequests`), setting the `singleThread` argument to true prevents other suspended threads from resuming.
+// If the request cannot step into a target, `stepIn` behaves like the `next` request.
+// The debug adapter first sends the response and then a `stopped` event (with reason `step`) after the step has completed.
 // If there are multiple function/method calls (or other targets) on the source line,
-// the optional argument 'targetId' can be used to control into which target the 'stepIn' should occur.
-// The list of possible targets for a given source line can be retrieved via the 'stepInTargets' request.
+// the argument `targetId` can be used to control into which target the `stepIn` should occur.
+// The list of possible targets for a given source line can be retrieved via the `stepInTargets` request.
 type StepInRequest struct {
 	Request
 
@@ -905,22 +936,24 @@ type StepInRequest struct {
 
 func (r *StepInRequest) GetRequest() *Request { return &r.Request }
 
-// StepInArguments: Arguments for 'stepIn' request.
+// StepInArguments: Arguments for `stepIn` request.
 type StepInArguments struct {
-	ThreadId    int                 `json:"threadId"`
-	TargetId    int                 `json:"targetId,omitempty"`
-	Granularity SteppingGranularity `json:"granularity,omitempty"`
+	ThreadId     int                 `json:"threadId"`
+	SingleThread bool                `json:"singleThread,omitempty"`
+	TargetId     int                 `json:"targetId,omitempty"`
+	Granularity  SteppingGranularity `json:"granularity,omitempty"`
 }
 
-// StepInResponse: Response to 'stepIn' request. This is just an acknowledgement, so no body field is required.
+// StepInResponse: Response to `stepIn` request. This is just an acknowledgement, so no body field is required.
 type StepInResponse struct {
 	Response
 }
 
 func (r *StepInResponse) GetResponse() *Response { return &r.Response }
 
-// StepOutRequest: The request starts the debuggee to run again for one step.
-// The debug adapter first sends the response and then a 'stopped' event (with reason 'step') after the step has completed.
+// StepOutRequest: The request resumes the given thread to step out (return) from a function/method and allows all other threads to run freely by resuming them.
+// If the debug adapter supports single thread execution (see capability `supportsSingleThreadExecutionRequests`), setting the `singleThread` argument to true prevents other suspended threads from resuming.
+// The debug adapter first sends the response and then a `stopped` event (with reason `step`) after the step has completed.
 type StepOutRequest struct {
 	Request
 
@@ -929,22 +962,24 @@ type StepOutRequest struct {
 
 func (r *StepOutRequest) GetRequest() *Request { return &r.Request }
 
-// StepOutArguments: Arguments for 'stepOut' request.
+// StepOutArguments: Arguments for `stepOut` request.
 type StepOutArguments struct {
-	ThreadId    int                 `json:"threadId"`
-	Granularity SteppingGranularity `json:"granularity,omitempty"`
+	ThreadId     int                 `json:"threadId"`
+	SingleThread bool                `json:"singleThread,omitempty"`
+	Granularity  SteppingGranularity `json:"granularity,omitempty"`
 }
 
-// StepOutResponse: Response to 'stepOut' request. This is just an acknowledgement, so no body field is required.
+// StepOutResponse: Response to `stepOut` request. This is just an acknowledgement, so no body field is required.
 type StepOutResponse struct {
 	Response
 }
 
 func (r *StepOutResponse) GetResponse() *Response { return &r.Response }
 
-// StepBackRequest: The request starts the debuggee to run one step backwards.
-// The debug adapter first sends the response and then a 'stopped' event (with reason 'step') after the step has completed.
-// Clients should only call this request if the capability 'supportsStepBack' is true.
+// StepBackRequest: The request executes one backward step (in the given granularity) for the specified thread and allows all other threads to run backward freely by resuming them.
+// If the debug adapter supports single thread execution (see capability `supportsSingleThreadExecutionRequests`), setting the `singleThread` argument to true prevents other suspended threads from resuming.
+// The debug adapter first sends the response and then a `stopped` event (with reason `step`) after the step has completed.
+// Clients should only call this request if the corresponding capability `supportsStepBack` is true.
 type StepBackRequest struct {
 	Request
 
@@ -953,21 +988,22 @@ type StepBackRequest struct {
 
 func (r *StepBackRequest) GetRequest() *Request { return &r.Request }
 
-// StepBackArguments: Arguments for 'stepBack' request.
+// StepBackArguments: Arguments for `stepBack` request.
 type StepBackArguments struct {
-	ThreadId    int                 `json:"threadId"`
-	Granularity SteppingGranularity `json:"granularity,omitempty"`
+	ThreadId     int                 `json:"threadId"`
+	SingleThread bool                `json:"singleThread,omitempty"`
+	Granularity  SteppingGranularity `json:"granularity,omitempty"`
 }
 
-// StepBackResponse: Response to 'stepBack' request. This is just an acknowledgement, so no body field is required.
+// StepBackResponse: Response to `stepBack` request. This is just an acknowledgement, so no body field is required.
 type StepBackResponse struct {
 	Response
 }
 
 func (r *StepBackResponse) GetResponse() *Response { return &r.Response }
 
-// ReverseContinueRequest: The request starts the debuggee to run backward.
-// Clients should only call this request if the capability 'supportsStepBack' is true.
+// ReverseContinueRequest: The request resumes backward execution of all threads. If the debug adapter supports single thread execution (see capability `supportsSingleThreadExecutionRequests`), setting the `singleThread` argument to true resumes only the specified thread. If not all threads were resumed, the `allThreadsContinued` attribute of the response should be set to false.
+// Clients should only call this request if the corresponding capability `supportsStepBack` is true.
 type ReverseContinueRequest struct {
 	Request
 
@@ -976,21 +1012,22 @@ type ReverseContinueRequest struct {
 
 func (r *ReverseContinueRequest) GetRequest() *Request { return &r.Request }
 
-// ReverseContinueArguments: Arguments for 'reverseContinue' request.
+// ReverseContinueArguments: Arguments for `reverseContinue` request.
 type ReverseContinueArguments struct {
-	ThreadId int `json:"threadId"`
+	ThreadId     int  `json:"threadId"`
+	SingleThread bool `json:"singleThread,omitempty"`
 }
 
-// ReverseContinueResponse: Response to 'reverseContinue' request. This is just an acknowledgement, so no body field is required.
+// ReverseContinueResponse: Response to `reverseContinue` request. This is just an acknowledgement, so no body field is required.
 type ReverseContinueResponse struct {
 	Response
 }
 
 func (r *ReverseContinueResponse) GetResponse() *Response { return &r.Response }
 
-// RestartFrameRequest: The request restarts execution of the specified stackframe.
-// The debug adapter first sends the response and then a 'stopped' event (with reason 'restart') after the restart has completed.
-// Clients should only call this request if the capability 'supportsRestartFrame' is true.
+// RestartFrameRequest: The request restarts execution of the specified stack frame.
+// The debug adapter first sends the response and then a `stopped` event (with reason `restart`) after the restart has completed.
+// Clients should only call this request if the corresponding capability `supportsRestartFrame` is true.
 type RestartFrameRequest struct {
 	Request
 
@@ -999,12 +1036,12 @@ type RestartFrameRequest struct {
 
 func (r *RestartFrameRequest) GetRequest() *Request { return &r.Request }
 
-// RestartFrameArguments: Arguments for 'restartFrame' request.
+// RestartFrameArguments: Arguments for `restartFrame` request.
 type RestartFrameArguments struct {
 	FrameId int `json:"frameId"`
 }
 
-// RestartFrameResponse: Response to 'restartFrame' request. This is just an acknowledgement, so no body field is required.
+// RestartFrameResponse: Response to `restartFrame` request. This is just an acknowledgement, so no body field is required.
 type RestartFrameResponse struct {
 	Response
 }
@@ -1012,10 +1049,10 @@ type RestartFrameResponse struct {
 func (r *RestartFrameResponse) GetResponse() *Response { return &r.Response }
 
 // GotoRequest: The request sets the location where the debuggee will continue to run.
-// This makes it possible to skip the execution of code or to executed code again.
+// This makes it possible to skip the execution of code or to execute code again.
 // The code between the current location and the goto target is not executed but skipped.
-// The debug adapter first sends the response and then a 'stopped' event with reason 'goto'.
-// Clients should only call this request if the capability 'supportsGotoTargetsRequest' is true (because only then goto targets exist that can be passed as arguments).
+// The debug adapter first sends the response and then a `stopped` event with reason `goto`.
+// Clients should only call this request if the corresponding capability `supportsGotoTargetsRequest` is true (because only then goto targets exist that can be passed as arguments).
 type GotoRequest struct {
 	Request
 
@@ -1024,13 +1061,13 @@ type GotoRequest struct {
 
 func (r *GotoRequest) GetRequest() *Request { return &r.Request }
 
-// GotoArguments: Arguments for 'goto' request.
+// GotoArguments: Arguments for `goto` request.
 type GotoArguments struct {
 	ThreadId int `json:"threadId"`
 	TargetId int `json:"targetId"`
 }
 
-// GotoResponse: Response to 'goto' request. This is just an acknowledgement, so no body field is required.
+// GotoResponse: Response to `goto` request. This is just an acknowledgement, so no body field is required.
 type GotoResponse struct {
 	Response
 }
@@ -1038,7 +1075,7 @@ type GotoResponse struct {
 func (r *GotoResponse) GetResponse() *Response { return &r.Response }
 
 // PauseRequest: The request suspends the debuggee.
-// The debug adapter first sends the response and then a 'stopped' event (with reason 'pause') after the thread has been paused successfully.
+// The debug adapter first sends the response and then a `stopped` event (with reason `pause`) after the thread has been paused successfully.
 type PauseRequest struct {
 	Request
 
@@ -1047,12 +1084,12 @@ type PauseRequest struct {
 
 func (r *PauseRequest) GetRequest() *Request { return &r.Request }
 
-// PauseArguments: Arguments for 'pause' request.
+// PauseArguments: Arguments for `pause` request.
 type PauseArguments struct {
 	ThreadId int `json:"threadId"`
 }
 
-// PauseResponse: Response to 'pause' request. This is just an acknowledgement, so no body field is required.
+// PauseResponse: Response to `pause` request. This is just an acknowledgement, so no body field is required.
 type PauseResponse struct {
 	Response
 }
@@ -1060,7 +1097,7 @@ type PauseResponse struct {
 func (r *PauseResponse) GetResponse() *Response { return &r.Response }
 
 // StackTraceRequest: The request returns a stacktrace from the current execution state of a given thread.
-// A client can request all stack frames by omitting the startFrame and levels arguments. For performance conscious clients and if the debug adapter's 'supportsDelayedStackTraceLoading' capability is true, stack frames can be retrieved in a piecemeal way with the startFrame and levels arguments. The response of the stackTrace request may contain a totalFrames property that hints at the total number of frames in the stack. If a client needs this total number upfront, it can issue a request for a single (first) frame and depending on the value of totalFrames decide how to proceed. In any case a client should be prepared to receive less frames than requested, which is an indication that the end of the stack has been reached.
+// A client can request all stack frames by omitting the startFrame and levels arguments. For performance-conscious clients and if the corresponding capability `supportsDelayedStackTraceLoading` is true, stack frames can be retrieved in a piecemeal way with the `startFrame` and `levels` arguments. The response of the `stackTrace` request may contain a `totalFrames` property that hints at the total number of frames in the stack. If a client needs this total number upfront, it can issue a request for a single (first) frame and depending on the value of `totalFrames` decide how to proceed. In any case a client should be prepared to receive fewer frames than requested, which is an indication that the end of the stack has been reached.
 type StackTraceRequest struct {
 	Request
 
@@ -1069,15 +1106,15 @@ type StackTraceRequest struct {
 
 func (r *StackTraceRequest) GetRequest() *Request { return &r.Request }
 
-// StackTraceArguments: Arguments for 'stackTrace' request.
+// StackTraceArguments: Arguments for `stackTrace` request.
 type StackTraceArguments struct {
-	ThreadId   int              `json:"threadId"`
-	StartFrame int              `json:"startFrame,omitempty"`
-	Levels     int              `json:"levels,omitempty"`
-	Format     StackFrameFormat `json:"format,omitempty"`
+	ThreadId   int               `json:"threadId"`
+	StartFrame int               `json:"startFrame,omitempty"`
+	Levels     int               `json:"levels,omitempty"`
+	Format     *StackFrameFormat `json:"format,omitempty"`
 }
 
-// StackTraceResponse: Response to 'stackTrace' request.
+// StackTraceResponse: Response to `stackTrace` request.
 type StackTraceResponse struct {
 	Response
 
@@ -1091,7 +1128,7 @@ type StackTraceResponseBody struct {
 
 func (r *StackTraceResponse) GetResponse() *Response { return &r.Response }
 
-// ScopesRequest: The request returns the variable scopes for a given stackframe ID.
+// ScopesRequest: The request returns the variable scopes for a given stack frame ID.
 type ScopesRequest struct {
 	Request
 
@@ -1100,12 +1137,12 @@ type ScopesRequest struct {
 
 func (r *ScopesRequest) GetRequest() *Request { return &r.Request }
 
-// ScopesArguments: Arguments for 'scopes' request.
+// ScopesArguments: Arguments for `scopes` request.
 type ScopesArguments struct {
 	FrameId int `json:"frameId"`
 }
 
-// ScopesResponse: Response to 'scopes' request.
+// ScopesResponse: Response to `scopes` request.
 type ScopesResponse struct {
 	Response
 
@@ -1119,7 +1156,7 @@ type ScopesResponseBody struct {
 func (r *ScopesResponse) GetResponse() *Response { return &r.Response }
 
 // VariablesRequest: Retrieves all child variables for the given variable reference.
-// An optional filter can be used to limit the fetched children to either named or indexed children.
+// A filter can be used to limit the fetched children to either named or indexed children.
 type VariablesRequest struct {
 	Request
 
@@ -1128,16 +1165,16 @@ type VariablesRequest struct {
 
 func (r *VariablesRequest) GetRequest() *Request { return &r.Request }
 
-// VariablesArguments: Arguments for 'variables' request.
+// VariablesArguments: Arguments for `variables` request.
 type VariablesArguments struct {
-	VariablesReference int         `json:"variablesReference"`
-	Filter             string      `json:"filter,omitempty"`
-	Start              int         `json:"start,omitempty"`
-	Count              int         `json:"count,omitempty"`
-	Format             ValueFormat `json:"format,omitempty"`
+	VariablesReference int          `json:"variablesReference"`
+	Filter             string       `json:"filter,omitempty"`
+	Start              int          `json:"start,omitempty"`
+	Count              int          `json:"count,omitempty"`
+	Format             *ValueFormat `json:"format,omitempty"`
 }
 
-// VariablesResponse: Response to 'variables' request.
+// VariablesResponse: Response to `variables` request.
 type VariablesResponse struct {
 	Response
 
@@ -1150,8 +1187,8 @@ type VariablesResponseBody struct {
 
 func (r *VariablesResponse) GetResponse() *Response { return &r.Response }
 
-// SetVariableRequest: Set the variable with the given name in the variable container to a new value. Clients should only call this request if the capability 'supportsSetVariable' is true.
-// If a debug adapter implements both setVariable and setExpression, a client will only use setExpression if the variable has an evaluateName property.
+// SetVariableRequest: Set the variable with the given name in the variable container to a new value. Clients should only call this request if the corresponding capability `supportsSetVariable` is true.
+// If a debug adapter implements both `setVariable` and `setExpression`, a client will only use `setExpression` if the variable has an `evaluateName` property.
 type SetVariableRequest struct {
 	Request
 
@@ -1160,15 +1197,15 @@ type SetVariableRequest struct {
 
 func (r *SetVariableRequest) GetRequest() *Request { return &r.Request }
 
-// SetVariableArguments: Arguments for 'setVariable' request.
+// SetVariableArguments: Arguments for `setVariable` request.
 type SetVariableArguments struct {
-	VariablesReference int         `json:"variablesReference"`
-	Name               string      `json:"name"`
-	Value              string      `json:"value"`
-	Format             ValueFormat `json:"format,omitempty"`
+	VariablesReference int          `json:"variablesReference"`
+	Name               string       `json:"name"`
+	Value              string       `json:"value"`
+	Format             *ValueFormat `json:"format,omitempty"`
 }
 
-// SetVariableResponse: Response to 'setVariable' request.
+// SetVariableResponse: Response to `setVariable` request.
 type SetVariableResponse struct {
 	Response
 
@@ -1194,13 +1231,13 @@ type SourceRequest struct {
 
 func (r *SourceRequest) GetRequest() *Request { return &r.Request }
 
-// SourceArguments: Arguments for 'source' request.
+// SourceArguments: Arguments for `source` request.
 type SourceArguments struct {
-	Source          Source `json:"source,omitempty"`
-	SourceReference int    `json:"sourceReference"`
+	Source          *Source `json:"source,omitempty"`
+	SourceReference int     `json:"sourceReference"`
 }
 
-// SourceResponse: Response to 'source' request.
+// SourceResponse: Response to `source` request.
 type SourceResponse struct {
 	Response
 
@@ -1221,7 +1258,7 @@ type ThreadsRequest struct {
 
 func (r *ThreadsRequest) GetRequest() *Request { return &r.Request }
 
-// ThreadsResponse: Response to 'threads' request.
+// ThreadsResponse: Response to `threads` request.
 type ThreadsResponse struct {
 	Response
 
@@ -1235,7 +1272,7 @@ type ThreadsResponseBody struct {
 func (r *ThreadsResponse) GetResponse() *Response { return &r.Response }
 
 // TerminateThreadsRequest: The request terminates the threads with the given ids.
-// Clients should only call this request if the capability 'supportsTerminateThreadsRequest' is true.
+// Clients should only call this request if the corresponding capability `supportsTerminateThreadsRequest` is true.
 type TerminateThreadsRequest struct {
 	Request
 
@@ -1244,12 +1281,12 @@ type TerminateThreadsRequest struct {
 
 func (r *TerminateThreadsRequest) GetRequest() *Request { return &r.Request }
 
-// TerminateThreadsArguments: Arguments for 'terminateThreads' request.
+// TerminateThreadsArguments: Arguments for `terminateThreads` request.
 type TerminateThreadsArguments struct {
 	ThreadIds []int `json:"threadIds,omitempty"`
 }
 
-// TerminateThreadsResponse: Response to 'terminateThreads' request. This is just an acknowledgement, so no body field is required.
+// TerminateThreadsResponse: Response to `terminateThreads` request. This is just an acknowledgement, no body field is required.
 type TerminateThreadsResponse struct {
 	Response
 }
@@ -1257,7 +1294,7 @@ type TerminateThreadsResponse struct {
 func (r *TerminateThreadsResponse) GetResponse() *Response { return &r.Response }
 
 // ModulesRequest: Modules can be retrieved from the debug adapter with this request which can either return all modules or a range of modules to support paging.
-// Clients should only call this request if the capability 'supportsModulesRequest' is true.
+// Clients should only call this request if the corresponding capability `supportsModulesRequest` is true.
 type ModulesRequest struct {
 	Request
 
@@ -1266,13 +1303,13 @@ type ModulesRequest struct {
 
 func (r *ModulesRequest) GetRequest() *Request { return &r.Request }
 
-// ModulesArguments: Arguments for 'modules' request.
+// ModulesArguments: Arguments for `modules` request.
 type ModulesArguments struct {
 	StartModule int `json:"startModule,omitempty"`
 	ModuleCount int `json:"moduleCount,omitempty"`
 }
 
-// ModulesResponse: Response to 'modules' request.
+// ModulesResponse: Response to `modules` request.
 type ModulesResponse struct {
 	Response
 
@@ -1287,20 +1324,20 @@ type ModulesResponseBody struct {
 func (r *ModulesResponse) GetResponse() *Response { return &r.Response }
 
 // LoadedSourcesRequest: Retrieves the set of all sources currently loaded by the debugged process.
-// Clients should only call this request if the capability 'supportsLoadedSourcesRequest' is true.
+// Clients should only call this request if the corresponding capability `supportsLoadedSourcesRequest` is true.
 type LoadedSourcesRequest struct {
 	Request
 
-	Arguments LoadedSourcesArguments `json:"arguments,omitempty"`
+	Arguments *LoadedSourcesArguments `json:"arguments,omitempty"`
 }
 
 func (r *LoadedSourcesRequest) GetRequest() *Request { return &r.Request }
 
-// LoadedSourcesArguments: Arguments for 'loadedSources' request.
+// LoadedSourcesArguments: Arguments for `loadedSources` request.
 type LoadedSourcesArguments struct {
 }
 
-// LoadedSourcesResponse: Response to 'loadedSources' request.
+// LoadedSourcesResponse: Response to `loadedSources` request.
 type LoadedSourcesResponse struct {
 	Response
 
@@ -1313,7 +1350,7 @@ type LoadedSourcesResponseBody struct {
 
 func (r *LoadedSourcesResponse) GetResponse() *Response { return &r.Response }
 
-// EvaluateRequest: Evaluates the given expression in the context of the top most stack frame.
+// EvaluateRequest: Evaluates the given expression in the context of the topmost stack frame.
 // The expression has access to any variables and arguments that are in scope.
 type EvaluateRequest struct {
 	Request
@@ -1323,15 +1360,15 @@ type EvaluateRequest struct {
 
 func (r *EvaluateRequest) GetRequest() *Request { return &r.Request }
 
-// EvaluateArguments: Arguments for 'evaluate' request.
+// EvaluateArguments: Arguments for `evaluate` request.
 type EvaluateArguments struct {
-	Expression string      `json:"expression"`
-	FrameId    int         `json:"frameId,omitempty"`
-	Context    string      `json:"context,omitempty"`
-	Format     ValueFormat `json:"format,omitempty"`
+	Expression string       `json:"expression"`
+	FrameId    int          `json:"frameId,omitempty"`
+	Context    string       `json:"context,omitempty"`
+	Format     *ValueFormat `json:"format,omitempty"`
 }
 
-// EvaluateResponse: Response to 'evaluate' request.
+// EvaluateResponse: Response to `evaluate` request.
 type EvaluateResponse struct {
 	Response
 
@@ -1339,21 +1376,21 @@ type EvaluateResponse struct {
 }
 
 type EvaluateResponseBody struct {
-	Result             string                   `json:"result"`
-	Type               string                   `json:"type,omitempty"`
-	PresentationHint   VariablePresentationHint `json:"presentationHint,omitempty"`
-	VariablesReference int                      `json:"variablesReference"`
-	NamedVariables     int                      `json:"namedVariables,omitempty"`
-	IndexedVariables   int                      `json:"indexedVariables,omitempty"`
-	MemoryReference    string                   `json:"memoryReference,omitempty"`
+	Result             string                    `json:"result"`
+	Type               string                    `json:"type,omitempty"`
+	PresentationHint   *VariablePresentationHint `json:"presentationHint,omitempty"`
+	VariablesReference int                       `json:"variablesReference"`
+	NamedVariables     int                       `json:"namedVariables,omitempty"`
+	IndexedVariables   int                       `json:"indexedVariables,omitempty"`
+	MemoryReference    string                    `json:"memoryReference,omitempty"`
 }
 
 func (r *EvaluateResponse) GetResponse() *Response { return &r.Response }
 
-// SetExpressionRequest: Evaluates the given 'value' expression and assigns it to the 'expression' which must be a modifiable l-value.
+// SetExpressionRequest: Evaluates the given `value` expression and assigns it to the `expression` which must be a modifiable l-value.
 // The expressions have access to any variables and arguments that are in scope of the specified frame.
-// Clients should only call this request if the capability 'supportsSetExpression' is true.
-// If a debug adapter implements both setExpression and setVariable, a client will only use setExpression if the variable has an evaluateName property.
+// Clients should only call this request if the corresponding capability `supportsSetExpression` is true.
+// If a debug adapter implements both `setExpression` and `setVariable`, a client uses `setExpression` if the variable has an `evaluateName` property.
 type SetExpressionRequest struct {
 	Request
 
@@ -1362,15 +1399,15 @@ type SetExpressionRequest struct {
 
 func (r *SetExpressionRequest) GetRequest() *Request { return &r.Request }
 
-// SetExpressionArguments: Arguments for 'setExpression' request.
+// SetExpressionArguments: Arguments for `setExpression` request.
 type SetExpressionArguments struct {
-	Expression string      `json:"expression"`
-	Value      string      `json:"value"`
-	FrameId    int         `json:"frameId,omitempty"`
-	Format     ValueFormat `json:"format,omitempty"`
+	Expression string       `json:"expression"`
+	Value      string       `json:"value"`
+	FrameId    int          `json:"frameId,omitempty"`
+	Format     *ValueFormat `json:"format,omitempty"`
 }
 
-// SetExpressionResponse: Response to 'setExpression' request.
+// SetExpressionResponse: Response to `setExpression` request.
 type SetExpressionResponse struct {
 	Response
 
@@ -1378,20 +1415,19 @@ type SetExpressionResponse struct {
 }
 
 type SetExpressionResponseBody struct {
-	Value              string                   `json:"value"`
-	Type               string                   `json:"type,omitempty"`
-	PresentationHint   VariablePresentationHint `json:"presentationHint,omitempty"`
-	VariablesReference int                      `json:"variablesReference,omitempty"`
-	NamedVariables     int                      `json:"namedVariables,omitempty"`
-	IndexedVariables   int                      `json:"indexedVariables,omitempty"`
+	Value              string                    `json:"value"`
+	Type               string                    `json:"type,omitempty"`
+	PresentationHint   *VariablePresentationHint `json:"presentationHint,omitempty"`
+	VariablesReference int                       `json:"variablesReference,omitempty"`
+	NamedVariables     int                       `json:"namedVariables,omitempty"`
+	IndexedVariables   int                       `json:"indexedVariables,omitempty"`
 }
 
 func (r *SetExpressionResponse) GetResponse() *Response { return &r.Response }
 
-// StepInTargetsRequest: This request retrieves the possible stepIn targets for the specified stack frame.
-// These targets can be used in the 'stepIn' request.
-// The StepInTargets may only be called if the 'supportsStepInTargetsRequest' capability exists and is true.
-// Clients should only call this request if the capability 'supportsStepInTargetsRequest' is true.
+// StepInTargetsRequest: This request retrieves the possible step-in targets for the specified stack frame.
+// These targets can be used in the `stepIn` request.
+// Clients should only call this request if the corresponding capability `supportsStepInTargetsRequest` is true.
 type StepInTargetsRequest struct {
 	Request
 
@@ -1400,12 +1436,12 @@ type StepInTargetsRequest struct {
 
 func (r *StepInTargetsRequest) GetRequest() *Request { return &r.Request }
 
-// StepInTargetsArguments: Arguments for 'stepInTargets' request.
+// StepInTargetsArguments: Arguments for `stepInTargets` request.
 type StepInTargetsArguments struct {
 	FrameId int `json:"frameId"`
 }
 
-// StepInTargetsResponse: Response to 'stepInTargets' request.
+// StepInTargetsResponse: Response to `stepInTargets` request.
 type StepInTargetsResponse struct {
 	Response
 
@@ -1419,8 +1455,8 @@ type StepInTargetsResponseBody struct {
 func (r *StepInTargetsResponse) GetResponse() *Response { return &r.Response }
 
 // GotoTargetsRequest: This request retrieves the possible goto targets for the specified source location.
-// These targets can be used in the 'goto' request.
-// Clients should only call this request if the capability 'supportsGotoTargetsRequest' is true.
+// These targets can be used in the `goto` request.
+// Clients should only call this request if the corresponding capability `supportsGotoTargetsRequest` is true.
 type GotoTargetsRequest struct {
 	Request
 
@@ -1429,14 +1465,14 @@ type GotoTargetsRequest struct {
 
 func (r *GotoTargetsRequest) GetRequest() *Request { return &r.Request }
 
-// GotoTargetsArguments: Arguments for 'gotoTargets' request.
+// GotoTargetsArguments: Arguments for `gotoTargets` request.
 type GotoTargetsArguments struct {
 	Source Source `json:"source"`
 	Line   int    `json:"line"`
 	Column int    `json:"column,omitempty"`
 }
 
-// GotoTargetsResponse: Response to 'gotoTargets' request.
+// GotoTargetsResponse: Response to `gotoTargets` request.
 type GotoTargetsResponse struct {
 	Response
 
@@ -1450,7 +1486,7 @@ type GotoTargetsResponseBody struct {
 func (r *GotoTargetsResponse) GetResponse() *Response { return &r.Response }
 
 // CompletionsRequest: Returns a list of possible completions for a given caret position and text.
-// Clients should only call this request if the capability 'supportsCompletionsRequest' is true.
+// Clients should only call this request if the corresponding capability `supportsCompletionsRequest` is true.
 type CompletionsRequest struct {
 	Request
 
@@ -1459,7 +1495,7 @@ type CompletionsRequest struct {
 
 func (r *CompletionsRequest) GetRequest() *Request { return &r.Request }
 
-// CompletionsArguments: Arguments for 'completions' request.
+// CompletionsArguments: Arguments for `completions` request.
 type CompletionsArguments struct {
 	FrameId int    `json:"frameId,omitempty"`
 	Text    string `json:"text"`
@@ -1467,7 +1503,7 @@ type CompletionsArguments struct {
 	Line    int    `json:"line,omitempty"`
 }
 
-// CompletionsResponse: Response to 'completions' request.
+// CompletionsResponse: Response to `completions` request.
 type CompletionsResponse struct {
 	Response
 
@@ -1481,7 +1517,7 @@ type CompletionsResponseBody struct {
 func (r *CompletionsResponse) GetResponse() *Response { return &r.Response }
 
 // ExceptionInfoRequest: Retrieves the details of the exception that caused this event to be raised.
-// Clients should only call this request if the capability 'supportsExceptionInfoRequest' is true.
+// Clients should only call this request if the corresponding capability `supportsExceptionInfoRequest` is true.
 type ExceptionInfoRequest struct {
 	Request
 
@@ -1490,12 +1526,12 @@ type ExceptionInfoRequest struct {
 
 func (r *ExceptionInfoRequest) GetRequest() *Request { return &r.Request }
 
-// ExceptionInfoArguments: Arguments for 'exceptionInfo' request.
+// ExceptionInfoArguments: Arguments for `exceptionInfo` request.
 type ExceptionInfoArguments struct {
 	ThreadId int `json:"threadId"`
 }
 
-// ExceptionInfoResponse: Response to 'exceptionInfo' request.
+// ExceptionInfoResponse: Response to `exceptionInfo` request.
 type ExceptionInfoResponse struct {
 	Response
 
@@ -1506,13 +1542,13 @@ type ExceptionInfoResponseBody struct {
 	ExceptionId string             `json:"exceptionId"`
 	Description string             `json:"description,omitempty"`
 	BreakMode   ExceptionBreakMode `json:"breakMode"`
-	Details     ExceptionDetails   `json:"details,omitempty"`
+	Details     *ExceptionDetails  `json:"details,omitempty"`
 }
 
 func (r *ExceptionInfoResponse) GetResponse() *Response { return &r.Response }
 
 // ReadMemoryRequest: Reads bytes from memory at the provided location.
-// Clients should only call this request if the capability 'supportsReadMemoryRequest' is true.
+// Clients should only call this request if the corresponding capability `supportsReadMemoryRequest` is true.
 type ReadMemoryRequest struct {
 	Request
 
@@ -1521,14 +1557,14 @@ type ReadMemoryRequest struct {
 
 func (r *ReadMemoryRequest) GetRequest() *Request { return &r.Request }
 
-// ReadMemoryArguments: Arguments for 'readMemory' request.
+// ReadMemoryArguments: Arguments for `readMemory` request.
 type ReadMemoryArguments struct {
 	MemoryReference string `json:"memoryReference"`
 	Offset          int    `json:"offset,omitempty"`
 	Count           int    `json:"count"`
 }
 
-// ReadMemoryResponse: Response to 'readMemory' request.
+// ReadMemoryResponse: Response to `readMemory` request.
 type ReadMemoryResponse struct {
 	Response
 
@@ -1544,7 +1580,7 @@ type ReadMemoryResponseBody struct {
 func (r *ReadMemoryResponse) GetResponse() *Response { return &r.Response }
 
 // WriteMemoryRequest: Writes bytes to memory at the provided location.
-// Clients should only call this request if the capability 'supportsWriteMemoryRequest' is true.
+// Clients should only call this request if the corresponding capability `supportsWriteMemoryRequest` is true.
 type WriteMemoryRequest struct {
 	Request
 
@@ -1553,7 +1589,7 @@ type WriteMemoryRequest struct {
 
 func (r *WriteMemoryRequest) GetRequest() *Request { return &r.Request }
 
-// WriteMemoryArguments: Arguments for 'writeMemory' request.
+// WriteMemoryArguments: Arguments for `writeMemory` request.
 type WriteMemoryArguments struct {
 	MemoryReference string `json:"memoryReference"`
 	Offset          int    `json:"offset,omitempty"`
@@ -1561,7 +1597,7 @@ type WriteMemoryArguments struct {
 	Data            string `json:"data"`
 }
 
-// WriteMemoryResponse: Response to 'writeMemory' request.
+// WriteMemoryResponse: Response to `writeMemory` request.
 type WriteMemoryResponse struct {
 	Response
 
@@ -1576,7 +1612,7 @@ type WriteMemoryResponseBody struct {
 func (r *WriteMemoryResponse) GetResponse() *Response { return &r.Response }
 
 // DisassembleRequest: Disassembles code stored at the provided location.
-// Clients should only call this request if the capability 'supportsDisassembleRequest' is true.
+// Clients should only call this request if the corresponding capability `supportsDisassembleRequest` is true.
 type DisassembleRequest struct {
 	Request
 
@@ -1585,7 +1621,7 @@ type DisassembleRequest struct {
 
 func (r *DisassembleRequest) GetRequest() *Request { return &r.Request }
 
-// DisassembleArguments: Arguments for 'disassemble' request.
+// DisassembleArguments: Arguments for `disassemble` request.
 type DisassembleArguments struct {
 	MemoryReference   string `json:"memoryReference"`
 	Offset            int    `json:"offset,omitempty"`
@@ -1594,7 +1630,7 @@ type DisassembleArguments struct {
 	ResolveSymbols    bool   `json:"resolveSymbols,omitempty"`
 }
 
-// DisassembleResponse: Response to 'disassemble' request.
+// DisassembleResponse: Response to `disassemble` request.
 type DisassembleResponse struct {
 	Response
 
@@ -1609,47 +1645,48 @@ func (r *DisassembleResponse) GetResponse() *Response { return &r.Response }
 
 // Capabilities: Information about the capabilities of a debug adapter.
 type Capabilities struct {
-	SupportsConfigurationDoneRequest   bool                         `json:"supportsConfigurationDoneRequest,omitempty"`
-	SupportsFunctionBreakpoints        bool                         `json:"supportsFunctionBreakpoints,omitempty"`
-	SupportsConditionalBreakpoints     bool                         `json:"supportsConditionalBreakpoints,omitempty"`
-	SupportsHitConditionalBreakpoints  bool                         `json:"supportsHitConditionalBreakpoints,omitempty"`
-	SupportsEvaluateForHovers          bool                         `json:"supportsEvaluateForHovers,omitempty"`
-	ExceptionBreakpointFilters         []ExceptionBreakpointsFilter `json:"exceptionBreakpointFilters,omitempty"`
-	SupportsStepBack                   bool                         `json:"supportsStepBack,omitempty"`
-	SupportsSetVariable                bool                         `json:"supportsSetVariable,omitempty"`
-	SupportsRestartFrame               bool                         `json:"supportsRestartFrame,omitempty"`
-	SupportsGotoTargetsRequest         bool                         `json:"supportsGotoTargetsRequest,omitempty"`
-	SupportsStepInTargetsRequest       bool                         `json:"supportsStepInTargetsRequest,omitempty"`
-	SupportsCompletionsRequest         bool                         `json:"supportsCompletionsRequest,omitempty"`
-	CompletionTriggerCharacters        []string                     `json:"completionTriggerCharacters,omitempty"`
-	SupportsModulesRequest             bool                         `json:"supportsModulesRequest,omitempty"`
-	AdditionalModuleColumns            []ColumnDescriptor           `json:"additionalModuleColumns,omitempty"`
-	SupportedChecksumAlgorithms        []ChecksumAlgorithm          `json:"supportedChecksumAlgorithms,omitempty"`
-	SupportsRestartRequest             bool                         `json:"supportsRestartRequest,omitempty"`
-	SupportsExceptionOptions           bool                         `json:"supportsExceptionOptions,omitempty"`
-	SupportsValueFormattingOptions     bool                         `json:"supportsValueFormattingOptions,omitempty"`
-	SupportsExceptionInfoRequest       bool                         `json:"supportsExceptionInfoRequest,omitempty"`
-	SupportTerminateDebuggee           bool                         `json:"supportTerminateDebuggee,omitempty"`
-	SupportSuspendDebuggee             bool                         `json:"supportSuspendDebuggee,omitempty"`
-	SupportsDelayedStackTraceLoading   bool                         `json:"supportsDelayedStackTraceLoading,omitempty"`
-	SupportsLoadedSourcesRequest       bool                         `json:"supportsLoadedSourcesRequest,omitempty"`
-	SupportsLogPoints                  bool                         `json:"supportsLogPoints,omitempty"`
-	SupportsTerminateThreadsRequest    bool                         `json:"supportsTerminateThreadsRequest,omitempty"`
-	SupportsSetExpression              bool                         `json:"supportsSetExpression,omitempty"`
-	SupportsTerminateRequest           bool                         `json:"supportsTerminateRequest,omitempty"`
-	SupportsDataBreakpoints            bool                         `json:"supportsDataBreakpoints,omitempty"`
-	SupportsReadMemoryRequest          bool                         `json:"supportsReadMemoryRequest,omitempty"`
-	SupportsWriteMemoryRequest         bool                         `json:"supportsWriteMemoryRequest,omitempty"`
-	SupportsDisassembleRequest         bool                         `json:"supportsDisassembleRequest,omitempty"`
-	SupportsCancelRequest              bool                         `json:"supportsCancelRequest,omitempty"`
-	SupportsBreakpointLocationsRequest bool                         `json:"supportsBreakpointLocationsRequest,omitempty"`
-	SupportsClipboardContext           bool                         `json:"supportsClipboardContext,omitempty"`
-	SupportsSteppingGranularity        bool                         `json:"supportsSteppingGranularity,omitempty"`
-	SupportsInstructionBreakpoints     bool                         `json:"supportsInstructionBreakpoints,omitempty"`
-	SupportsExceptionFilterOptions     bool                         `json:"supportsExceptionFilterOptions,omitempty"`
-}
-
-// ExceptionBreakpointsFilter: An ExceptionBreakpointsFilter is shown in the UI as an filter option for configuring how exceptions are dealt with.
+	SupportsConfigurationDoneRequest      bool                         `json:"supportsConfigurationDoneRequest,omitempty"`
+	SupportsFunctionBreakpoints           bool                         `json:"supportsFunctionBreakpoints,omitempty"`
+	SupportsConditionalBreakpoints        bool                         `json:"supportsConditionalBreakpoints,omitempty"`
+	SupportsHitConditionalBreakpoints     bool                         `json:"supportsHitConditionalBreakpoints,omitempty"`
+	SupportsEvaluateForHovers             bool                         `json:"supportsEvaluateForHovers,omitempty"`
+	ExceptionBreakpointFilters            []ExceptionBreakpointsFilter `json:"exceptionBreakpointFilters,omitempty"`
+	SupportsStepBack                      bool                         `json:"supportsStepBack,omitempty"`
+	SupportsSetVariable                   bool                         `json:"supportsSetVariable,omitempty"`
+	SupportsRestartFrame                  bool                         `json:"supportsRestartFrame,omitempty"`
+	SupportsGotoTargetsRequest            bool                         `json:"supportsGotoTargetsRequest,omitempty"`
+	SupportsStepInTargetsRequest          bool                         `json:"supportsStepInTargetsRequest,omitempty"`
+	SupportsCompletionsRequest            bool                         `json:"supportsCompletionsRequest,omitempty"`
+	CompletionTriggerCharacters           []string                     `json:"completionTriggerCharacters,omitempty"`
+	SupportsModulesRequest                bool                         `json:"supportsModulesRequest,omitempty"`
+	AdditionalModuleColumns               []ColumnDescriptor           `json:"additionalModuleColumns,omitempty"`
+	SupportedChecksumAlgorithms           []ChecksumAlgorithm          `json:"supportedChecksumAlgorithms,omitempty"`
+	SupportsRestartRequest                bool                         `json:"supportsRestartRequest,omitempty"`
+	SupportsExceptionOptions              bool                         `json:"supportsExceptionOptions,omitempty"`
+	SupportsValueFormattingOptions        bool                         `json:"supportsValueFormattingOptions,omitempty"`
+	SupportsExceptionInfoRequest          bool                         `json:"supportsExceptionInfoRequest,omitempty"`
+	SupportTerminateDebuggee              bool                         `json:"supportTerminateDebuggee,omitempty"`
+	SupportSuspendDebuggee                bool                         `json:"supportSuspendDebuggee,omitempty"`
+	SupportsDelayedStackTraceLoading      bool                         `json:"supportsDelayedStackTraceLoading,omitempty"`
+	SupportsLoadedSourcesRequest          bool                         `json:"supportsLoadedSourcesRequest,omitempty"`
+	SupportsLogPoints                     bool                         `json:"supportsLogPoints,omitempty"`
+	SupportsTerminateThreadsRequest       bool                         `json:"supportsTerminateThreadsRequest,omitempty"`
+	SupportsSetExpression                 bool                         `json:"supportsSetExpression,omitempty"`
+	SupportsTerminateRequest              bool                         `json:"supportsTerminateRequest,omitempty"`
+	SupportsDataBreakpoints               bool                         `json:"supportsDataBreakpoints,omitempty"`
+	SupportsReadMemoryRequest             bool                         `json:"supportsReadMemoryRequest,omitempty"`
+	SupportsWriteMemoryRequest            bool                         `json:"supportsWriteMemoryRequest,omitempty"`
+	SupportsDisassembleRequest            bool                         `json:"supportsDisassembleRequest,omitempty"`
+	SupportsCancelRequest                 bool                         `json:"supportsCancelRequest,omitempty"`
+	SupportsBreakpointLocationsRequest    bool                         `json:"supportsBreakpointLocationsRequest,omitempty"`
+	SupportsClipboardContext              bool                         `json:"supportsClipboardContext,omitempty"`
+	SupportsSteppingGranularity           bool                         `json:"supportsSteppingGranularity,omitempty"`
+	SupportsInstructionBreakpoints        bool                         `json:"supportsInstructionBreakpoints,omitempty"`
+	SupportsExceptionFilterOptions        bool                         `json:"supportsExceptionFilterOptions,omitempty"`
+	SupportsSingleThreadExecutionRequests bool                         `json:"supportsSingleThreadExecutionRequests,omitempty"`
+}
+
+// ExceptionBreakpointsFilter: An `ExceptionBreakpointsFilter` is shown in the UI as an filter option for configuring how exceptions are dealt with.
 type ExceptionBreakpointsFilter struct {
 	Filter               string `json:"filter"`
 	Label                string `json:"label"`
@@ -1671,13 +1708,12 @@ type ErrorMessage struct {
 }
 
 // Module: A Module object represents a row in the modules view.
-// Two attributes are mandatory: an id identifies a module in the modules view and is used in a ModuleEvent for identifying a module for adding, updating or deleting.
-// The name is used to minimally render the module in the UI.
+// The `id` attribute identifies a module in the modules view and is used in a `module` event for identifying a module for adding, updating or deleting.
+// The `name` attribute is used to minimally render the module in the UI.
 //
-// Additional attributes can be added to the module. They will show up in the module View if they have a corresponding ColumnDescriptor.
+// Additional attributes can be added to the module. They show up in the module view if they have a corresponding `ColumnDescriptor`.
 //
-// To avoid an unnecessary proliferation of additional attributes with similar semantics but different names
-// we recommend to re-use attributes from the 'recommended' list below first, and only introduce new attributes if nothing appropriate could be found.
+// To avoid an unnecessary proliferation of additional attributes with similar semantics but different names, we recommend to re-use attributes from the 'recommended' list below first, and only introduce new attributes if nothing appropriate could be found.
 type Module struct {
 	Id             interface{} `json:"id"`
 	Name           string      `json:"name"`
@@ -1691,7 +1727,7 @@ type Module struct {
 	AddressRange   string      `json:"addressRange,omitempty"`
 }
 
-// ColumnDescriptor: A ColumnDescriptor specifies what module attribute to show in a column of the ModulesView, how to format it,
+// ColumnDescriptor: A `ColumnDescriptor` specifies what module attribute to show in a column of the modules view, how to format it,
 // and what the column's label should be.
 // It is only used if the underlying UI actually supports this level of customization.
 type ColumnDescriptor struct {
@@ -1702,7 +1738,7 @@ type ColumnDescriptor struct {
 	Width         int    `json:"width,omitempty"`
 }
 
-// ModulesViewDescriptor: The ModulesViewDescriptor is the container for all declarative configuration options of a ModuleView.
+// ModulesViewDescriptor: The ModulesViewDescriptor is the container for all declarative configuration options of a module view.
 // For now it only specifies the columns to be shown in the modules view.
 type ModulesViewDescriptor struct {
 	Columns []ColumnDescriptor `json:"columns"`
@@ -1714,8 +1750,8 @@ type Thread struct {
 	Name string `json:"name"`
 }
 
-// Source: A Source is a descriptor for source code.
-// It is returned from the debug adapter as part of a StackFrame and it is used by clients when specifying breakpoints.
+// Source: A `Source` is a descriptor for source code.
+// It is returned from the debug adapter as part of a `StackFrame` and it is used by clients when specifying breakpoints.
 type Source struct {
 	Name             string      `json:"name,omitempty"`
 	Path             string      `json:"path,omitempty"`
@@ -1731,7 +1767,7 @@ type Source struct {
 type StackFrame struct {
 	Id                          int         `json:"id"`
 	Name                        string      `json:"name"`
-	Source                      Source      `json:"source,omitempty"`
+	Source                      *Source     `json:"source,omitempty"`
 	Line                        int         `json:"line"`
 	Column                      int         `json:"column"`
 	EndLine                     int         `json:"endLine,omitempty"`
@@ -1742,47 +1778,48 @@ type StackFrame struct {
 	PresentationHint            string      `json:"presentationHint,omitempty"`
 }
 
-// Scope: A Scope is a named container for variables. Optionally a scope can map to a source or a range within a source.
+// Scope: A `Scope` is a named container for variables. Optionally a scope can map to a source or a range within a source.
 type Scope struct {
-	Name               string `json:"name"`
-	PresentationHint   string `json:"presentationHint,omitempty"`
-	VariablesReference int    `json:"variablesReference"`
-	NamedVariables     int    `json:"namedVariables,omitempty"`
-	IndexedVariables   int    `json:"indexedVariables,omitempty"`
-	Expensive          bool   `json:"expensive"`
-	Source             Source `json:"source,omitempty"`
-	Line               int    `json:"line,omitempty"`
-	Column             int    `json:"column,omitempty"`
-	EndLine            int    `json:"endLine,omitempty"`
-	EndColumn          int    `json:"endColumn,omitempty"`
+	Name               string  `json:"name"`
+	PresentationHint   string  `json:"presentationHint,omitempty"`
+	VariablesReference int     `json:"variablesReference"`
+	NamedVariables     int     `json:"namedVariables,omitempty"`
+	IndexedVariables   int     `json:"indexedVariables,omitempty"`
+	Expensive          bool    `json:"expensive"`
+	Source             *Source `json:"source,omitempty"`
+	Line               int     `json:"line,omitempty"`
+	Column             int     `json:"column,omitempty"`
+	EndLine            int     `json:"endLine,omitempty"`
+	EndColumn          int     `json:"endColumn,omitempty"`
 }
 
 // Variable: A Variable is a name/value pair.
-// Optionally a variable can have a 'type' that is shown if space permits or when hovering over the variable's name.
-// An optional 'kind' is used to render additional properties of the variable, e.g. different icons can be used to indicate that a variable is public or private.
-// If the value is structured (has children), a handle is provided to retrieve the children with the VariablesRequest.
-// If the number of named or indexed children is large, the numbers should be returned via the optional 'namedVariables' and 'indexedVariables' attributes.
-// The client can use this optional information to present the children in a paged UI and fetch them in chunks.
+// The `type` attribute is shown if space permits or when hovering over the variable's name.
+// The `kind` attribute is used to render additional properties of the variable, e.g. different icons can be used to indicate that a variable is public or private.
+// If the value is structured (has children), a handle is provided to retrieve the children with the `variables` request.
+// If the number of named or indexed children is large, the numbers should be returned via the `namedVariables` and `indexedVariables` attributes.
+// The client can use this information to present the children in a paged UI and fetch them in chunks.
 type Variable struct {
-	Name               string                   `json:"name"`
-	Value              string                   `json:"value"`
-	Type               string                   `json:"type,omitempty"`
-	PresentationHint   VariablePresentationHint `json:"presentationHint,omitempty"`
-	EvaluateName       string                   `json:"evaluateName,omitempty"`
-	VariablesReference int                      `json:"variablesReference"`
-	NamedVariables     int                      `json:"namedVariables,omitempty"`
-	IndexedVariables   int                      `json:"indexedVariables,omitempty"`
-	MemoryReference    string                   `json:"memoryReference,omitempty"`
-}
-
-// VariablePresentationHint: Optional properties of a variable that can be used to determine how to render the variable in the UI.
+	Name               string                    `json:"name"`
+	Value              string                    `json:"value"`
+	Type               string                    `json:"type,omitempty"`
+	PresentationHint   *VariablePresentationHint `json:"presentationHint,omitempty"`
+	EvaluateName       string                    `json:"evaluateName,omitempty"`
+	VariablesReference int                       `json:"variablesReference"`
+	NamedVariables     int                       `json:"namedVariables,omitempty"`
+	IndexedVariables   int                       `json:"indexedVariables,omitempty"`
+	MemoryReference    string                    `json:"memoryReference,omitempty"`
+}
+
+// VariablePresentationHint: Properties of a variable that can be used to determine how to render the variable in the UI.
 type VariablePresentationHint struct {
 	Kind       string   `json:"kind,omitempty"`
 	Attributes []string `json:"attributes,omitempty"`
 	Visibility string   `json:"visibility,omitempty"`
+	Lazy       bool     `json:"lazy,omitempty"`
 }
 
-// BreakpointLocation: Properties of a breakpoint location returned from the 'breakpointLocations' request.
+// BreakpointLocation: Properties of a breakpoint location returned from the `breakpointLocations` request.
 type BreakpointLocation struct {
 	Line      int `json:"line"`
 	Column    int `json:"column,omitempty"`
@@ -1790,7 +1827,7 @@ type BreakpointLocation struct {
 	EndColumn int `json:"endColumn,omitempty"`
 }
 
-// SourceBreakpoint: Properties of a breakpoint or logpoint passed to the setBreakpoints request.
+// SourceBreakpoint: Properties of a breakpoint or logpoint passed to the `setBreakpoints` request.
 type SourceBreakpoint struct {
 	Line         int    `json:"line"`
 	Column       int    `json:"column,omitempty"`
@@ -1799,7 +1836,7 @@ type SourceBreakpoint struct {
 	LogMessage   string `json:"logMessage,omitempty"`
 }
 
-// FunctionBreakpoint: Properties of a breakpoint passed to the setFunctionBreakpoints request.
+// FunctionBreakpoint: Properties of a breakpoint passed to the `setFunctionBreakpoints` request.
 type FunctionBreakpoint struct {
 	Name         string `json:"name"`
 	Condition    string `json:"condition,omitempty"`
@@ -1809,7 +1846,7 @@ type FunctionBreakpoint struct {
 // DataBreakpointAccessType: This enumeration defines all possible access types for data breakpoints.
 type DataBreakpointAccessType string
 
-// DataBreakpoint: Properties of a data breakpoint passed to the setDataBreakpoints request.
+// DataBreakpoint: Properties of a data breakpoint passed to the `setDataBreakpoints` request.
 type DataBreakpoint struct {
 	DataId       string                   `json:"dataId"`
 	AccessType   DataBreakpointAccessType `json:"accessType,omitempty"`
@@ -1817,7 +1854,7 @@ type DataBreakpoint struct {
 	HitCondition string                   `json:"hitCondition,omitempty"`
 }
 
-// InstructionBreakpoint: Properties of a breakpoint passed to the setInstructionBreakpoints request
+// InstructionBreakpoint: Properties of a breakpoint passed to the `setInstructionBreakpoints` request
 type InstructionBreakpoint struct {
 	InstructionReference string `json:"instructionReference"`
 	Offset               int    `json:"offset,omitempty"`
@@ -1825,7 +1862,7 @@ type InstructionBreakpoint struct {
 	HitCondition         string `json:"hitCondition,omitempty"`
 }
 
-// Breakpoint: Information about a Breakpoint created in setBreakpoints, setFunctionBreakpoints, setInstructionBreakpoints, or setDataBreakpoints.
+// Breakpoint: Information about a breakpoint created in `setBreakpoints`, `setFunctionBreakpoints`, `setInstructionBreakpoints`, or `setDataBreakpoints` requests.
 type Breakpoint struct {
 	Id                   int     `json:"id,omitempty"`
 	Verified             bool    `json:"verified"`
@@ -1839,17 +1876,21 @@ type Breakpoint struct {
 	Offset               int     `json:"offset,omitempty"`
 }
 
-// SteppingGranularity: The granularity of one 'step' in the stepping requests 'next', 'stepIn', 'stepOut', and 'stepBack'.
+// SteppingGranularity: The granularity of one 'step' in the stepping requests `next`, `stepIn`, `stepOut`, and `stepBack`.
 type SteppingGranularity string
 
-// StepInTarget: A StepInTarget can be used in the 'stepIn' request and determines into which single target the stepIn request should step.
+// StepInTarget: A `StepInTarget` can be used in the `stepIn` request and determines into which single target the `stepIn` request should step.
 type StepInTarget struct {
-	Id    int    `json:"id"`
-	Label string `json:"label"`
+	Id        int    `json:"id"`
+	Label     string `json:"label"`
+	Line      int    `json:"line,omitempty"`
+	Column    int    `json:"column,omitempty"`
+	EndLine   int    `json:"endLine,omitempty"`
+	EndColumn int    `json:"endColumn,omitempty"`
 }
 
-// GotoTarget: A GotoTarget describes a code location that can be used as a target in the 'goto' request.
-// The possible goto targets can be determined via the 'gotoTargets' request.
+// GotoTarget: A `GotoTarget` describes a code location that can be used as a target in the `goto` request.
+// The possible goto targets can be determined via the `gotoTargets` request.
 type GotoTarget struct {
 	Id                          int    `json:"id"`
 	Label                       string `json:"label"`
@@ -1860,11 +1901,12 @@ type GotoTarget struct {
 	InstructionPointerReference string `json:"instructionPointerReference,omitempty"`
 }
 
-// CompletionItem: CompletionItems are the suggestions returned from the CompletionsRequest.
+// CompletionItem: `CompletionItems` are the suggestions returned from the `completions` request.
 type CompletionItem struct {
 	Label           string             `json:"label"`
 	Text            string             `json:"text,omitempty"`
 	SortText        string             `json:"sortText,omitempty"`
+	Detail          string             `json:"detail,omitempty"`
 	Type            CompletionItemType `json:"type,omitempty"`
 	Start           int                `json:"start,omitempty"`
 	Length          int                `json:"length,omitempty"`
@@ -1902,13 +1944,13 @@ type StackFrameFormat struct {
 	IncludeAll      bool `json:"includeAll,omitempty"`
 }
 
-// ExceptionFilterOptions: An ExceptionFilterOptions is used to specify an exception filter together with a condition for the setExceptionsFilter request.
+// ExceptionFilterOptions: An `ExceptionFilterOptions` is used to specify an exception filter together with a condition for the `setExceptionBreakpoints` request.
 type ExceptionFilterOptions struct {
 	FilterId  string `json:"filterId"`
 	Condition string `json:"condition,omitempty"`
 }
 
-// ExceptionOptions: An ExceptionOptions assigns configuration options to a set of exceptions.
+// ExceptionOptions: An `ExceptionOptions` assigns configuration options to a set of exceptions.
 type ExceptionOptions struct {
 	Path      []ExceptionPathSegment `json:"path,omitempty"`
 	BreakMode ExceptionBreakMode     `json:"breakMode"`
@@ -1921,9 +1963,8 @@ type ExceptionOptions struct {
 // userUnhandled: breaks if the exception is not handled by user code.
 type ExceptionBreakMode string
 
-// ExceptionPathSegment: An ExceptionPathSegment represents a segment in a path that is used to match leafs or nodes in a tree of exceptions.
-// If a segment consists of more than one name, it matches the names provided if 'negate' is false or missing or
-// it matches anything except the names provided if 'negate' is true.
+// ExceptionPathSegment: An `ExceptionPathSegment` represents a segment in a path that is used to match leafs or nodes in a tree of exceptions.
+// If a segment consists of more than one name, it matches the names provided if `negate` is false or missing, or it matches anything except the names provided if `negate` is true.
 type ExceptionPathSegment struct {
 	Negate bool     `json:"negate,omitempty"`
 	Names  []string `json:"names"`
@@ -1941,25 +1982,26 @@ type ExceptionDetails struct {
 
 // DisassembledInstruction: Represents a single disassembled instruction.
 type DisassembledInstruction struct {
-	Address          string `json:"address"`
-	InstructionBytes string `json:"instructionBytes,omitempty"`
-	Instruction      string `json:"instruction"`
-	Symbol           string `json:"symbol,omitempty"`
-	Location         Source `json:"location,omitempty"`
-	Line             int    `json:"line,omitempty"`
-	Column           int    `json:"column,omitempty"`
-	EndLine          int    `json:"endLine,omitempty"`
-	EndColumn        int    `json:"endColumn,omitempty"`
-}
-
-// InvalidatedAreas: Logical areas that can be invalidated by the 'invalidated' event.
+	Address          string  `json:"address"`
+	InstructionBytes string  `json:"instructionBytes,omitempty"`
+	Instruction      string  `json:"instruction"`
+	Symbol           string  `json:"symbol,omitempty"`
+	Location         *Source `json:"location,omitempty"`
+	Line             int     `json:"line,omitempty"`
+	Column           int     `json:"column,omitempty"`
+	EndLine          int     `json:"endLine,omitempty"`
+	EndColumn        int     `json:"endColumn,omitempty"`
+}
+
+// InvalidatedAreas: Logical areas that can be invalidated by the `invalidated` event.
 type InvalidatedAreas string
 
 // Mapping of request commands and corresponding struct constructors that
 // can be passed to json.Unmarshal.
 var requestCtor = map[string]messageCtor{
-	"cancel":        func() Message { return &CancelRequest{} },
-	"runInTerminal": func() Message { return &RunInTerminalRequest{} },
+	"cancel":         func() Message { return &CancelRequest{} },
+	"runInTerminal":  func() Message { return &RunInTerminalRequest{} },
+	"startDebugging": func() Message { return &StartDebuggingRequest{} },
 	"initialize": func() Message {
 		return &InitializeRequest{
 			Arguments: InitializeRequestArguments{
@@ -2017,6 +2059,7 @@ var requestCtor = map[string]messageCtor{
 var responseCtor = map[string]messageCtor{
 	"cancel":                    func() Message { return &CancelResponse{} },
 	"runInTerminal":             func() Message { return &RunInTerminalResponse{} },
+	"startDebugging":            func() Message { return &StartDebuggingResponse{} },
 	"initialize":                func() Message { return &InitializeResponse{} },
 	"configurationDone":         func() Message { return &ConfigurationDoneResponse{} },
 	"launch":                    func() Message { return &LaunchResponse{} },
@@ -2081,3 +2124,4 @@ var eventCtor = map[string]messageCtor{
 	"invalidated":    func() Message { return &InvalidatedEvent{} },
 	"memory":         func() Message { return &MemoryEvent{} },
 }
+ 
\ No newline at end of file
diff --git a/vendor/modules.txt b/vendor/modules.txt
index 29230a47..783546ca 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -22,7 +22,7 @@ github.com/derekparker/trie
 # github.com/go-delve/liner v1.2.3-0.20220127212407-d32d89dd2a5d
 ## explicit
 github.com/go-delve/liner
-# github.com/google/go-dap v0.7.0
+# github.com/google/go-dap v0.9.1
 ## explicit
 github.com/google/go-dap
 # github.com/hashicorp/golang-lru v0.5.4


Test patch:
diff --git a/cmd/dlv/dlv_test.go b/cmd/dlv/dlv_test.go
index 06b8fd60..aa1b1001 100644
--- a/cmd/dlv/dlv_test.go
+++ b/cmd/dlv/dlv_test.go
@@ -26,7 +26,6 @@ import (
 	"github.com/go-delve/delve/pkg/terminal"
 	"github.com/go-delve/delve/service/dap"
 	"github.com/go-delve/delve/service/dap/daptest"
-	"github.com/go-delve/delve/service/debugger"
 	"github.com/go-delve/delve/service/rpc2"
 	godap "github.com/google/go-dap"
 	"golang.org/x/tools/go/packages"
@@ -282,57 +281,6 @@ func TestContinue(t *testing.T) {
 	cmd.Wait()
 }
 
-// TestChildProcessExitWhenNoDebugInfo verifies that the child process exits when dlv launch the binary without debug info
-func TestChildProcessExitWhenNoDebugInfo(t *testing.T) {
-	noDebugFlags := protest.LinkStrip
-	// -s doesn't strip symbols on Mac, use -w instead
-	if runtime.GOOS == "darwin" {
-		noDebugFlags = protest.LinkDisableDWARF
-	}
-
-	if _, err := exec.LookPath("ps"); err != nil {
-		t.Skip("test skipped, `ps` not found")
-	}
-
-	dlvbin := getDlvBin(t)
-
-	fix := protest.BuildFixture("http_server", noDebugFlags)
-
-	// dlv exec the binary file and expect error.
-	out, err := exec.Command(dlvbin, "exec", "--headless", "--log", fix.Path).CombinedOutput()
-	t.Log(string(out))
-	if err == nil {
-		t.Fatalf("Expected err when launching the binary without debug info, but got nil")
-	}
-	//  Test only for dlv's prefix of the error like "could not launch process: could not open debug info"
-	if !strings.Contains(string(out), "could not launch process") || !strings.Contains(string(out), debugger.NoDebugWarning) {
-		t.Fatalf("Expected logged error 'could not launch process: ... - %s'", debugger.NoDebugWarning)
-	}
-
-	// search the running process named fix.Name
-	cmd := exec.Command("ps", "-aux")
-	stdout, err := cmd.StdoutPipe()
-	assertNoError(err, t, "stdout pipe")
-	defer stdout.Close()
-
-	assertNoError(cmd.Start(), t, "start `ps -aux`")
-
-	var foundFlag bool
-	scan := bufio.NewScanner(stdout)
-	for scan.Scan() {
-		t.Log(scan.Text())
-		if strings.Contains(scan.Text(), fix.Name) {
-			foundFlag = true
-			break
-		}
-	}
-	cmd.Wait()
-
-	if foundFlag {
-		t.Fatalf("Expected child process exited, but found it running")
-	}
-}
-
 // TestRedirect verifies that redirecting stdin works
 func TestRedirect(t *testing.T) {
 	const listenAddr = "127.0.0.1:40573"
@@ -711,57 +659,6 @@ func TestDAPCmd(t *testing.T) {
 	cmd.Wait()
 }
 
-func TestDAPCmdWithNoDebugBinary(t *testing.T) {
-	const listenAddr = "127.0.0.1:40579"
-
-	dlvbin := getDlvBin(t)
-
-	cmd := exec.Command(dlvbin, "dap", "--log", "--listen", listenAddr)
-	stdout, err := cmd.StdoutPipe()
-	assertNoError(err, t, "stdout pipe")
-	defer stdout.Close()
-	stderr, err := cmd.StderrPipe()
-	assertNoError(err, t, "stderr pipe")
-	defer stderr.Close()
-	assertNoError(cmd.Start(), t, "start dap instance")
-
-	scanOut := bufio.NewScanner(stdout)
-	scanErr := bufio.NewScanner(stderr)
-	// Wait for the debug server to start
-	scanOut.Scan()
-	listening := "DAP server listening at: " + listenAddr
-	if scanOut.Text() != listening {
-		cmd.Process.Kill() // release the port
-		t.Fatalf("Unexpected stdout:\ngot  %q\nwant %q", scanOut.Text(), listening)
-	}
-	go func() { // Capture logging
-		for scanErr.Scan() {
-			t.Log(scanErr.Text())
-		}
-	}()
-
-	// Exec the stripped debuggee and expect things to fail
-	noDebugFlags := protest.LinkStrip
-	// -s doesn't strip symbols on Mac, use -w instead
-	if runtime.GOOS == "darwin" {
-		noDebugFlags = protest.LinkDisableDWARF
-	}
-	fixture := protest.BuildFixture("increment", noDebugFlags)
-	go func() {
-		for scanOut.Scan() {
-			t.Errorf("Unexpected stdout: %s", scanOut.Text())
-		}
-	}()
-	client := daptest.NewClient(listenAddr)
-	client.LaunchRequest("exec", fixture.Path, false)
-	client.ExpectErrorResponse(t)
-	client.DisconnectRequest()
-	client.ExpectDisconnectResponse(t)
-	client.ExpectTerminatedEvent(t)
-	client.Close()
-	cmd.Wait()
-}
-
 func newDAPRemoteClient(t *testing.T, addr string, isDlvAttach bool, isMulti bool) *daptest.Client {
 	c := daptest.NewClient(addr)
 	c.AttachRequest(map[string]interface{}{"mode": "remote", "stopOnEntry": true})
diff --git a/pkg/proc/proc_test.go b/pkg/proc/proc_test.go
index 874434c8..10f7876d 100644
--- a/pkg/proc/proc_test.go
+++ b/pkg/proc/proc_test.go
@@ -3165,69 +3165,18 @@ func TestShadowedFlag(t *testing.T) {
 	})
 }
 
-func TestAttachStripped(t *testing.T) {
-	if testBackend == "lldb" && runtime.GOOS == "linux" {
-		bs, _ := ioutil.ReadFile("/proc/sys/kernel/yama/ptrace_scope")
-		if bs == nil || strings.TrimSpace(string(bs)) != "0" {
-			t.Logf("can not run TestAttachStripped: %v\n", bs)
-			return
-		}
-	}
-	if testBackend == "rr" {
-		return
-	}
-	if runtime.GOOS == "darwin" {
-		t.Log("-s does not produce stripped executables on macOS")
-		return
-	}
-	if buildMode != "" {
-		t.Skip("not enabled with buildmode=PIE")
-	}
-	fixture := protest.BuildFixture("testnextnethttp", protest.LinkStrip)
-	cmd := exec.Command(fixture.Path)
-	cmd.Stdout = os.Stdout
-	cmd.Stderr = os.Stderr
-	assertNoError(cmd.Start(), t, "starting fixture")
-
-	// wait for testnextnethttp to start listening
-	t0 := time.Now()
-	for {
-		conn, err := net.Dial("tcp", "127.0.0.1:9191")
-		if err == nil {
-			conn.Close()
-			break
-		}
-		time.Sleep(50 * time.Millisecond)
-		if time.Since(t0) > 10*time.Second {
-			t.Fatal("fixture did not start")
-		}
-	}
-
-	var p *proc.TargetGroup
-	var err error
-
-	switch testBackend {
-	case "native":
-		p, err = native.Attach(cmd.Process.Pid, []string{})
-	case "lldb":
-		path := ""
-		if runtime.GOOS == "darwin" {
-			path = fixture.Path
-		}
-		p, err = gdbserial.LLDBAttach(cmd.Process.Pid, path, []string{})
-	default:
-		t.Fatalf("unknown backend %q", testBackend)
-	}
-
-	t.Logf("error is %v", err)
-
-	if err == nil {
-		p.Detach(true)
-		t.Fatalf("expected error after attach, got nothing")
-	} else {
-		cmd.Process.Kill()
-	}
-	os.Remove(fixture.Path)
+func TestDebugStripped(t *testing.T) {
+	// Currently only implemented for Linux ELF executables.
+	// TODO(derekparker): Add support for Mach-O and PE.
+	skipUnlessOn(t, "linux only", "linux")
+	withTestProcessArgs("testnextprog", t, "", []string{}, protest.LinkStrip, func(p *proc.Target, grp *proc.TargetGroup, f protest.Fixture) {
+		setFunctionBreakpoint(p, t, "main.main")
+		assertNoError(grp.Continue(), t, "Continue")
+		assertCurrentLocationFunction(p, t, "main.main")
+		assertLineNumber(p, t, 37, "first continue")
+		assertNoError(grp.Next(), t, "Next")
+		assertLineNumber(p, t, 38, "after next")
+	})
 }
 
 func TestIssue844(t *testing.T) {
diff --git a/service/dap/daptest/client.go b/service/dap/daptest/client.go
index 7277c78d..77de5511 100644
--- a/service/dap/daptest/client.go
+++ b/service/dap/daptest/client.go
@@ -73,7 +73,7 @@ func (c *Client) ExpectMessage(t *testing.T) dap.Message {
 func (c *Client) ExpectInvisibleErrorResponse(t *testing.T) *dap.ErrorResponse {
 	t.Helper()
 	er := c.ExpectErrorResponse(t)
-	if er.Body.Error.ShowUser {
+	if er.Body.Error != nil && er.Body.Error.ShowUser {
 		t.Errorf("\ngot %#v\nwant ShowUser=false", er)
 	}
 	return er
@@ -82,7 +82,7 @@ func (c *Client) ExpectInvisibleErrorResponse(t *testing.T) *dap.ErrorResponse {
 func (c *Client) ExpectVisibleErrorResponse(t *testing.T) *dap.ErrorResponse {
 	t.Helper()
 	er := c.ExpectErrorResponse(t)
-	if !er.Body.Error.ShowUser {
+	if er.Body.Error == nil || !er.Body.Error.ShowUser {
 		t.Errorf("\ngot %#v\nwant ShowUser=true", er)
 	}
 	return er
@@ -91,6 +91,10 @@ func (c *Client) ExpectVisibleErrorResponse(t *testing.T) *dap.ErrorResponse {
 func (c *Client) ExpectErrorResponseWith(t *testing.T, id int, message string, showUser bool) *dap.ErrorResponse {
 	t.Helper()
 	er := c.ExpectErrorResponse(t)
+	if er.Body.Error == nil {
+		t.Errorf("got nil, want Id=%d Format=%q ShowUser=%v", id, message, showUser)
+		return er
+	}
 	if matched, _ := regexp.MatchString(message, er.Body.Error.Format); !matched || er.Body.Error.Id != id || er.Body.Error.ShowUser != showUser {
 		t.Errorf("got %#v, want Id=%d Format=%q ShowUser=%v", er, id, message, showUser)
 	}
@@ -277,7 +281,9 @@ func (c *Client) DisconnectRequest() {
 // `terminateDebuggee`.
 func (c *Client) DisconnectRequestWithKillOption(kill bool) {
 	request := &dap.DisconnectRequest{Request: *c.newRequest("disconnect")}
-	request.Arguments.TerminateDebuggee = kill
+	request.Arguments = &dap.DisconnectArguments{
+		TerminateDebuggee: kill,
+	}
 	c.send(request)
 }
 
diff --git a/service/dap/server_test.go b/service/dap/server_test.go
index 5b9b515a..3faee837 100644
--- a/service/dap/server_test.go
+++ b/service/dap/server_test.go
@@ -429,21 +429,21 @@ func TestLaunchStopOnEntry(t *testing.T) {
 		// 8 >> stackTrace, << error
 		client.StackTraceRequest(1, 0, 20)
 		stResp := client.ExpectInvisibleErrorResponse(t)
-		if stResp.Seq != 0 || stResp.RequestSeq != 8 || stResp.Body.Error.Format != "Unable to produce stack trace: unknown goroutine 1" {
+		if stResp.Seq != 0 || stResp.RequestSeq != 8 || !checkErrorMessageFormat(stResp.Body.Error, "Unable to produce stack trace: unknown goroutine 1") {
 			t.Errorf("\ngot %#v\nwant Seq=0, RequestSeq=8 Format=\"Unable to produce stack trace: unknown goroutine 1\"", stResp)
 		}
 
 		// 9 >> stackTrace, << error
 		client.StackTraceRequest(1, 0, 20)
 		stResp = client.ExpectInvisibleErrorResponse(t)
-		if stResp.Seq != 0 || stResp.RequestSeq != 9 || stResp.Body.Error.Id != UnableToProduceStackTrace {
+		if stResp.Seq != 0 || stResp.RequestSeq != 9 || !checkErrorMessageId(stResp.Body.Error, UnableToProduceStackTrace) {
 			t.Errorf("\ngot %#v\nwant Seq=0, RequestSeq=9 Id=%d", stResp, UnableToProduceStackTrace)
 		}
 
 		// 10 >> evaluate, << error
 		client.EvaluateRequest("foo", 0 /*no frame specified*/, "repl")
 		erResp := client.ExpectInvisibleErrorResponse(t)
-		if erResp.Seq != 0 || erResp.RequestSeq != 10 || erResp.Body.Error.Id != UnableToEvaluateExpression {
+		if erResp.Seq != 0 || erResp.RequestSeq != 10 || !checkErrorMessageId(erResp.Body.Error, UnableToEvaluateExpression) {
 			t.Errorf("\ngot %#v\nwant Seq=0, RequestSeq=10 Id=%d", erResp, UnableToEvaluateExpression)
 		}
 
@@ -576,7 +576,7 @@ func TestAttachStopOnEntry(t *testing.T) {
 		// 10 >> evaluate, << error
 		client.EvaluateRequest("foo", 0 /*no frame specified*/, "repl")
 		erResp := client.ExpectInvisibleErrorResponse(t)
-		if erResp.Seq != 0 || erResp.RequestSeq != 10 || erResp.Body.Error.Id != UnableToEvaluateExpression {
+		if erResp.Seq != 0 || erResp.RequestSeq != 10 || !checkErrorMessageId(erResp.Body.Error, UnableToEvaluateExpression) {
 			t.Errorf("\ngot %#v\nwant Seq=0, RequestSeq=10 Id=%d", erResp, UnableToEvaluateExpression)
 		}
 
@@ -749,7 +749,7 @@ func TestPreSetBreakpoint(t *testing.T) {
 				if got.Id != id || got.Name != name {
 					t.Errorf("\ngot  %#v\nwant Id=%d Name=%s", got, id, name)
 				}
-				if (sourceName != "" && got.Source.Name != sourceName) || (line > 0 && got.Line != line) {
+				if (sourceName != "" && (got.Source == nil || got.Source.Name != sourceName)) || (line > 0 && got.Line != line) {
 					t.Errorf("\ngot  %#v\nwant Source.Name=%s Line=%d", got, sourceName, line)
 				}
 			}
@@ -1613,7 +1613,7 @@ func TestScopesAndVariablesRequests(t *testing.T) {
 
 					client.ScopesRequest(1111)
 					erres := client.ExpectInvisibleErrorResponse(t)
-					if erres.Body.Error.Format != "Unable to list locals: unknown frame id 1111" {
+					if !checkErrorMessageFormat(erres.Body.Error, "Unable to list locals: unknown frame id 1111") {
 						t.Errorf("\ngot %#v\nwant Format=\"Unable to list locals: unknown frame id 1111\"", erres)
 					}
 
@@ -1628,7 +1628,7 @@ func TestScopesAndVariablesRequests(t *testing.T) {
 
 					client.VariablesRequest(7777)
 					erres = client.ExpectInvisibleErrorResponse(t)
-					if erres.Body.Error.Format != "Unable to lookup variable: unknown reference 7777" {
+					if !checkErrorMessageFormat(erres.Body.Error, "Unable to lookup variable: unknown reference 7777") {
 						t.Errorf("\ngot %#v\nwant Format=\"Unable to lookup variable: unknown reference 7777\"", erres)
 					}
 				},
@@ -3337,7 +3337,7 @@ func checkLogMessage(t *testing.T, oe *dap.OutputEvent, goid int, text, path str
 	if oe.Body.Category != "stdout" || !strings.HasPrefix(oe.Body.Output, prefix) || !strings.HasSuffix(oe.Body.Output, text+"\n") {
 		t.Errorf("got output event = %#v, \nwant Category=\"stdout\" Output=\"%s: %s\\n\"", oe, prefix, text)
 	}
-	if oe.Body.Line != line || oe.Body.Source.Path != path {
+	if oe.Body.Line != line || oe.Body.Source == nil || oe.Body.Source.Path != path {
 		t.Errorf("got output event = %#v, \nwant Line=%d Source.Path=%s", oe, line, path)
 	}
 }
@@ -3955,27 +3955,27 @@ func TestEvaluateRequest(t *testing.T) {
 					// Next frame
 					client.EvaluateRequest("a1", 1002, "any context but watch")
 					erres := client.ExpectVisibleErrorResponse(t)
-					if erres.Body.Error.Format != "Unable to evaluate expression: could not find symbol value for a1" {
+					if !checkErrorMessageFormat(erres.Body.Error, "Unable to evaluate expression: could not find symbol value for a1") {
 						t.Errorf("\ngot %#v\nwant Format=\"Unable to evaluate expression: could not find symbol value for a1\"", erres)
 					}
 					client.EvaluateRequest("a1", 1002, "watch")
 					erres = client.ExpectInvisibleErrorResponse(t)
-					if erres.Body.Error.Format != "Unable to evaluate expression: could not find symbol value for a1" {
+					if !checkErrorMessageFormat(erres.Body.Error, "Unable to evaluate expression: could not find symbol value for a1") {
 						t.Errorf("\ngot %#v\nwant Format=\"Unable to evaluate expression: could not find symbol value for a1\"", erres)
 					}
 					client.EvaluateRequest("a1", 1002, "repl")
 					erres = client.ExpectInvisibleErrorResponse(t)
-					if erres.Body.Error.Format != "Unable to evaluate expression: could not find symbol value for a1" {
+					if !checkErrorMessageFormat(erres.Body.Error, "Unable to evaluate expression: could not find symbol value for a1") {
 						t.Errorf("\ngot %#v\nwant Format=\"Unable to evaluate expression: could not find symbol value for a1\"", erres)
 					}
 					client.EvaluateRequest("a1", 1002, "hover")
 					erres = client.ExpectInvisibleErrorResponse(t)
-					if erres.Body.Error.Format != "Unable to evaluate expression: could not find symbol value for a1" {
+					if !checkErrorMessageFormat(erres.Body.Error, "Unable to evaluate expression: could not find symbol value for a1") {
 						t.Errorf("\ngot %#v\nwant Format=\"Unable to evaluate expression: could not find symbol value for a1\"", erres)
 					}
 					client.EvaluateRequest("a1", 1002, "clipboard")
 					erres = client.ExpectVisibleErrorResponse(t)
-					if erres.Body.Error.Format != "Unable to evaluate expression: could not find symbol value for a1" {
+					if !checkErrorMessageFormat(erres.Body.Error, "Unable to evaluate expression: could not find symbol value for a1") {
 						t.Errorf("\ngot %#v\nwant Format=\"Unable to evaluate expression: could not find symbol value for a1\"", erres)
 					}
 				},
@@ -4291,7 +4291,7 @@ func TestEvaluateCallRequest(t *testing.T) {
 					client.ExpectEvaluateResponse(t)
 					client.EvaluateRequest("call callstacktrace()", 1001, "not watch")
 					erres := client.ExpectVisibleErrorResponse(t)
-					if erres.Body.Error.Format != "Unable to evaluate expression: call is only supported with topmost stack frame" {
+					if !checkErrorMessageFormat(erres.Body.Error, "Unable to evaluate expression: call is only supported with topmost stack frame") {
 						t.Errorf("\ngot %#v\nwant Format=\"Unable to evaluate expression: call is only supported with topmost stack frame\"", erres)
 					}
 
@@ -4302,14 +4302,14 @@ func TestEvaluateCallRequest(t *testing.T) {
 						t.Errorf("\ngot %#v\nwant Reason=\"hardcoded breakpoint\"", s)
 					}
 					erres = client.ExpectVisibleErrorResponse(t)
-					if erres.Body.Error.Format != "Unable to evaluate expression: call stopped" {
+					if !checkErrorMessageFormat(erres.Body.Error, "Unable to evaluate expression: call stopped") {
 						t.Errorf("\ngot %#v\nwant Format=\"Unable to evaluate expression: call stopped\"", erres)
 					}
 
 					// A call during a call causes an error
 					client.EvaluateRequest("call callstacktrace()", 1000, "not watch")
 					erres = client.ExpectVisibleErrorResponse(t)
-					if erres.Body.Error.Format != "Unable to evaluate expression: cannot call function while another function call is already in progress" {
+					if !checkErrorMessageFormat(erres.Body.Error, "Unable to evaluate expression: cannot call function while another function call is already in progress") {
 						t.Errorf("\ngot %#v\nwant Format=\"Unable to evaluate expression: cannot call function while another function call is already in progress\"", erres)
 					}
 
@@ -4327,7 +4327,7 @@ func TestEvaluateCallRequest(t *testing.T) {
 					client.EvaluateRequest("call makeclos(nil)", 1000, "not watch")
 					stopped := client.ExpectStoppedEvent(t)
 					erres = client.ExpectVisibleErrorResponse(t)
-					if erres.Body.Error.Format != "Unable to evaluate expression: call stopped" {
+					if !checkErrorMessageFormat(erres.Body.Error, "Unable to evaluate expression: call stopped") {
 						t.Errorf("\ngot %#v\nwant Format=\"Unable to evaluate expression: call stopped\"", erres)
 					}
 					checkStop(t, client, stopped.Body.ThreadId, "main.makeclos", 88)
@@ -4401,7 +4401,7 @@ func TestEvaluateCallRequest(t *testing.T) {
 					// Call error
 					client.EvaluateRequest("call call1(one)", 1000, "watch")
 					erres := client.ExpectInvisibleErrorResponse(t)
-					if erres.Body.Error.Format != "Unable to evaluate expression: not enough arguments" {
+					if !checkErrorMessageFormat(erres.Body.Error, "Unable to evaluate expression: not enough arguments") {
 						t.Errorf("\ngot %#v\nwant Format=\"Unable to evaluate expression: not enough arguments\"", erres)
 					}
 
@@ -4417,7 +4417,7 @@ func TestEvaluateCallRequest(t *testing.T) {
 					// Call can exit.
 					client.EvaluateRequest("call callexit()", 1000, "this context will be ignored")
 					client.ExpectTerminatedEvent(t)
-					if res := client.ExpectVisibleErrorResponse(t); !strings.Contains(res.Body.Error.Format, "terminated") {
+					if res := client.ExpectVisibleErrorResponse(t); res.Body.Error == nil || !strings.Contains(res.Body.Error.Format, "terminated") {
 						t.Errorf("\ngot %#v\nwant Format=.*terminated.*", res)
 					}
 				},
@@ -4957,7 +4957,7 @@ func TestPanicBreakpointOnContinue(t *testing.T) {
 							if frame.PresentationHint != "subtle" {
 								t.Errorf("\ngot Body.StackFrames[%d]=%#v\nwant Source.PresentationHint=\"subtle\"", i, frame)
 							}
-						} else if frame.Source.PresentationHint != "" {
+						} else if frame.Source != nil && frame.Source.PresentationHint != "" {
 							t.Errorf("\ngot Body.StackFrames[%d]=%#v\nwant Source.PresentationHint=\"\"", i, frame)
 						}
 
@@ -5377,7 +5377,7 @@ func TestNoDebug_AcceptNoRequestsButDisconnect(t *testing.T) {
 		// Anything other than disconnect should get rejected
 		var ExpectNoDebugError = func(cmd string) {
 			er := client.ExpectErrorResponse(t)
-			if er.Body.Error.Format != fmt.Sprintf("noDebug mode: unable to process '%s' request", cmd) {
+			if !checkErrorMessageFormat(er.Body.Error, fmt.Sprintf("noDebug mode: unable to process '%s' request", cmd)) {
 				t.Errorf("\ngot %#v\nwant 'noDebug mode: unable to process '%s' request'", er, cmd)
 			}
 		}
@@ -5877,7 +5877,7 @@ func (h *helperForSetVariable) failSetVariable0(ref int, name, value, wantErrInf
 		h.c.ExpectStoppedEvent(h.t)
 	}
 	resp := h.c.ExpectErrorResponse(h.t)
-	if got := resp.Body.Error.Format; !stringContainsCaseInsensitive(got, wantErrInfo) {
+	if got := resp.Body.Error; !stringContainsCaseInsensitive(got.Format, wantErrInfo) {
 		h.t.Errorf("got %#v, want error string containing %v", got, wantErrInfo)
 	}
 }
@@ -6231,8 +6231,8 @@ func TestBadLaunchRequests(t *testing.T) {
 			if response.Message != "Failed to launch" {
 				t.Errorf("Message got %q, want \"Failed to launch\"", response.Message)
 			}
-			if response.Body.Error.Id != FailedToLaunch {
-				t.Errorf("Id got %d, want %d", response.Body.Error.Id, FailedToLaunch)
+			if !checkErrorMessageId(response.Body.Error, FailedToLaunch) {
+				t.Errorf("Id got %v, want Id=%d", response.Body.Error, FailedToLaunch)
 			}
 			seqCnt++
 		}
@@ -6240,8 +6240,8 @@ func TestBadLaunchRequests(t *testing.T) {
 		checkFailedToLaunchWithMessage := func(response *dap.ErrorResponse, errmsg string) {
 			t.Helper()
 			checkFailedToLaunch(response)
-			if response.Body.Error.Format != errmsg {
-				t.Errorf("\ngot  %q\nwant %q", response.Body.Error.Format, errmsg)
+			if !checkErrorMessageFormat(response.Body.Error, errmsg) {
+				t.Errorf("\ngot  %v\nwant Format=%q", response.Body.Error, errmsg)
 			}
 		}
 
@@ -6432,8 +6432,8 @@ func TestBadAttachRequest(t *testing.T) {
 			if response.Message != "Failed to attach" {
 				t.Errorf("Message got %q, want \"Failed to attach\"", response.Message)
 			}
-			if response.Body.Error.Id != FailedToAttach {
-				t.Errorf("Id got %d, want %d", response.Body.Error.Id, FailedToAttach)
+			if !checkErrorMessageId(response.Body.Error, FailedToAttach) {
+				t.Errorf("Id got %v, want %d", response.Body.Error, FailedToAttach)
 			}
 			seqCnt++
 		}
@@ -6441,8 +6441,8 @@ func TestBadAttachRequest(t *testing.T) {
 		checkFailedToAttachWithMessage := func(response *dap.ErrorResponse, errmsg string) {
 			t.Helper()
 			checkFailedToAttach(response)
-			if response.Body.Error.Format != errmsg {
-				t.Errorf("\ngot  %q\nwant %q", response.Body.Error.Format, errmsg)
+			if !checkErrorMessageFormat(response.Body.Error, errmsg) {
+				t.Errorf("\ngot  %v\nwant Format=%q", response.Body.Error, errmsg)
 			}
 		}
 
@@ -6494,11 +6494,11 @@ func TestBadAttachRequest(t *testing.T) {
 		if er.Command != "" {
 			t.Errorf("Command got %q, want \"attach\"", er.Command)
 		}
-		if er.Body.Error.Format != "Internal Error: runtime error: index out of range [0] with length 0" {
+		if !checkErrorMessageFormat(er.Body.Error, "Internal Error: runtime error: index out of range [0] with length 0") {
 			t.Errorf("Message got %q, want \"Internal Error: runtime error: index out of range [0] with length 0\"", er.Message)
 		}
-		if er.Body.Error.Id != InternalError {
-			t.Errorf("Id got %d, want %d", er.Body.Error.Id, InternalError)
+		if !checkErrorMessageId(er.Body.Error, InternalError) {
+			t.Errorf("Id got %v, want Id=%d", er.Body.Error, InternalError)
 		}
 
 		// Bad "backend"
@@ -6813,8 +6813,8 @@ func TestLaunchAttachErrorWhenDebugInProgress(t *testing.T) {
 				client.AttachRequest(map[string]interface{}{"mode": "local", "processId": 100})
 				er := client.ExpectVisibleErrorResponse(t)
 				msgRe := regexp.MustCompile("Failed to attach: debug session already in progress at [0-9]+:[0-9]+ - use remote mode to connect to a server with an active debug session")
-				if er.Body.Error.Id != FailedToAttach || msgRe.MatchString(er.Body.Error.Format) {
-					t.Errorf("got %#v, want Id=%d Format=%q", er, FailedToAttach, msgRe)
+				if er.Body.Error == nil || er.Body.Error.Id != FailedToAttach || msgRe.MatchString(er.Body.Error.Format) {
+					t.Errorf("got %#v, want Id=%d Format=%q", er.Body.Error, FailedToAttach, msgRe)
 				}
 				tests := []string{"debug", "test", "exec", "replay", "core"}
 				for _, mode := range tests {
@@ -6822,8 +6822,8 @@ func TestLaunchAttachErrorWhenDebugInProgress(t *testing.T) {
 						client.LaunchRequestWithArgs(map[string]interface{}{"mode": mode})
 						er := client.ExpectVisibleErrorResponse(t)
 						msgRe := regexp.MustCompile("Failed to launch: debug session already in progress at [0-9]+:[0-9]+ - use remote attach mode to connect to a server with an active debug session")
-						if er.Body.Error.Id != FailedToLaunch || msgRe.MatchString(er.Body.Error.Format) {
-							t.Errorf("got %#v, want Id=%d Format=%q", er, FailedToLaunch, msgRe)
+						if er.Body.Error == nil || er.Body.Error.Id != FailedToLaunch || msgRe.MatchString(er.Body.Error.Format) {
+							t.Errorf("got %#v, want Id=%d Format=%q", er.Body.Error, FailedToLaunch, msgRe)
 						}
 					})
 				}
@@ -6849,10 +6849,10 @@ func TestBadInitializeRequest(t *testing.T) {
 		if response.Message != "Failed to initialize" {
 			t.Errorf("Message got %q, want \"Failed to launch\"", response.Message)
 		}
-		if response.Body.Error.Id != FailedToInitialize {
-			t.Errorf("Id got %d, want %d", response.Body.Error.Id, FailedToInitialize)
+		if !checkErrorMessageId(response.Body.Error, FailedToInitialize) {
+			t.Errorf("Id got %v, want Id=%d", response.Body.Error, FailedToInitialize)
 		}
-		if response.Body.Error.Format != err {
+		if !checkErrorMessageFormat(response.Body.Error, err) {
 			t.Errorf("\ngot  %q\nwant %q", response.Body.Error.Format, err)
 		}
 
@@ -6913,7 +6913,7 @@ func TestBadlyFormattedMessageToServer(t *testing.T) {
 		// an error response.
 		client.UnknownRequest()
 		err := client.ExpectErrorResponse(t)
-		if err.Body.Error.Format != "Internal Error: Request command 'unknown' is not supported (seq: 1)" || err.RequestSeq != 1 {
+		if !checkErrorMessageFormat(err.Body.Error, "Internal Error: Request command 'unknown' is not supported (seq: 1)") || err.RequestSeq != 1 {
 			t.Errorf("got %v, want  RequestSeq=1 Error=\"Internal Error: Request command 'unknown' is not supported (seq: 1)\"", err)
 		}
 
@@ -7365,3 +7365,13 @@ func TestDisassembleCgo(t *testing.T) {
 	},
 		protest.AllNonOptimized, true)
 }
+
+// Helper functions for checking ErrorMessage field values.
+
+func checkErrorMessageId(er *dap.ErrorMessage, id int) bool {
+	return er != nil && er.Id == id
+}
+
+func checkErrorMessageFormat(er *dap.ErrorMessage, fmt string) bool {
+	return er != nil && er.Format == fmt
+}