[release] prepare v0.30.0 release

ed978a6 src/goDebugConfiguration: infer default mode property
f5d1004 docs/debugging.md: add details for troubleshooting
5cb334d src/goToolsInformation: pin gofumports at v0.1.1
511945e test/integration: add missing await in goDebugConfiguration tests
27bcdca src/goInstallTools: pin dlv-dap version @2f136727
bf2ce37 src/goDebugConfiguration.ts: allow users to debug with older versions of dlv-dap
7919ded README.md: fix the broken link for debugging
8dd6020 docs/debugging: include logpoints, remove stop conditions, revise faqs
28a97ef package-lock.json: update json-schema to 0.4.0
7d023af package.json: update remote attach references to reflect dlv-dap support
6320e8b docs/debugging.md: update on newly available traditional remote debugging via DAP
4763647 stop debugger when delve remote connection ends
50b13f1 package.json: limit file search scope for extension activation
6448e9d goDebugConfiguration.test.ts: remove .only
ed9b7bc src/goDebugConfiguration: update list of delveConfig properties
8a25201 src/goDebugFactory: let startAndConnectToServer return a socket
4983f1d docs: fix bold text error
08f9065 src/testUtils: add test codelenses for Fuzz* functions
ae78458 tsconfig.json: bump target to ES2017
32a5776 src/goTools.ts: disable lint tool if 'staticcheck' is true
cc34acf github/workflows: update lannonbr/vsce-action
b2c00ac debug: allow debugAdapter=dlv-dap with remote attach mode
a445ec3 src/goSurvey: use our latest survey URL
44e2d4d package.json: add config to hide system goroutines in debug
18e3fca package.json: allow 'rr' as a valid delve backend
681be58 tools/installtools: add a helper to install Go tools for testing
5f4e3ca test/integration/goTest: temporarily disable profile tests
8750bb3 tsconfig.json: set esModuleInterop
498123d package.json: add showRegisters to the delve config
48c6022 package.json: start v0.30.0-dev

Updates golang/vscode-go#1930

Change-Id: Iafccb01812bdf029323d76d79971743f04e44a12
diff --git a/.github/workflows/release-nightly.yml b/.github/workflows/release-nightly.yml
index cc6d298..811b087 100644
--- a/.github/workflows/release-nightly.yml
+++ b/.github/workflows/release-nightly.yml
@@ -44,29 +44,7 @@
 
       - name: Install Go tools (Modules mode)
         run: |
-            go version
-            go get github.com/acroca/go-symbols
-            go get github.com/davidrjenni/reftools/cmd/fillstruct
-            go get github.com/haya14busa/goplay/cmd/goplay
-
-            # Install two versions of gocode (one as gocode-gomod)
-            go get github.com/stamblerre/gocode
-            mv "${HOME}/go/bin/gocode${{env.EXT}}" "${HOME}/go/bin/gocode-gomod${{env.EXT}}"
-            go get github.com/mdempsky/gocode
-
-            go get github.com/sqs/goreturns
-            go get github.com/uudashr/gopkgs/v2/cmd/gopkgs
-            go get github.com/zmb3/gogetdoc
-            go get honnef.co/go/tools/...
-            go get golang.org/x/tools/cmd/gorename
-            go get golang.org/x/tools/gopls
-            go get github.com/cweill/gotests/...
-            go get github.com/rogpeppe/godef
-            go get github.com/ramya-rao-a/go-outline
-            go get github.com/go-delve/delve/cmd/dlv@master
-            cp "${HOME}/go/bin/dlv${{env.EXT}}" "${HOME}/go/bin/dlv-dap${{env.EXT}}"
-            go get github.com/go-delve/delve/cmd/dlv
-        working-directory: ${{ runner.temp }}
+            go run ./tools/installtools/main.go
         env:
           GO111MODULE: on
           EXT: "${{ matrix.os == 'windows-latest' && '.exe' || ''}}"
@@ -84,7 +62,7 @@
 
       - name: Publish
         if: github.ref == 'refs/heads/master' && github.repository == 'golang/vscode-go'
-        uses: lannonbr/vsce-action@704da577da0f27de5cdb4ae018374c2f08b5f523
+        uses: lannonbr/vsce-action@0f3391ee0477b08fae949eb0a875e91e6d20b075
         with:
           args: "publish -p $VSCE_TOKEN"
         env:
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 420153e..f2156ad 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -75,7 +75,7 @@
           npm run vscode:prepublish
 
       - name: package
-        uses: lannonbr/vsce-action@704da577da0f27de5cdb4ae018374c2f08b5f523
+        uses: lannonbr/vsce-action@0f3391ee0477b08fae949eb0a875e91e6d20b075
         with:
           args: "package"
 
@@ -102,10 +102,10 @@
 
       - name: publish
         if: env.EXT_ISPREVIEW != 1 && github.repository == 'golang/vscode-go'
-        uses: lannonbr/vsce-action@704da577da0f27de5cdb4ae018374c2f08b5f523
+        uses: lannonbr/vsce-action@0f3391ee0477b08fae949eb0a875e91e6d20b075
         with:
           args: "publish -p $VSCE_TOKEN"
         env:
           VSCE_TOKEN: ${{ secrets.VSCE_TOKEN }}
 
-# TODO: check if the commit is in green state. (test-long.yml results)
\ No newline at end of file
+# TODO: check if the commit is in green state. (test-long.yml results)
diff --git a/.github/workflows/test-long-all.yml b/.github/workflows/test-long-all.yml
index acc82c0..4b43f30 100644
--- a/.github/workflows/test-long-all.yml
+++ b/.github/workflows/test-long-all.yml
@@ -43,27 +43,7 @@
       - name: Install Go tools (Modules mode)
         run: |
             go version
-            go get github.com/acroca/go-symbols
-            go get github.com/davidrjenni/reftools/cmd/fillstruct
-            go get github.com/haya14busa/goplay/cmd/goplay
-            # Install two versions of gocode (one as gocode-gomod)
-            go get github.com/stamblerre/gocode
-            mv "${HOME}/go/bin/gocode${{env.EXT}}" "${HOME}/go/bin/gocode-gomod${{env.EXT}}"
-            go get github.com/mdempsky/gocode
-            go get github.com/sqs/goreturns
-            go get github.com/uudashr/gopkgs/v2/cmd/gopkgs
-            go get github.com/zmb3/gogetdoc
-            go get honnef.co/go/tools/...
-            go get golang.org/x/tools/cmd/gorename
-            go get golang.org/x/tools/gopls
-            go get github.com/cweill/gotests/...
-            go get github.com/rogpeppe/godef
-            go get github.com/ramya-rao-a/go-outline
-            # Install two versions of dlv (one as dlv-dap)
-            go get github.com/go-delve/delve/cmd/dlv@master
-            mv "${HOME}/go/bin/dlv${{env.EXT}}" "${HOME}/go/bin/dlv-dap${{env.EXT}}"
-            go get github.com/go-delve/delve/cmd/dlv@latest
-        working-directory: ${{ runner.temp }}
+            go run ./tools/installtools/main.go
         env:
           GO111MODULE: on
           EXT: "${{ matrix.os == 'windows-latest' && '.exe' || ''}}"
diff --git a/.github/workflows/test-long.yml b/.github/workflows/test-long.yml
index 67711f1..91f1a76 100644
--- a/.github/workflows/test-long.yml
+++ b/.github/workflows/test-long.yml
@@ -43,27 +43,7 @@
       - name: Install Go tools (Modules mode)
         run: |
             go version
-            go get github.com/acroca/go-symbols
-            go get github.com/davidrjenni/reftools/cmd/fillstruct
-            go get github.com/haya14busa/goplay/cmd/goplay
-            # Install two versions of gocode (one as gocode-gomod)
-            go get github.com/stamblerre/gocode
-            mv "${HOME}/go/bin/gocode${{env.EXT}}" "${HOME}/go/bin/gocode-gomod${{env.EXT}}"
-            go get github.com/mdempsky/gocode
-            go get github.com/sqs/goreturns
-            go get github.com/uudashr/gopkgs/v2/cmd/gopkgs
-            go get github.com/zmb3/gogetdoc
-            go get honnef.co/go/tools/...
-            go get golang.org/x/tools/cmd/gorename
-            go get golang.org/x/tools/gopls
-            go get github.com/cweill/gotests/...
-            go get github.com/rogpeppe/godef
-            go get github.com/ramya-rao-a/go-outline
-            # Install two versions of dlv (one as dlv-dap)
-            go get github.com/go-delve/delve/cmd/dlv@master
-            mv "${HOME}/go/bin/dlv${{env.EXT}}" "${HOME}/go/bin/dlv-dap${{env.EXT}}"
-            go get github.com/go-delve/delve/cmd/dlv@latest
-        working-directory: ${{ runner.temp }}
+            go run ./tools/installtools/main.go
         env:
           GO111MODULE: on
           EXT: "${{ matrix.os == 'windows-latest' && '.exe' || ''}}"
diff --git a/.github/workflows/test-smoke.yml b/.github/workflows/test-smoke.yml
index 270954f..3954b7f 100644
--- a/.github/workflows/test-smoke.yml
+++ b/.github/workflows/test-smoke.yml
@@ -40,27 +40,7 @@
       - name: Install Go tools (Modules mode)
         run: |
             go version
-            go get github.com/acroca/go-symbols
-            go get github.com/davidrjenni/reftools/cmd/fillstruct
-            go get github.com/haya14busa/goplay/cmd/goplay
-            # Install two versions of gocode (one as gocode-gomod)
-            go get github.com/stamblerre/gocode
-            mv "${HOME}/go/bin/gocode${{env.EXT}}"  "${HOME}/go/bin/gocode-gomod${{env.EXT}}"
-            go get github.com/mdempsky/gocode
-            go get github.com/sqs/goreturns
-            go get github.com/uudashr/gopkgs/v2/cmd/gopkgs
-            go get github.com/zmb3/gogetdoc
-            go get honnef.co/go/tools/...
-            go get golang.org/x/tools/cmd/gorename
-            go get golang.org/x/tools/gopls
-            go get github.com/cweill/gotests/...
-            go get github.com/rogpeppe/godef
-            go get github.com/ramya-rao-a/go-outline
-            # Install two versions of dlv (one as dlv-dap)
-            go get github.com/go-delve/delve/cmd/dlv@master
-            mv "${HOME}/go/bin/dlv${{env.EXT}}" "${HOME}/go/bin/dlv-dap${{env.EXT}}"
-            go get github.com/go-delve/delve/cmd/dlv@latest
-        working-directory: ${{ runner.temp }}
+            go run ./tools/installtools/main.go
         env:
           GO111MODULE: on
           EXT: "${{ matrix.os == 'windows-latest' && '.exe' || ''}}"
diff --git a/README.md b/README.md
index 84335c3..34a79e2 100644
--- a/README.md
+++ b/README.md
@@ -170,7 +170,7 @@
 [code editing]: https://github.com/golang/vscode-go/blob/master/docs/features.md#code-editing
 [diagnostics]: https://github.com/golang/vscode-go/blob/master/docs/features.md#diagnostics
 [testing]: https://github.com/golang/vscode-go/blob/master/docs/features.md##run-and-test-in-the-editor
-[debugging]: #debugging
+[debugging]: https://github.com/golang/vscode-go/blob/master/docs/debugging.md#features
 [full feature breakdown]: https://github.com/golang/vscode-go/blob/master/docs/features.md
 [workspace documentation]: https://github.com/golang/tools/blob/master/gopls/doc/workspace.md
 [`Go: Install/Update Tools` command]: https://github.com/golang/vscode-go/blob/master/docs/commands.md#go-installupdate-tools
diff --git a/build/Dockerfile b/build/Dockerfile
index 17662f0..1ca02ee 100644
--- a/build/Dockerfile
+++ b/build/Dockerfile
@@ -6,9 +6,9 @@
 ENV GOBIN /gobin
 
 # Install other Go tools tests depend on
-RUN mkdir -p /scratch/build
-ADD build/all.bash /scratch/build/all.bash
-RUN /scratch/build/all.bash setup_env
+RUN mkdir -p /scratch/installtools
+ADD tools/installtools/main.go /scratch/installtools/main.go
+RUN go run /scratch/installtools/main.go
 
 FROM node:latest
 
diff --git a/build/all.bash b/build/all.bash
index f981def..120da2b 100755
--- a/build/all.bash
+++ b/build/all.bash
@@ -81,7 +81,7 @@
 .displayName="Go Nightly" |
 .publisher="golang" |
 .description="Rich Go language support for Visual Studio Code (Nightly)" |
-.contributes.configuration.properties."go.useLanguageServer".default=true
+.contributes.configuration.properties."go.delveConfig.hideSystemGoroutines".default=true
 ') > /tmp/package.json && mv /tmp/package.json package.json
 
   # Replace CHANGELOG.md with CHANGELOG.md + Release commit info.
@@ -92,36 +92,6 @@
   cp build/nightly/const.ts src/const.ts
 }
 
-# setup dependencies required for tests.
-install_dependencies() {
-	# TARGET is where `go get` will output the compiled binaries.
-	local GOPATHS=`go env GOPATH`
-	local TARGET="${GOBIN}"
-	if [[ -z "${GOBIN}" ]]; then TARGET="${GOPATHS%%:*}/bin" ; fi
-
-	GO111MODULE=on go install golang.org/x/tools/gopls@latest
-	GO111MODULE=on go install github.com/acroca/go-symbols@latest
-	GO111MODULE=on go install github.com/cweill/gotests/gotests@latest
-	GO111MODULE=on go install github.com/davidrjenni/reftools/cmd/fillstruct@latest
-	GO111MODULE=on go install github.com/haya14busa/goplay/cmd/goplay@latest
-
-	# We install two versions of gocode, one for module mode (gocode-gomod)
-	# and another for GOPATH mode (gocode).
-	GO111MODULE=on go install github.com/stamblerre/gocode@latest && mv "${TARGET}/gocode" "${TARGET}/gocode-gomod"
-	GO111MODULE=on go install github.com/mdempsky/gocode@latest
-
-	GO111MODULE=on go install github.com/ramya-rao-a/go-outline@latest
-	GO111MODULE=on go install github.com/rogpeppe/godef@latest
-	GO111MODULE=on go install github.com/sqs/goreturns@latest
-	GO111MODULE=on go install github.com/uudashr/gopkgs/v2/cmd/gopkgs@latest
-	GO111MODULE=on go install github.com/zmb3/gogetdoc@latest
-	GO111MODULE=on go install honnef.co/go/tools/cmd/staticcheck@latest
-	GO111MODULE=on go install golang.org/x/tools/cmd/gorename@latest
-
-	GO111MODULE=on go install github.com/go-delve/delve/cmd/dlv@master && cp "${TARGET}/dlv" "${TARGET}/dlv-dap"
-	GO111MODULE=on go install github.com/go-delve/delve/cmd/dlv@latest
-}
-
 main() {
   cd "$(root_dir)"  # always run from the script root.
   case "$1" in
@@ -144,9 +114,6 @@
     "prepare_nightly")
       prepare_nightly
       ;;
-    "setup_env")
-      install_dependencies
-      ;;
     *)
       usage
       exit 2
diff --git a/docs/debugging.md b/docs/debugging.md
index aa94e02..353c94f 100644
--- a/docs/debugging.md
+++ b/docs/debugging.md
@@ -1,16 +1,12 @@
 # Debugging
 
-The Go extension allows you to launch or attach to Go programs for debugging. You can inspect variables and stacks, setting breakpoints, and do other debugging activities using [VS Code’s Debugging UI](https://code.visualstudio.com/docs/editor/debugging).
+The Go extension allows you to launch or attach to Go programs for debugging. You can inspect variables and stacks, set breakpoints, and do other debugging activities using [VS Code’s Debugging UI](https://code.visualstudio.com/docs/editor/debugging).
 
 These debugging features are possible by using [Delve](https://github.com/go-delve/delve), the Go debugger.
 The Go extension has been communicating with Delve through a custom debug adapter program (`legacy` mode).
-As the new [`Delve`'s native DAP implementation](https://github.com/go-delve/delve/tree/master/service/dap) becomes available,
-the Go extension is transitioning to skip the legacy debug adapter and directly communicate with Delve for local debugging.
+As the new [`Delve`'s native debug adapter implementation](https://github.com/go-delve/delve/tree/master/service/dap) has become available, the Go extension is transitioning to deprecate the legacy debug adapter in favor of direct communication with Delve via [DAP](https://microsoft.github.io/debug-adapter-protocol/overview).
 
-** 📣 We are happy to announce that now this new mode of Delve integration (_`dlv-dap`_ mode) is enabled for _local_ _debugging_ by default! **
-
-Delve DAP implementation's support for remote debugging is still a work in progress and the Go extension still uses
-the legacy debug adapter for the debug configuration with the `"remote"` mode.
+ 📣 **We are happy to announce that now this new mode of Delve integration (_`dlv-dap`_ mode) is enabled for _local_ _debugging_ by default and is available for [_remote_ _debugging_](#remote-debugging) on demand!**
 
 Many features and settings described in this document may be available only with the new `dlv-dap` mode.
 For troubleshooting and configuring the legacy debug adapter, see [the legacy debug adapter documentation](https://github.com/golang/vscode-go/tree/master/docs/debugging-legacy.md).
@@ -62,6 +58,7 @@
 If you chose to switch to legacy because of bugs or limitations in the new debug adapter,
 please [open an issue](https://github.com/golang/vscode-go/issues/new)
 to help us improve the new debug adapter.
+
 ## Features
 
 For general debugging features such as inspecting variables, setting breakpoints, and other activities that aren't language-dependent, review [VS Code debugging](https://code.visualstudio.com/docs/editor/debugging).
@@ -90,10 +87,19 @@
     *   `exec`: debug a precompiled binary. The binary needs to be built with `-gcflags=all="-N -l"` flags to avoid stripping debugging information.
     *   `auto`: automatically choose between `debug` and `test` depending on the open file.
 
+⚠️ If a `port` attribute is added to any of the launch configurations, it will signal VS Code that instead of launching the debug server internally, it should connect to an external user-specified `dlv dap` server at `host:port` and launch the target there. See ["Remote Debugging"](#remote-debugging) for more details).
+
+The `program` attribute must point to the absolute path to the package or binary to debug in the remote host’s file system even when `substitutePath` is specified.
+
 ### Attach
 
-You can debug an already running program using the `attach` request type configuration. With the `attach` request, the Go extension starts `dlv-dap` and configures it to attach to the specified process. Users can select the process to debug with one of the following options:
+You can use this configuration to attach to a running process or a running debug session.
 
+*   Supported modes
+    *   `local`: attaches to a local process
+    *   `remote`: attaches to an in-progress debug session run by an external server
+
+You can debug an already running program using the `local` mode type configuration. The Go extension will start `dlv-dap` and configure it to attach to the specified process. Users can select the process to debug with one of the following options:
 
 *   Specifying the numeric process id (PID) with the `processId` attribute.
 *   Specifying the target program name in the `processId` attribute. If there are multiple processes matching the specified program name, the extension will show the list of matching processes at the start of the debug session.
@@ -103,10 +109,18 @@
 <img src="images/attach.gif" alt="Attach to a running process" width="75%">
 </p>
 
-When you end the debug session, the debug UI allows you to choose to either
+NOTE: If a `port` attribute is added to a local attach configuration, it will signal VS Code that instead of launching the debug server internally, it should connect to an external user-specified `dlv dap` server at `host:port` and attach to the target there. The process resolution features will only work if localhost is used. See ["Remote Debugging"](#remote-debugging) for more details).
 
-*   Disconnect: detach and leave the process running. (default)
-*   Terminate: terminate the attached process.
+You can connect to an already running remote debug session using the `remote` mode. Specify optional `host` and required `port` for the external `dlv --headless` server that already took program or process id details as command-line arguments. See ["Remote Debugging"](#remote-debugging) for more details).
+
+When you end an attach debug session, the debug UI allows you to choose to:
+
+*   [DEFAULT] Disconnect: disconnect the client and
+    * `local`: leave the target process running (dlv terminates).
+	* `remote`: let dlv decide if it can continue running (`--accept-multiclient` mode only); if so, the target will stay in halted or running state it was in at disconnect.
+	   * `dlv debug/test/exec`: terminate the target process if dlv terminates.
+	   * `dlv attach`: leave the target process running even if dlv terminates.
+*   Stop: stop the attached server and the target process.
 
 <p align="center">
 <img src="images/attach-terminate.gif" alt="Terminate Debugging started with Attach" style="width: 30%">
@@ -155,7 +169,7 @@
 <img src="images/function-breakpoint.gif" alt="Function breakpoint" width="75%">
 </p>
 
-*   Logpoint (WIP)
+*   **Logpoints**: a [logpoint](https://code.visualstudio.com/docs/editor/debugging#_logpoints) is a variant of breakpoint that does not 'break', but instead logs a message to Debug Console and continues execution. Expressions within `{}` are interpolated. For the list of acceptable expressions and syntax, see [Delve's documentation](https://github.com/go-delve/delve/blob/master/Documentation/cli/expr.md#expressions).
 
 ### Data Inspection
 
@@ -238,7 +252,7 @@
 | Property | Launch | Attach |
 | --- | --- | --- |
 | `args` | Command line arguments passed to the debugged program.<br/> | <center>_n/a_</center> |
-| `backend` | Backend used by delve. Maps to `dlv`'s `--backend` flag.<br/><p>Allowed Values: `"default"`, `"native"`, `"lldb"`<br/> | <center>_same as Launch_</center>|
+| `backend` | Backend used by delve. Maps to `dlv`'s `--backend` flag.<br/><p>Allowed Values: `"default"`, `"native"`, `"lldb"`, `"rr"`<br/> | <center>_same as Launch_</center>|
 | `buildFlags` | Build flags, to be passed to the Go compiler. Maps to dlv's `--build-flags` flag.<br/>(Default: `""`)<br/> | <center>_n/a_</center> |
 | `coreFilePath` | Path to the core dump file to open. For use on 'core' mode only<br/>(Default: `""`)<br/> | <center>_n/a_</center> |
 | `cwd` | Workspace relative or absolute path to the working directory of the program being debugged if a non-empty value is specified. The `program` folder is used as the working directory if `cwd` is omitted or empty.<br/>(Default: `""`)<br/> | Workspace relative or absolute path to the working directory of the program being debugged. Default is the current workspace.<br/>(Default: `"${workspaceFolder}"`)<br/> |
@@ -246,17 +260,19 @@
 | `dlvFlags` | Extra flags for `dlv`. See `dlv help` for the full list of supported. Flags such as `--log-output`, `--log`, `--log-dest`, `--api-version`, `--output`, `--backend` already have corresponding properties in the debug configuration, and flags such as `--listen` and `--headless` are used internally. If they are specified in `dlvFlags`, they may be ignored or cause an error.<br/> | <center>_same as Launch_</center>|
 | `env` | Environment variables passed to the program.<br/> | <center>_n/a_</center> |
 | `envFile` | Absolute path to a file containing environment variable definitions. Multiple files can be specified by provided an array of absolute paths<br/>(Default: `${workspaceFolder}/.env`)<br/> | <center>_n/a_</center> |
-| `host` | In legacy mode, this will only apply to remote-attach configurations, which will look for "dlv ... --headless --listen=<host>:<port>" server started externally. In dlv-dap mode (which does not yet support remote-attach), this will apply to all other configurations. The extension will try to connect to an external server started with "dlv dap --listen=<host>:<port>" to ask it to launch/attach to the target process.<br/>(Default: `"127.0.0.1"`)<br/> | <center>_same as Launch_</center>|
+| `hideSystemGoroutines` | Boolean value to indicate whether system goroutines should be hidden from call stack view.<br/>(Default: `false`)<br/> | <center>_same as Launch_</center>|
+| `host` | When applied to remote-attach configurations, will look for "dlv ... --headless --listen=<host>:<port>" server started externally. In dlv-dap mode this will apply to all other configurations as well. The extension will try to connect to an external server started with "dlv dap --listen=<host>:<port>" to ask it to launch/attach to the target process.<br/>(Default: `"127.0.0.1"`)<br/> | When applied to remote-attach configurations, will look for "dlv ... --headless --listen=<host>:<port>" server started externally. In dlv-dap mode, this will apply to all other configurations as well. The extension will try to connect to an external server started with "dlv dap --listen=<host>:<port>" to ask it to launch/attach to the target process.<br/>(Default: `"127.0.0.1"`)<br/> |
 | `logDest` | dlv's `--log-dest` flag. See `dlv log` for details. Number argument is not allowed. Supported only in `dlv-dap` mode, and on Linux and Mac OS.<br/> | dlv's `--log-dest` flag. See `dlv log` for details. Number argument is not allowed. Supported only in `dlv-dap` mode and on Linux and Mac OS.<br/> |
 | `logOutput` | Comma separated list of components that should produce debug output. Maps to dlv's `--log-output` flag. Check `dlv log` for details.<br/><p>Allowed Values: `"debugger"`, `"gdbwire"`, `"lldbout"`, `"debuglineerr"`, `"rpc"`, `"dap"`<br/>(Default: `"debugger"`)<br/> | <center>_same as Launch_</center>|
-| `mode` | One of `auto`, `debug`, `test`, `exec`, `replay`, `core`. In `auto` mode, the extension will choose either `debug` or `test` depending on active editor window.<br/><p>Allowed Values: `"auto"`, `"debug"`, `"test"`, `"exec"`, `"replay"`, `"core"`<br/>(Default: `auto`)<br/> | Indicates local or remote debugging. Local maps to the `dlv attach` command, remote maps to `connect`. `remote` is not supported in `dlv-dap` mode currently. Use `host` and `port` instead.<br/><p>Allowed Values: `"local"`, `"remote"`<br/>(Default: `local`)<br/> |
+| `mode` | One of `auto`, `debug`, `test`, `exec`, `replay`, `core`. In `auto` mode, the extension will choose either `debug` or `test` depending on active editor window.<br/><p>Allowed Values: `"auto"`, `"debug"`, `"test"`, `"exec"`, `"replay"`, `"core"`<br/>(Default: `auto`)<br/> | Indicates local or remote debugging. Local is similar to the `dlv attach` command, remote - to `dlv connect`<br/><p>Allowed Values: `"local"`, `"remote"`<br/>(Default: `local`)<br/> |
 | `output` | Output path for the binary of the debugee.<br/>(Default: `"debug"`)<br/> | <center>_n/a_</center> |
-| `port` | In legacy mode, this will only apply to remote-attach configurations, which will look for "dlv ... --headless --listen=<host>:<port>" server started externally. In dlv-dap mode (which does not yet support remote-attach), this will apply to all other configurations. The extension will try to connect to an external server started with "dlv dap --listen=<host>:<port>" to ask it to launch/attach to the target process.<br/>(Default: `2345`)<br/> | <center>_same as Launch_</center>|
+| `port` | When applied to remote-attach configurations, will look for "dlv ... --headless --listen=<host>:<port>" server started externally. In dlv-dap mode this will apply to all other configurations as well. The extension will try to connect to an external server started with "dlv dap --listen=<host>:<port>" to ask it to launch/attach to the target process.<br/>(Default: `2345`)<br/> | When applied to remote-attach configurations, will look for "dlv ... --headless --listen=<host>:<port>" server started externally. In dlv-dap mode, this will apply to all other configurations as well. The extension will try to connect to an external server started with "dlv dap --listen=<host>:<port>" to ask it to launch/attach to the target process.<br/>(Default: `2345`)<br/> |
 | `processId` | <center>_n/a_</center> | <br/><p><b>Option 1:</b> Use process picker to select a process to attach, or Process ID as integer.<br/><p>Allowed Values: `"${command:pickProcess}"`, `"${command:pickGoProcess}"`<br/><br/><p><b>Option 2:</b> Attach to a process by name. If more than one process matches the name, use the process picker to select a process.<br/><br/><p><b>Option 3:</b> The numeric ID of the process to be debugged. If 0, use the process picker to select a process.<br/><br/>(Default: `0`)<br/> |
 | `program` | Path to the program folder (or any go file within that folder) when in `debug` or `test` mode, and to the pre-built binary file to debug in `exec` mode. If it is not an absolute path, the extension interpretes it as a workspace relative path.<br/>(Default: `"${workspaceFolder}"`)<br/> | <center>_n/a_</center> |
-| `remotePath` | <center>_n/a_</center> | (Deprecated) *Use `substitutePath` instead.*<br/>The path to the source code on the remote machine, when the remote path is different from the local machine. If specified, becomes the first entry in substitutePath.<br/>(Default: `""`)<br/> |
+| `remotePath` | <center>_n/a_</center> | (Deprecated) *Use `substitutePath` instead.*<br/>The path to the source code on the remote machine, when the remote path is different from the local machine. If specified, becomes the first entry in substitutePath. Not supported with `dlv-dap`.<br/>(Default: `""`)<br/> |
 | `showGlobalVariables` | Boolean value to indicate whether global package variables should be shown in the variables pane or not.<br/>(Default: `false`)<br/> | <center>_same as Launch_</center>|
 | `showLog` | Show log output from the delve debugger. Maps to dlv's `--log` flag.<br/>(Default: `false`)<br/> | <center>_same as Launch_</center>|
+| `showRegisters` | Boolean value to indicate whether register variables should be shown in the variables pane or not.<br/>(Default: `false`)<br/> | <center>_same as Launch_</center>|
 | `stackTraceDepth` | Maximum depth of stack trace collected from Delve.<br/>(Default: `50`)<br/> | <center>_same as Launch_</center>|
 | `stopOnEntry` | Automatically stop program after launch.<br/>(Default: `false`)<br/> | Automatically stop program after attach.<br/>(Default: `false`)<br/> |
 | `substitutePath` | An array of mappings from a local path (editor) to the remote path (debugee). This setting is useful when working in a file system with symbolic links, running remote debugging, or debugging an executable compiled externally. The debug adapter will replace the local path with the remote path in all of the calls.<br/><p><br/><ul><li>`"from"`: The absolute local path to be replaced when passing paths to the debugger.<br/>(Default: `""`)<br/></li><li>`"to"`: The absolute remote path to be replaced when passing paths back to the client.<br/>(Default: `""`)<br/></li></ul><br/> | An array of mappings from a local path (editor) to the remote path (debugee). This setting is useful when working in a file system with symbolic links, running remote debugging, or debugging an executable compiled externally. The debug adapter will replace the local path with the remote path in all of the calls.  Overriden by `remotePath`.<br/><p><br/><ul><li>`"from"`: The absolute local path to be replaced when passing paths to the debugger.<br/>(Default: `""`)<br/></li><li>`"to"`: The absolute remote path to be replaced when passing paths back to the client.<br/>(Default: `""`)<br/></li></ul><br/> |
@@ -268,18 +284,18 @@
 
 ### **Debugging symlink directories**
 
-Since the debugger and go compiler use the actual filenames, extra configuration is required to debug symlinked directories. Use the substitutePath property to tell the `debugAdapter` how to properly translate the paths. For example, if your project lives in `/path/to/actual/helloWorld`, but the project is open in vscode under the linked folder `/path/to/hello`, you can add the following to your config to set breakpoints in the files in `/path/to/hello`:
+Since the debugger and go compiler use the actual filenames, extra configuration is required to debug symlinked directories. Use the `substitutePath` property to tell the `debugAdapter` how to properly translate the paths. For example, if your project lives in `/path/to/actual/helloWorld`, but the project is open in vscode under the linked folder `/link/to/helloWorld`, you can add the following to your config to set breakpoints in the files in `/link/to/helloWorld`:
 
 ```
 {
-    "name": "Launch remote",
+    "name": "Launch with symlinks",
     "type": "go",
     "request": "launch",
     "mode": "debug",
     "program": "/path/to/actual/helloWorld",
     "substitutePath": [
 		{
-			"from": "/path/to/hello",
+			"from": "/link/to/helloWorld",
 			"to": "/path/to/actual/helloWorld",
 		},
 	],
@@ -351,15 +367,139 @@
 
 > If you are able to use the [Remote Development](https://aka.ms/vscode-remote/download/extension) extensions and VS Code’s  universal [remote development capabilities](https://code.visualstudio.com/docs/remote/remote-overview), that is the recommended way to debug Go programs remotely. Check out [Getting started](https://code.visualstudio.com/docs/remote/remote-overview#_getting-started) section and [Remote tutorials](https://code.visualstudio.com/docs/remote/remote-overview#_remote-tutorials) to learn more.
 
-🚧 Remote debugging is the debug mode intended to work with a debugger and target running on a different machine or a container. Support for remote debugging using Delve’s native DAP implementation is still a work-in-progress. Please fall back to the `legacy` debug adapter.
+Remote debugging is the debug mode commonly used to work with a debugger and target running on a remote machine or a container. In spite of its name, it can also be used on a local machine with server started in an external terminal (e.g. to support entering stdin into the server's terminal window).
+
+With the introduction of `dlv dap` users now have two options for remote (i.e. external) debugging.
+
+#### Connecting to Headless Delve with Target Specified at Server Start-Up
+
+In this mode the user must first manually start a [`dlv --headless`](https://github.com/go-delve/delve/tree/master/Documentation/api) server listening at `host:port` while specifying the target program to debug/test/exec or a process to attach to on the command-line. A [remote attach](#attach) configuration is then used to connect to the debugger with a running target.
+
+The [headless dlv server](https://github.com/go-delve/delve/tree/master/Documentation/api) can now be used with both `"debugAdapter": "legacy"` (default value) and `"debugAdapter": "dlv-dap"` (with Delve v1.7.3 or newer) as well as Delve's [command-line interface](https://github.com/go-delve/delve/tree/master/Documentation/cli) via `dlv connect`. The `--accept-multiclient` flag can be used to make this a multi-use server that persists on `Disconnect` from a client and allows repeated client connections. Please see `dlv --help` and `dlv [command] --help` for dlv's command-line options.
+
+We encourage you to give the newly added `"debugAdapter": "dlv-dap"` support a try and to [let us know of any issues](https://github.com/golang/vscode-go/issues/new). If you need to use the `legacy` mode, pleasse also see the [legacy remote debugging](https://github.com/golang/vscode-go/blob/master/docs/debugging-legacy.md#remote-debugging) documentation.
+
+For example, start external headless server:
+```
+dlv debug /path/to/program/ --headless --listen=:12345
+```
+
+Connect to it with a remote attach configuration in your `launch.json`:
+```json5
+{
+    "name": "Connect to external session",
+    "type": "go",
+    "debugAdapter": "dlv-dap", // `legacy` by default
+    "request": "attach",
+    "mode": "remote",
+    "port": 12345,
+    "host": "127.0.0.1", // can skip for localhost
+    "substitutePath": [
+      { "from": ${workspaceFolder}, "to": "/path/to/remote/workspace" },
+      ...
+  ]
+}
+```
+
+#### Connecting to Delve DAP with Target Specified at Client Start-Up
+
+In this mode the user must first manually start a [`dlv dap` server](https://github.com/go-delve/delve/blob/master/Documentation/usage/dlv_dap.md) listening at `host:port` and then specify the target program via [launch](#launch) or [attach](#attach) client config with a `"port"` attribute. Instead of starting a new local server, the Go extension will tell VS Code to connect to the server specified by `host:port` attributes and then send a request with the target to debug. This option provides the flexibility of easily adapting local configurations to connect to external servers, but ⚠️ must be used with care since anyone who can connect to the server can make it run arbitrary programs.
+
+When using `launch` mode, the `program` attribute must point to the absolute path of the package or binary to debug in the remote host’s file system even when `substitutePath` is specified. When using `attach` mode outside of local host, you need to specify the `processId` in the config since [the processId resolution feature](#attach) cannot gather information about processes running remotely.
+
+<!-- TODO: update or remote this picture
+<p align="center"><img src="images/remote-debugging.png" alt="Remote Debugging"> </p>
+-->
+
+Start a dlv-dap server ready to accept a client request to launch or attach to a target process:
+```
+$ dlv-dap dap --listen=:12345
+```
+
+Use the following `launch` configuration to tell `dlv-dap` to execute a binary precompiled with `-gcflags='all=-N -l'`:
+
+```json5
+{
+  "name": "Connect and launch",
+  "type": "go",
+  "debugAdapter": "dlv-dap", // the default
+  "request": "launch",
+  "port": 12345,
+  "host": "127.0.0.1", // can skip for localhost
+  "mode": "exec",
+  "program": "/absolute/path/to/remote/workspace/program/executable",
+  "substitutePath": [
+      { "from": ${workspaceFolder}, "to": "/path/to/remote/workspace" },
+      ...
+  ]
+}
+```
+
+Or have the binary compiled by dlv-dap by modifying the above configuration to use:
+
+```json5
+  "mode": "debug",
+  "program": "/absolute/path/to/remote/workspace/package",
+```
+
+⚠️ Limitations
+*   Delve DAP does not support `--accept-multiclient` or `--continue` flags, which means after a debug session ends, the dlv-dap process will always exit.
+*   If you use `debug` or `test` mode `launch` requests, Delve builds the target binary. Delve tries to build the target from the directory where the `dlv` (or `dlv-dap`) process is running, so make sure to run the `dlv-dap` command from the directory you would run the `go build` or `go test` command.
 
 ### Running Debugee Externally
 
-Sometimes you’d like to launch the program for debugging outside VS Code (e.g., as a workaround of the missing `console` support), there are currently two options.
+Sometimes you might like to launch the program for debugging outside of VS Code (e.g. as a workaround of the missing `console` support to enter stdin via an external terminal or separate target's output from debug session logging). There are currently two options:
 
-*   Compile and run the program from the external terminal and use [the "attach" configuration](#attach).
-*   Launch the server externally; run `dlv-dap dap --listen=:<port>` from the external terminal, and set the `"debugServer": <port>` attribute in your launch configuration.
+*   Compile and run the target program from the external terminal and use [the "attach" configuration](#attach).
+*   Run the debug server from the external terminal with `--listen=:<port>` and have VS Code connect to it using `port` in your launch configuration (see ["Remote Debugging"](#remote-debugging) for more details)
 
+## Troubleshooting
+
+The suggestions below are intended to help you troubleshoot any problems you encounter. If you are unable to resolve the issue, please take a look at the [current known debugging issues](https://github.com/golang/vscode-go/issues?q=is%3Aissue+is%3Aopen+label%3ADebug) or [report a new issue](#reporting-issues).
+
+1. Read documentation and [FAQs](#faqs). Also check the [Delve FAQ](https://github.com/go-delve/delve/blob/master/Documentation/faq.md) in case the problem is mentioned there.
+1. Check your `launch.json` configuration. Often error messages appearing in the DEBUG CONSOLE panel reveal issues.
+1. Update Delve (`dlv-dap`) to pick up most recent bug fixes. Follow [the instruction](https://github.com/golang/vscode-go/blob/master/docs/debugging.md#staying-up-to-date).
+1. Check if you can reproduce the issue with `dlv`, the command line tool from the integrated terminal. <!-- TODO(vscode-go): add instructions https://github.com/golang/vscode-go/issues/1931 --> If it's reproducible when using `dlv`, take a look at the [delve's issue tracker](https://github.com/go-delve/delve/issues).
+1. Capture [logs](https://github.com/golang/vscode-go/blob/master/docs/debugging.md#collecting-logs) and inspect them.
+1. Look at the [existing debugging issues](https://github.com/golang/vscode-go/labels/Debug) if similar issues were reported.
+1. If none of these solve your problem, please [open a new issue](#reporting-issues).
+
+## FAQs
+
+### I need to view large strings. How can I do that if `dlvLoadConfig` with `maxStringLen` is deprecated?
+
+The legacy adapter used `dlvLoadConfig` as one-time session-wide setting to override dlv's conservative default variable loading limits, intended to protect tool's performance. The new debug adapter is taking a different approach with on-demand loading of composite data and updated string limits, relaxed when interacting with individual strings. In particular, if the new default limit of 512, applied to all string values in the variables pane, is not sufficient, you can take advantage of a larger limit of 4096 with one of the following:
+
+*   Hover over the variable in the source code
+*   `Copy as Expression` to query the string via REPL in the DEBUG CONSOLE panel
+*   `Copy Value` to clipboard
+
+Please [open an issue](https://github.com/golang/vscode-go/issues/new) if this is not sufficient for your use case or if you have any additional feedback.
+
+### Why does my debug session have an `invalid command` error when I try to step?
+
+When stepping through a program on a particular goroutine, the debugger will make sure that the step is completed, even when interrupted by events on a different goroutine. If a breakpoint is hit on a different goroutine, the debug adapter will stop the program execution to allow you to inspect the state, even though the step request is still active.
+
+If you attempt to make another step request you will get an `invalid command` error.
+
+<p align="center"><img src="images/invalidCommandExceptionInfo.png" alt="Disable breakpoints from the Breakpoints context menu" width="75%"> </p>
+
+Use `Continue` to resume program execution.
+
+If you do not want the step request to be interrupted, you can disable all breakpoints from VS Code from the context menu in the `Breakpoints` view.
+
+<p align="center"><img src="images/disablebps.png" alt="Disable breakpoints from the Breakpoints context menu" width="75%"> </p>
+
+### My program does not stop at breakpoints.
+
+Check the "BREAKPOINTS" section in the debug view and see if the breakpoints are [greyed out](https://code.visualstudio.com/docs/editor/debugging#_breakpoints) when your debug session is active. Setting `stopOnEntry` is a great way to pause execution at the start to _verify_ breakpoints are set correctly. Or [enable logging](#collecting-logs) and see if `setBreakpoints` requests succeeded with all the breakpoints _verified_.
+
+This problem often occurs when the source location used in compiling the debugged program and the workspace directory VS Code uses are different. Common culprits are remote debugging where the program is built in the remote location, use of symbolic links, or use of `-trimpath` build flags. In this case, configure the `substitutePath` attribute in your launch configuration.
+
+### Debug sessions started with the "debug test" CodeLens or the test UI does not use my `launch.json` configuration.
+
+The "debug test" CodeLens and the [test UI](https://github.com/golang/vscode-go/blob/master/docs/features.md#test-and-benchmark) do not use the `launch.json` configuration ([Issue 855](https://github.com/golang/vscode-go/issues/855)). As a workaround, use the `go.delveConfig` setting and the `go.testFlags` setting. Please note that these all apply to all debug sessions unless overwritten by a specific `launch.json` configuration.
 ## Reporting Issues
 
 When you are having issues in `dlv-dap` mode, first check if the problems are reproducible after updating `dlv-dap`. It's possible that the problems are already fixed. Follow the instruction for [updating dlv-dap](#updating-dlv-dap)) and [updating extension](https://code.visualstudio.com/docs/editor/extension-gallery#\_extension-autoupdate).
@@ -421,40 +561,10 @@
     "request": "launch",
     "debugAdapter": "dlv-dap",
     ...
-    "debugServer": 12345,
+    "port": 12345
 }
 ```
 
-## FAQs
-
-### Why does my debug session stop when I set breakpoints?
-
-To support being able to set breakpoints while the program is running, the debug adapter needs to stop the program. Due to the extra synchronization required to correctly resume the program, the debug adapter currently sends a stopped event. This means that if you are editing breakpoints while the program is running, you will need to hit continue to continue your debug session. We plan to change the behavior of the debug adapter for more seamless editing of breakpoints. You can track the progress [here](https://github.com/golang/vscode-go/issues/1676).
-
-### I need to view large strings. How can I do that if `dlvLoadConfig` with `maxStringLen` is deprecated?
-
-The legacy adapter used `dlvLoadConfig` as one-time session-wide setting to override dlv's conservative default variable loading limits, intended to protect tool's performance. The new debug adapter is taking a different approach with on-demand loading of composite data and updated string limits, relaxed when interacting with individual strings. In particular, if the new default limit of 512, applied to all string values in the variables pane, is not sufficient, you can take advantage of a larger limit of 4096 with one of the following:
-
-*   Hover over the variable in the source code
-*   `Copy as Expression` to query the string via REPL in the DEBUG CONSOLE panel
-*   `Copy Value` to clipboard
-
-Please [open an issue](https://github.com/golang/vscode-go/issues/new) if this is not sufficient for your use case or if you have any additional feedback.
-
-### Why does my debug session have an `invalid command` error when I try to step?
-
-When stepping through a program on a particular goroutine, the debugger will make sure that the step is completed, even when interrupted by events on a different goroutine. If a breakpoint is hit on a different goroutine, the debug adapter will stop the program execution to allow you to inspect the state, even though the step request is still active.
-
-If you attempt to make another step request you will get an `invalid command` error.
-
-<p align="center"><img src="images/invalidCommandExceptionInfo.png" alt="Disable breakpoints from the Breakpoints context menu" width="75%"> </p>
-
-
-Use `Continue` to resume program execution.
-
-If you do not want the step request to be interrupted, you can disable all breakpoints from VS Code from the context menu in the `Breakpoints` view.
-
-<p align="center"><img src="images/disablebps.png" alt="Disable breakpoints from the Breakpoints context menu" width="75%"> </p>
 
 
 [Delve]: https://github.com/go-delve/delve
diff --git a/docs/settings.md b/docs/settings.md
index 51350f3..ab15c93 100644
--- a/docs/settings.md
+++ b/docs/settings.md
@@ -146,9 +146,11 @@
 | `debugAdapter` | Select which debug adapter to use by default. This is also used for choosing which debug adapter to use when no launch.json is present and with codelenses. <br/> Allowed Options: `legacy`, `dlv-dap` <br/> Default: `"dlv-dap"` |
 | `dlvFlags` | Extra flags for `dlv`. See `dlv help` for the full list of supported. Flags such as `--log-output`, `--log`, `--log-dest`, `--api-version`, `--output`, `--backend` already have corresponding properties in the debug configuration, and flags such as `--listen` and `--headless` are used internally. If they are specified in `dlvFlags`, they may be ignored or cause an error. |
 | `dlvLoadConfig` | LoadConfig describes to delve, how to load values from target's memory. Ignored by 'dlv-dap'. <br/> Default: ``` { <pre>"followPointers" :	true,<br/>"maxArrayValues" :	64,<br/>"maxStringLen" :	64,<br/>"maxStructFields" :	-1,<br/>"maxVariableRecurse" :	1,</pre>} ``` |
+| `hideSystemGoroutines` | Boolean value to indicate whether system goroutines should be hidden from call stack view. <br/> Default: `false` |
 | `logOutput` | Comma separated list of components that should produce debug output. Maps to dlv's `--log-output` flag. Check `dlv log` for details. <br/> Allowed Options: `debugger`, `gdbwire`, `lldbout`, `debuglineerr`, `rpc`, `dap` <br/> Default: `"debugger"` |
 | `showGlobalVariables` | Boolean value to indicate whether global package variables should be shown in the variables pane or not. <br/> Default: `false` |
 | `showLog` | Show log output from the delve debugger. Maps to dlv's `--log` flag. <br/> Default: `false` |
+| `showRegisters` | Boolean value to indicate whether register variables should be shown in the variables pane or not. <br/> Default: `false` |
 | `substitutePath` | An array of mappings from a local path to the remote path that is used by the debuggee. The debug adapter will replace the local path with the remote path in all of the calls. Overriden by `remotePath` (in attach request). |
 ### `go.disableConcurrentTests`
 
diff --git a/package-lock.json b/package-lock.json
index 63c1c5f..4429547 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
 {
   "name": "go",
-  "version": "0.29.0",
+  "version": "0.30.0",
   "lockfileVersion": 2,
   "requires": true,
   "packages": {
     "": {
       "name": "go",
-      "version": "0.29.0",
+      "version": "0.30.0",
       "license": "MIT",
       "dependencies": {
         "deep-equal": "^2.0.2",
@@ -3082,9 +3082,9 @@
       }
     },
     "node_modules/json-schema": {
-      "version": "0.2.3",
-      "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
-      "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM="
+      "version": "0.4.0",
+      "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz",
+      "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA=="
     },
     "node_modules/json-schema-traverse": {
       "version": "0.4.1",
@@ -3138,17 +3138,17 @@
       ]
     },
     "node_modules/jsprim": {
-      "version": "1.4.1",
-      "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
-      "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=",
-      "engines": [
-        "node >=0.6.0"
-      ],
+      "version": "1.4.2",
+      "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz",
+      "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==",
       "dependencies": {
         "assert-plus": "1.0.0",
         "extsprintf": "1.3.0",
-        "json-schema": "0.2.3",
+        "json-schema": "0.4.0",
         "verror": "1.10.0"
+      },
+      "engines": {
+        "node": ">=0.6.0"
       }
     },
     "node_modules/just-extend": {
@@ -8032,9 +8032,9 @@
       }
     },
     "json-schema": {
-      "version": "0.2.3",
-      "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
-      "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM="
+      "version": "0.4.0",
+      "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz",
+      "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA=="
     },
     "json-schema-traverse": {
       "version": "0.4.1",
@@ -8077,13 +8077,13 @@
       "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA="
     },
     "jsprim": {
-      "version": "1.4.1",
-      "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
-      "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=",
+      "version": "1.4.2",
+      "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz",
+      "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==",
       "requires": {
         "assert-plus": "1.0.0",
         "extsprintf": "1.3.0",
-        "json-schema": "0.2.3",
+        "json-schema": "0.4.0",
         "verror": "1.10.0"
       }
     },
diff --git a/package.json b/package.json
index 6aeab6f..45f23ab 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
 {
   "name": "go",
   "displayName": "Go",
-  "version": "0.29.0",
+  "version": "0.30.0",
   "publisher": "golang",
   "description": "Rich Go language support for Visual Studio Code",
   "author": {
@@ -90,8 +90,10 @@
     "vscode": "^1.59.0"
   },
   "activationEvents": [
-    "workspaceContains:**/*.go",
     "onLanguage:go",
+    "workspaceContains:*.go",
+    "workspaceContains:*/*.go",
+    "workspaceContains:*/*/*.go",
     "onCommand:go.gopath",
     "onCommand:go.tools.install",
     "onCommand:go.locate.tools",
@@ -653,12 +655,12 @@
               },
               "port": {
                 "type": "number",
-                "description": "In legacy mode, this will only apply to remote-attach configurations, which will look for \"dlv ... --headless --listen=<host>:<port>\" server started externally. In dlv-dap mode (which does not yet support remote-attach), this will apply to all other configurations. The extension will try to connect to an external server started with \"dlv dap --listen=<host>:<port>\" to ask it to launch/attach to the target process.",
+                "description": "When applied to remote-attach configurations, will look for \"dlv ... --headless --listen=<host>:<port>\" server started externally. In dlv-dap mode this will apply to all other configurations as well. The extension will try to connect to an external server started with \"dlv dap --listen=<host>:<port>\" to ask it to launch/attach to the target process.",
                 "default": 2345
               },
               "host": {
                 "type": "string",
-                "description": "In legacy mode, this will only apply to remote-attach configurations, which will look for \"dlv ... --headless --listen=<host>:<port>\" server started externally. In dlv-dap mode (which does not yet support remote-attach), this will apply to all other configurations. The extension will try to connect to an external server started with \"dlv dap --listen=<host>:<port>\" to ask it to launch/attach to the target process.",
+                "description": "When applied to remote-attach configurations, will look for \"dlv ... --headless --listen=<host>:<port>\" server started externally. In dlv-dap mode this will apply to all other configurations as well. The extension will try to connect to an external server started with \"dlv dap --listen=<host>:<port>\" to ask it to launch/attach to the target process.",
                 "default": "127.0.0.1"
               },
               "trace": {
@@ -690,7 +692,8 @@
                 "enum": [
                   "default",
                   "native",
-                  "lldb"
+                  "lldb",
+                  "rr"
                 ],
                 "description": "Backend used by delve. Maps to `dlv`'s `--backend` flag."
               },
@@ -772,6 +775,16 @@
                 "type": "boolean",
                 "default": false,
                 "description": "Boolean value to indicate whether global package variables should be shown in the variables pane or not."
+              },
+              "showRegisters": {
+                "type": "boolean",
+                "default": false,
+                "description": "Boolean value to indicate whether register variables should be shown in the variables pane or not."
+              },
+              "hideSystemGoroutines": {
+                "type": "boolean",
+                "default": false,
+                "description": "Boolean value to indicate whether system goroutines should be hidden from call stack view."
               }
             }
           },
@@ -811,7 +824,7 @@
                   "local",
                   "remote"
                 ],
-                "description": "Indicates local or remote debugging. Local maps to the `dlv attach` command, remote maps to `connect`. `remote` is not supported in `dlv-dap` mode currently. Use `host` and `port` instead.",
+                "description": "Indicates local or remote debugging. Local is similar to the `dlv attach` command, remote - to `dlv connect`",
                 "default": "local"
               },
               "stopOnEntry": {
@@ -839,18 +852,18 @@
               },
               "remotePath": {
                 "type": "string",
-                "description": "The path to the source code on the remote machine, when the remote path is different from the local machine. If specified, becomes the first entry in substitutePath.",
+                "description": "The path to the source code on the remote machine, when the remote path is different from the local machine. If specified, becomes the first entry in substitutePath. Not supported with `dlv-dap`.",
                 "markdownDeprecationMessage": "Use `substitutePath` instead.",
                 "default": ""
               },
               "port": {
                 "type": "number",
-                "description": "In legacy mode, this will only apply to remote-attach configurations, which will look for \"dlv ... --headless --listen=<host>:<port>\" server started externally. In dlv-dap mode (which does not yet support remote-attach), this will apply to all other configurations. The extension will try to connect to an external server started with \"dlv dap --listen=<host>:<port>\" to ask it to launch/attach to the target process.",
+                "description": "When applied to remote-attach configurations, will look for \"dlv ... --headless --listen=<host>:<port>\" server started externally. In dlv-dap mode, this will apply to all other configurations as well. The extension will try to connect to an external server started with \"dlv dap --listen=<host>:<port>\" to ask it to launch/attach to the target process.",
                 "default": 2345
               },
               "host": {
                 "type": "string",
-                "description": "In legacy mode, this will only apply to remote-attach configurations, which will look for \"dlv ... --headless --listen=<host>:<port>\" server started externally. In dlv-dap mode (which does not yet support remote-attach), this will apply to all other configurations. The extension will try to connect to an external server started with \"dlv dap --listen=<host>:<port>\" to ask it to launch/attach to the target process.",
+                "description": "When applied to remote-attach configurations, will look for \"dlv ... --headless --listen=<host>:<port>\" server started externally. In dlv-dap mode, this will apply to all other configurations as well. The extension will try to connect to an external server started with \"dlv dap --listen=<host>:<port>\" to ask it to launch/attach to the target process.",
                 "default": "127.0.0.1"
               },
               "substitutePath": {
@@ -891,7 +904,8 @@
                 "enum": [
                   "default",
                   "native",
-                  "lldb"
+                  "lldb",
+                  "rr"
                 ],
                 "description": "Backend used by delve. Maps to `dlv`'s `--backend` flag."
               },
@@ -968,6 +982,16 @@
                 "type": "boolean",
                 "default": false,
                 "description": "Boolean value to indicate whether global package variables should be shown in the variables pane or not."
+              },
+              "showRegisters": {
+                "type": "boolean",
+                "default": false,
+                "description": "Boolean value to indicate whether register variables should be shown in the variables pane or not."
+              },
+              "hideSystemGoroutines": {
+                "type": "boolean",
+                "default": false,
+                "description": "Boolean value to indicate whether system goroutines should be hidden from call stack view."
               }
             }
           }
@@ -1819,6 +1843,16 @@
               "description": "Boolean value to indicate whether global package variables should be shown in the variables pane or not.",
               "default": false
             },
+            "showRegisters": {
+              "type": "boolean",
+              "default": false,
+              "description": "Boolean value to indicate whether register variables should be shown in the variables pane or not."
+            },
+            "hideSystemGoroutines": {
+              "type": "boolean",
+              "default": false,
+              "description": "Boolean value to indicate whether system goroutines should be hidden from call stack view."
+            },
             "showLog": {
               "type": "boolean",
               "description": "Show log output from the delve debugger. Maps to dlv's `--log` flag.",
diff --git a/src/debugAdapter/goDebug.ts b/src/debugAdapter/goDebug.ts
index 1ad80c5..840d148 100644
--- a/src/debugAdapter/goDebug.ts
+++ b/src/debugAdapter/goDebug.ts
@@ -456,7 +456,7 @@
 				this.isRemoteDebugging = true;
 				this.goroot = await queryGOROOT(dlvCwd, process.env);
 				serverRunning = true; // assume server is running when in remote mode
-				connectClient(launchArgs.port, launchArgs.host);
+				connectClient(launchArgs.port, launchArgs.host, this.onclose);
 				return;
 			}
 			this.isRemoteDebugging = false;
@@ -701,18 +701,18 @@
 				env
 			});
 
-			function connectClient(port: number, host: string) {
+			function connectClient(port: number, host: string, onClose?: Delve['onclose']) {
 				// Add a slight delay to avoid issues on Linux with
 				// Delve failing calls made shortly after connection.
 				setTimeout(() => {
-					const client = Client.$create(port, host);
-					client.connectSocket((err, conn) => {
-						if (err) {
-							return reject(err);
-						}
-						return resolve(conn);
-					});
-					client.on('error', reject);
+					const conn = Client.$create(port, host).connectSocket();
+
+					conn.on('connect', () => resolve(conn))
+						.on('error', reject)
+						.on('close', (hadError) => {
+							logError('Socket connection to remote was closed');
+							onClose?.(hadError ? 1 : 0);
+						});
 				}, 200);
 			}
 
@@ -729,7 +729,7 @@
 				}
 				if (!serverRunning) {
 					serverRunning = true;
-					connectClient(launchArgs.port, launchArgs.host);
+					connectClient(launchArgs.port, launchArgs.host, this.onclose);
 				}
 			});
 			this.debugProcess.on('close', (code) => {
diff --git a/src/goDebugConfiguration.ts b/src/goDebugConfiguration.ts
index c21ec0a..dc6055c 100644
--- a/src/goDebugConfiguration.ts
+++ b/src/goDebugConfiguration.ts
@@ -10,6 +10,7 @@
 import { lstatSync } from 'fs';
 import path = require('path');
 import vscode = require('vscode');
+import { ContinuedEvent } from 'vscode-debugadapter';
 import { getGoConfig } from './config';
 import { toolExecutionEnvironment } from './goEnv';
 import {
@@ -27,7 +28,7 @@
 import { parseEnvFiles } from './utils/envUtils';
 import { resolveHomeDir } from './utils/pathUtils';
 
-let dlvDAPVersionCurrent = false;
+let dlvDAPVersionChecked = false;
 
 export class GoDebugConfigurationProvider implements vscode.DebugConfigurationProvider {
 	constructor(private defaultDebugAdapterType: string = 'go') {}
@@ -140,6 +141,15 @@
 			debugConfiguration['type'] = this.defaultDebugAdapterType;
 		}
 
+		if (!debugConfiguration['mode']) {
+			if (debugConfiguration.request === 'launch') {
+				// 'auto' will decide mode by checking file extensions later
+				debugConfiguration['mode'] = 'auto';
+			} else if (debugConfiguration.request === 'attach') {
+				debugConfiguration['mode'] = 'local';
+			}
+		}
+
 		debugConfiguration['packagePathToGoModPathMap'] = packagePathToGoModPathMap;
 
 		const goConfig = getGoConfig(folder && folder.uri);
@@ -155,21 +165,24 @@
 			}
 		}
 		if (!debugConfiguration['debugAdapter']) {
-			// for local mode, default to dlv-dap.
+			// For local modes, default to dlv-dap. For remote - to legacy for now.
 			debugConfiguration['debugAdapter'] = debugConfiguration['mode'] !== 'remote' ? 'dlv-dap' : 'legacy';
 		}
-		if (debugConfiguration['debugAdapter'] === 'dlv-dap' && debugConfiguration['mode'] === 'remote') {
-			this.showWarning(
-				'ignoreDlvDAPInRemoteModeWarning',
-				"debugAdapter type of 'dlv-dap' with mode 'remote' is unsupported. Fall back to the 'legacy' debugAdapter for 'remote' mode."
-			);
-			debugConfiguration['debugAdapter'] = 'legacy';
-		}
-		if (debugConfiguration['debugAdapter'] === 'dlv-dap' && debugConfiguration['port']) {
-			this.showWarning(
-				'ignorePortUsedInDlvDapWarning',
-				"`port` is used with the 'dlv-dap' debugAdapter to support [launching the debug adapter server externally](https://github.com/golang/vscode-go/blob/master/docs/debugging.md#running-debugee-externally). Remove 'host' and 'port' from your launch.json if you are not launching a DAP server."
-			);
+		if (debugConfiguration['debugAdapter'] === 'dlv-dap') {
+			if (debugConfiguration['mode'] === 'remote') {
+				// This is only possible if a user explicitely requests this combination. Let them, with a warning.
+				// They need to use dlv at version 'v1.7.3-0.20211026171155-b48ceec161d5' or later,
+				// but we have no way of detectng that with an external server.
+				this.showWarning(
+					'ignoreDlvDAPInRemoteModeWarning',
+					"'remote' mode with 'dlv-dap' debugAdapter must connect to an external `dlv --headless` server @ v1.7.3 or later. Older versions will fail with \"error layer=rpc rpc:invalid character 'C' looking for beginning of value\" logged to the terminal.\n"
+				);
+			} else if (debugConfiguration['port']) {
+				this.showWarning(
+					'ignorePortUsedInDlvDapWarning',
+					"`port` with 'dlv-dap' debugAdapter connects to [an external `dlv dap` server](https://github.com/golang/vscode-go/blob/master/docs/debugging.md#running-debugee-externally) to launch a program or attach to a process. Remove 'host' and 'port' from your launch.json if you have not launched a 'dlv dap' server."
+				);
+			}
 		}
 
 		const debugAdapter = debugConfiguration['debugAdapter'] === 'dlv-dap' ? 'dlv-dap' : 'dlv';
@@ -199,7 +212,15 @@
 		}
 
 		// Reflect the defaults set through go.delveConfig setting.
-		const dlvProperties = ['showGlobalVariables', 'substitutePath', 'showLog', 'logOutput', 'dlvFlags'];
+		const dlvProperties = [
+			'showRegisters',
+			'showGlobalVariables',
+			'substitutePath',
+			'showLog',
+			'logOutput',
+			'dlvFlags',
+			'hideSystemGoroutines'
+		];
 		if (debugAdapter !== 'dlv-dap') {
 			dlvProperties.push('dlvLoadConfig');
 		}
@@ -254,7 +275,7 @@
 		}
 		debugConfiguration['dlvToolPath'] = dlvToolPath;
 
-		if (debugAdapter === 'dlv-dap' && !dlvDAPVersionCurrent) {
+		if (debugAdapter === 'dlv-dap' && !dlvDAPVersionChecked) {
 			const tool = getToolAtVersion('dlv-dap');
 			if (await shouldUpdateTool(tool, dlvToolPath)) {
 				// If the user has opted in to automatic tool updates, we can update
@@ -265,13 +286,13 @@
 					const toolVersion = { ...tool, version: tool.latestVersion }; // ToolWithVersion
 					await installTools([toolVersion], goVersion, true);
 				} else {
-					// If we are prompting the user to update, we do not want to continue
-					// with this debug session.
-					promptForUpdatingTool(tool.name);
-					return;
+					await promptForUpdatingTool(tool.name);
 				}
+				// installTools could've failed (e.g. no network access) or the user decliend to install dlv-dap
+				// in promptForUpdatingTool. If dlv-dap doesn't exist or dlv-dap is too old to have MVP features,
+				// the failure will be visible to users when launching the dlv-dap process (crash or error message).
 			}
-			dlvDAPVersionCurrent = true;
+			dlvDAPVersionChecked = true;
 		}
 
 		if (debugConfiguration['mode'] === 'auto') {
diff --git a/src/goDebugFactory.ts b/src/goDebugFactory.ts
index b58f665..4ab4fb7 100644
--- a/src/goDebugFactory.ts
+++ b/src/goDebugFactory.ts
@@ -38,11 +38,13 @@
 	private async createDebugAdapterDescriptorDlvDap(
 		configuration: vscode.DebugConfiguration
 	): Promise<vscode.ProviderResult<vscode.DebugAdapterDescriptor>> {
-		if (configuration.port) {
-			return new vscode.DebugAdapterServer(configuration.port, configuration.host ?? '127.0.0.1');
-		}
 		const logger = new TimestampedLogger(configuration.trace, this.outputChannel);
-		logger.debug(`Config: ${JSON.stringify(configuration)}`);
+		logger.debug(`Config: ${JSON.stringify(configuration)}\n`);
+		if (configuration.port) {
+			const host = configuration.host ?? '127.0.0.1';
+			logger.info(`Connecting to DAP server at ${host}:${configuration.port}\n`);
+			return new vscode.DebugAdapterServer(configuration.port, host);
+		}
 		const d = new DelveDAPOutputAdapter(configuration, logger);
 		return new vscode.DebugAdapterInlineImplementation(d);
 	}
@@ -57,13 +59,33 @@
 			return null;
 		}
 		const logger = new TimestampedLogger(session.configuration?.trace || 'off', this.outputChannel);
+		let requestsSent = 0;
+		let responsesReceived = 0;
 		return {
 			onWillStartSession: () =>
 				logger.debug(`session ${session.id} will start with ${JSON.stringify(session.configuration)}\n`),
-			onWillReceiveMessage: (message: any) => logger.trace(`client -> ${JSON.stringify(message)}\n`),
-			onDidSendMessage: (message: any) => logger.trace(`client  <- ${JSON.stringify(message)}\n`),
+			onWillReceiveMessage: (message: any) => {
+				logger.trace(`client -> ${JSON.stringify(message)}\n`);
+				requestsSent++;
+			},
+			onDidSendMessage: (message: any) => {
+				logger.trace(`client  <- ${JSON.stringify(message)}\n`);
+				responsesReceived++;
+			},
 			onError: (error: Error) => logger.error(`error: ${error}\n`),
-			onWillStopSession: () => logger.debug(`session ${session.id} will stop\n`),
+			onWillStopSession: () => {
+				if (
+					session.configuration.debugAdapter === 'dlv-dap' &&
+					session.configuration.mode === 'remote' &&
+					requestsSent > 0 &&
+					responsesReceived === 0 // happens when the rpc server doesn't understand DAP
+				) {
+					logger.warn(
+						"'remote' mode with 'dlv-dap' debugAdapter must connect to an external headless server started with dlv @ v1.7.3 or later.\n"
+					);
+				}
+				logger.debug(`session ${session.id} will stop\n`);
+			},
 			onExit: (code: number | undefined, signal: string | undefined) =>
 				logger.info(`debug adapter exited: (code: ${code}, signal: ${signal})\n`)
 		};
@@ -277,7 +299,7 @@
 
 	private async startAndConnectToServer() {
 		try {
-			const { port, host, dlvDapServer } = await startDapServer(
+			const { dlvDapServer, socket } = await startDapServer(
 				this.configuration,
 				(msg) => this.outputEvent('stdout', msg),
 				(msg) => this.outputEvent('stderr', msg),
@@ -290,21 +312,8 @@
 					this.logger?.info(msg);
 				}
 			);
-			const socket = await new Promise<net.Socket>((resolve, reject) => {
-				// eslint-disable-next-line prefer-const
-				let timer: NodeJS.Timeout;
-				const s = net.createConnection(port, host, () => {
-					clearTimeout(timer);
-					resolve(s);
-				});
-				timer = setTimeout(() => {
-					reject('connection timeout');
-					s?.destroy();
-				}, 1000);
-			});
 
 			this.dlvDapServer = dlvDapServer;
-			this.port = port;
 			this.socket = socket;
 			this.start(this.socket, this.socket);
 		} catch (err) {
@@ -324,17 +333,30 @@
 	log: (msg: string) => void,
 	logErr: (msg: string) => void,
 	logConsole: (msg: string) => void
-): Promise<{ port: number; host: string; dlvDapServer?: ChildProcessWithoutNullStreams }> {
+): Promise<{ dlvDapServer?: ChildProcessWithoutNullStreams; socket: net.Socket }> {
 	const host = configuration.host || '127.0.0.1';
+	const port = configuration.port || (await getPort());
 
-	if (configuration.port) {
-		// If a port has been specified, assume there is an already
-		// running dap server to connect to.
-		return { port: configuration.port, host };
-	}
-	const port = await getPort();
-	const dlvDapServer = await spawnDlvDapServerProcess(configuration, host, port, log, logErr, logConsole);
-	return { dlvDapServer, port, host };
+	// If a port has been specified, assume there is an already
+	// running dap server to connect to. Otherwise, we start the dlv dap server.
+	const dlvDapServer = configuration.port
+		? undefined
+		: await spawnDlvDapServerProcess(configuration, host, port, log, logErr, logConsole);
+
+	const socket = await new Promise<net.Socket>((resolve, reject) => {
+		// eslint-disable-next-line prefer-const
+		let timer: NodeJS.Timeout;
+		const s = net.createConnection(port, host, () => {
+			clearTimeout(timer);
+			resolve(s);
+		});
+		timer = setTimeout(() => {
+			reject('connection timeout');
+			s?.destroy();
+		}, 1000);
+	});
+
+	return { dlvDapServer, socket };
 }
 
 function spawnDlvDapServerProcess(
diff --git a/src/goSurvey.ts b/src/goSurvey.ts
index 901a9ee..8e517c1 100644
--- a/src/goSurvey.ts
+++ b/src/goSurvey.ts
@@ -121,9 +121,7 @@
 	// the user.
 	// Probability is set based on the # of responses received, and will be
 	// decreased if we begin receiving > 200 responses/month.
-	// Doubled the probability for survey v2 experiment.
-	// TODO(hyangah): switch back to 0.03.
-	const probability = 0.03 * 2;
+	const probability = 0.06;
 	cfg.promptThisMonth = Math.random() < probability;
 	if (cfg.promptThisMonth) {
 		// end is the last day of the month, day is the random day of the
@@ -165,10 +163,7 @@
 				cfg.prompt = true;
 				const goplsEnabled = latestConfig.enabled;
 				const usersGoplsVersion = await getLocalGoplsVersion(latestConfig);
-				const surveyURL =
-					Math.random() < 0.5
-						? `https://google.qualtrics.com/jfe/form/SV_ekAdHVcVcvKUojX?usingGopls=${goplsEnabled}&gopls=${usersGoplsVersion}&extid=${extensionId}` // v1
-						: `https://google.qualtrics.com/jfe/form/SV_8kbsnNINPIQ2QGq?usingGopls=${goplsEnabled}&gopls=${usersGoplsVersion}&extid=${extensionId}`; // v2
+				const surveyURL = `https://google.qualtrics.com/jfe/form/SV_agUVNbrDS0Cak2W?usingGopls=${goplsEnabled}&gopls=${usersGoplsVersion}&extid=${extensionId}`;
 				await vscode.env.openExternal(vscode.Uri.parse(surveyURL));
 			}
 			break;
diff --git a/src/goTools.ts b/src/goTools.ts
index d6eba5a..a14420d 100644
--- a/src/goTools.ts
+++ b/src/goTools.ts
@@ -208,7 +208,11 @@
 	goConfig: { [key: string]: any },
 	goplsConfig: { [key: string]: any }
 ): boolean {
-	if (goConfig['useLanguageServer'] !== true || goplsConfig['ui.diagnostic.staticcheck'] !== true) {
+	if (
+		goConfig['useLanguageServer'] !== true ||
+		goplsConfig['ui.diagnostic.staticcheck'] === false ||
+		(goplsConfig['ui.diagnostic.staticcheck'] === undefined && goplsConfig['staticcheck'] !== true)
+	) {
 		return false;
 	}
 	const features = goConfig['languageServerExperimentalFeatures'];
diff --git a/src/goToolsInformation.ts b/src/goToolsInformation.ts
index f7b621f..aae0d5d 100644
--- a/src/goToolsInformation.ts
+++ b/src/goToolsInformation.ts
@@ -117,7 +117,8 @@
 		modulePath: 'mvdan.cc/gofumpt',
 		replacedByGopls: true,
 		isImportant: false,
-		description: 'Formatter'
+		description: 'Formatter',
+		defaultVersion: 'v0.1.1'
 	},
 	'gofumpt': {
 		name: 'gofumpt',
@@ -223,10 +224,10 @@
 		replacedByGopls: false,
 		isImportant: true,
 		description: 'Go debugger & debug adapter (Delve DAP)',
-		defaultVersion: 'master', // Always build from the master.
+		defaultVersion: '2f13672765fe', // pinned version
 		minimumGoVersion: semver.coerce('1.12'), // dlv requires 1.12+ for build
-		latestVersion: semver.parse('v1.7.1'),
-		latestVersionTimestamp: moment('2021-08-18', 'YYYY-MM-DD')
+		latestVersion: semver.parse('v1.7.3-0.20211026171155-b48ceec161d5'),
+		latestVersionTimestamp: moment('2021-10-26', 'YYYY-MM-DD')
 	},
 	'fillstruct': {
 		name: 'fillstruct',
diff --git a/src/testUtils.ts b/src/testUtils.ts
index 3d4c1e7..3dc4e45 100644
--- a/src/testUtils.ts
+++ b/src/testUtils.ts
@@ -40,7 +40,7 @@
 const testFuncRegex = /^Test$|^Test\P{Ll}.*|^Example$|^Example\P{Ll}.*/u;
 const testMethodRegex = /^\(([^)]+)\)\.(Test|Test\P{Ll}.*)$/u;
 const benchmarkRegex = /^Benchmark$|^Benchmark\P{Ll}.*/u;
-
+const fuzzFuncRegx = /^Fuzz$|^Fuzz\P{Ll}.*/u;
 /**
  * Input to goTest.
  */
@@ -158,7 +158,7 @@
 	return children.filter(
 		(sym) =>
 			sym.kind === vscode.SymbolKind.Function &&
-			(testFuncRegex.test(sym.name) || (testify && testMethodRegex.test(sym.name)))
+			(testFuncRegex.test(sym.name) || fuzzFuncRegx.test(sym.name) || (testify && testMethodRegex.test(sym.name)))
 	);
 }
 
diff --git a/test/gopls/configuration.test.ts b/test/gopls/configuration.test.ts
index 918a3d5..06859b7 100644
--- a/test/gopls/configuration.test.ts
+++ b/test/gopls/configuration.test.ts
@@ -4,7 +4,7 @@
  * Licensed under the MIT License. See License.txt in the project root for license information.
  *--------------------------------------------------------*/
 
-import * as assert from 'assert';
+import assert from 'assert';
 import { getGoplsConfig } from '../../src/config';
 import * as lsp from '../../src/goLanguageServer';
 
diff --git a/test/gopls/extension.test.ts b/test/gopls/extension.test.ts
index a0650b7..9a09f5a 100644
--- a/test/gopls/extension.test.ts
+++ b/test/gopls/extension.test.ts
@@ -3,7 +3,7 @@
  * Copyright (C) Microsoft Corporation. All rights reserved.
  * Licensed under the MIT License. See LICENSE in the project root for license information.
  *--------------------------------------------------------*/
-import * as assert from 'assert';
+import assert from 'assert';
 import { EventEmitter } from 'events';
 import * as path from 'path';
 import * as vscode from 'vscode';
diff --git a/test/gopls/index.ts b/test/gopls/index.ts
index 7d7be4a..4e5cf07 100644
--- a/test/gopls/index.ts
+++ b/test/gopls/index.ts
@@ -4,8 +4,8 @@
  * Copyright (C) Microsoft Corporation. All rights reserved.
  * Licensed under the MIT License. See LICENSE in the project root for license information.
  *--------------------------------------------------------*/
-import * as glob from 'glob';
-import * as Mocha from 'mocha';
+import glob from 'glob';
+import Mocha from 'mocha';
 import * as path from 'path';
 export function run(): Promise<void> {
 	// Create the mocha test
diff --git a/test/gopls/report.test.ts b/test/gopls/report.test.ts
index e378264..8653b03 100644
--- a/test/gopls/report.test.ts
+++ b/test/gopls/report.test.ts
@@ -3,7 +3,7 @@
  * Licensed under the MIT License. See LICENSE in the project root for license information.
  *--------------------------------------------------------*/
 
-import * as assert from 'assert';
+import assert from 'assert';
 import { sanitizeGoplsTrace } from '../../src/goLanguageServer';
 
 suite('gopls issue report tests', () => {
diff --git a/test/gopls/survey.test.ts b/test/gopls/survey.test.ts
index 652bb37..3782b24 100644
--- a/test/gopls/survey.test.ts
+++ b/test/gopls/survey.test.ts
@@ -3,7 +3,7 @@
  * Licensed under the MIT License. See License.txt in the project root for license information.
  *--------------------------------------------------------*/
 
-import * as assert from 'assert';
+import assert from 'assert';
 import sinon = require('sinon');
 import vscode = require('vscode');
 import goLanguageServer = require('../../src/goLanguageServer');
diff --git a/test/gopls/update.test.ts b/test/gopls/update.test.ts
index d27e97c..bb36605 100644
--- a/test/gopls/update.test.ts
+++ b/test/gopls/update.test.ts
@@ -6,7 +6,7 @@
  * Licensed under the MIT License. See License.txt in the project root for license information.
  *--------------------------------------------------------*/
 
-import * as assert from 'assert';
+import assert from 'assert';
 import * as vscode from 'vscode';
 import { getGoConfig } from '../../src/config';
 import * as lsp from '../../src/goLanguageServer';
diff --git a/test/integration/codelens.test.ts b/test/integration/codelens.test.ts
index 67b4f5c..10ecaab 100644
--- a/test/integration/codelens.test.ts
+++ b/test/integration/codelens.test.ts
@@ -5,7 +5,7 @@
 
 'use strict';
 
-import * as assert from 'assert';
+import assert from 'assert';
 import fs = require('fs-extra');
 import path = require('path');
 import sinon = require('sinon');
@@ -14,7 +14,7 @@
 import { updateGoVarsFromConfig } from '../../src/goInstallTools';
 import { GoRunTestCodeLensProvider } from '../../src/goRunTestCodelens';
 import { subTestAtCursor } from '../../src/goTest';
-import { getCurrentGoPath } from '../../src/util';
+import { getCurrentGoPath, getGoVersion } from '../../src/util';
 
 suite('Code lenses for testing and benchmarking', function () {
 	this.timeout(20000);
@@ -164,4 +164,24 @@
 			'Test함수'
 		]);
 	});
+
+	test('Test codelenses include valid fuzz function names', async function () {
+		if ((await getGoVersion()).lt('1.18')) {
+			this.skip();
+		}
+		const uri = vscode.Uri.file(path.join(fixturePath, 'codelens_go118_test.go'));
+		const testDocument = await vscode.workspace.openTextDocument(uri);
+		const codeLenses = await codeLensProvider.provideCodeLenses(testDocument, cancellationTokenSource.token);
+		assert.equal(codeLenses.length, 8, JSON.stringify(codeLenses, null, 2));
+		const found = [] as string[];
+		for (let i = 0; i < codeLenses.length; i++) {
+			const lens = codeLenses[i];
+			if (lens.command.command === 'go.test.cursor') {
+				found.push(lens.command.arguments[0].functionName);
+			}
+		}
+		found.sort();
+		// Results should match `go test -list`.
+		assert.deepStrictEqual(found, ['Fuzz', 'FuzzFunc', 'TestGo118']);
+	});
 });
diff --git a/test/integration/coverage.test.ts b/test/integration/coverage.test.ts
index f49384e..42c598f 100644
--- a/test/integration/coverage.test.ts
+++ b/test/integration/coverage.test.ts
@@ -6,7 +6,7 @@
 
 'use strict';
 
-import * as assert from 'assert';
+import assert from 'assert';
 import { applyCodeCoverageToAllEditors, coverageFilesForTest, initForTest } from '../../src/goCover';
 import { updateGoVarsFromConfig } from '../../src/goInstallTools';
 import fs = require('fs-extra');
diff --git a/test/integration/extension.test.ts b/test/integration/extension.test.ts
index c8d5bc1..c3b703e 100644
--- a/test/integration/extension.test.ts
+++ b/test/integration/extension.test.ts
@@ -7,7 +7,7 @@
  * Licensed under the MIT License. See LICENSE in the project root for license information.
  *--------------------------------------------------------*/
 
-import * as assert from 'assert';
+import assert from 'assert';
 import * as fs from 'fs-extra';
 import * as path from 'path';
 import * as sinon from 'sinon';
diff --git a/test/integration/goDebug.test.ts b/test/integration/goDebug.test.ts
index aa66322..88bf797 100644
--- a/test/integration/goDebug.test.ts
+++ b/test/integration/goDebug.test.ts
@@ -3,7 +3,7 @@
 /* eslint-disable node/no-unsupported-features/node-builtins */
 /* eslint-disable no-async-promise-executor */
 /* eslint-disable node/no-unpublished-import */
-import * as assert from 'assert';
+import assert from 'assert';
 import * as cp from 'child_process';
 import * as fs from 'fs';
 import * as readline from 'readline';
@@ -28,7 +28,7 @@
 import * as extConfig from '../../src/config';
 import { GoDebugConfigurationProvider, parseDebugProgramArgSync } from '../../src/goDebugConfiguration';
 import { getBinPath, rmdirRecursive } from '../../src/util';
-import { killProcessTree } from '../../src/utils/processUtils';
+import { killProcessTree, killProcess } from '../../src/utils/processUtils';
 import getPort = require('get-port');
 import util = require('util');
 import { TimestampedLogger } from '../../src/goLogging';
@@ -994,6 +994,7 @@
 		let childProcess: cp.ChildProcess;
 		let server: number;
 		let debugConfig: DebugConfiguration;
+
 		setup(async () => {
 			server = await getPort();
 			remoteAttachConfig.port = await getPort();
@@ -1036,6 +1037,20 @@
 
 			await setUpRemoteAttach(debugConfig);
 		});
+
+		test('connection to remote is terminated when external dlv process exits', async function () {
+			if (isDlvDap && dlvDapSkipsEnabled) {
+				this.skip(); // not working in dlv-dap.
+			}
+
+			const childProcess = await setUpRemoteProgram(remoteAttachConfig.port, server, true, false);
+
+			await setUpRemoteAttach(remoteAttachConfig);
+
+			killProcess(childProcess);
+
+			await dc.waitForEvent('terminated');
+		});
 	});
 
 	// The file paths returned from delve use '/' not the native path
diff --git a/test/integration/goDebugConfiguration.test.ts b/test/integration/goDebugConfiguration.test.ts
index d874546..5f63b8c 100644
--- a/test/integration/goDebugConfiguration.test.ts
+++ b/test/integration/goDebugConfiguration.test.ts
@@ -281,6 +281,8 @@
 					},
 					apiVersion: 1,
 					showGlobalVariables: true,
+					showRegisters: true,
+					hideSystemGoroutines: true,
 					debugAdapter: 'dlv-dap',
 					substitutePath: [{ from: 'hello', to: 'goodbye' }],
 					showLog: true,
@@ -301,6 +303,8 @@
 			const result = await debugConfigProvider.resolveDebugConfiguration(undefined, cfg);
 			assert.strictEqual(result.apiVersion, 1);
 			assert.strictEqual(result.showGlobalVariables, true);
+			assert.strictEqual(result.showRegisters, true);
+			assert.strictEqual(result.hideSystemGoroutines, true);
 			assert.strictEqual(result.debugAdapter, 'dlv-dap');
 			assert.strictEqual(result.substitutePath.length, 1);
 			assert.strictEqual(result.substitutePath[0].from, 'hello');
@@ -329,6 +333,8 @@
 					},
 					apiVersion: 1,
 					showGlobalVariables: true,
+					showRegisters: true,
+					hideSystemGoroutines: true,
 					debugAdapter: 'dlv-dap',
 					substitutePath: [{ from: 'hello', to: 'goodbye' }]
 				}
@@ -342,6 +348,8 @@
 				mode: 'auto',
 				program: '${fileDirname}',
 				showGlobalVariables: false,
+				showRegisters: false,
+				hideSystemGoroutines: false,
 				apiVersion: 2,
 				dlvLoadConfig: {
 					followPointers: true,
@@ -358,6 +366,8 @@
 			const result = await debugConfigProvider.resolveDebugConfiguration(undefined, cfg);
 			assert.strictEqual(result.apiVersion, 2);
 			assert.strictEqual(result.showGlobalVariables, false);
+			assert.strictEqual(result.showRegisters, false);
+			assert.strictEqual(result.hideSystemGoroutines, false);
 			assert.strictEqual(result.debugAdapter, 'legacy');
 			assert.strictEqual(result.substitutePath.length, 0);
 			assert.strictEqual(result.showLog, undefined);
@@ -435,7 +445,7 @@
 				assert.strictEqual(got.removed, tc.want.removed, `removed for ${tc.input} does not match expected`);
 			});
 		});
-		test('remove user set -gcflags in buildFlags', () => {
+		test('remove user set -gcflags in buildFlags', async () => {
 			const config = {
 				name: 'Launch',
 				type: 'go',
@@ -446,10 +456,10 @@
 				buildFlags: '-race -gcflags=-l -mod=mod'
 			};
 
-			debugConfigProvider.resolveDebugConfiguration(undefined, config);
+			await debugConfigProvider.resolveDebugConfiguration(undefined, config);
 			assert.strictEqual(config.buildFlags, '-race -mod=mod');
 		});
-		test('remove user set -gcflags in GOFLAGS', () => {
+		test('remove user set -gcflags in GOFLAGS', async () => {
 			const config = {
 				name: 'Launch',
 				type: 'go',
@@ -459,7 +469,7 @@
 				env: { GOFLAGS: '-race -gcflags=-l -mod=mod' }
 			};
 
-			debugConfigProvider.resolveDebugConfiguration(undefined, config);
+			await debugConfigProvider.resolveDebugConfiguration(undefined, config);
 
 			assert.strictEqual(config.env.GOFLAGS, '-race -mod=mod');
 		});
@@ -468,7 +478,7 @@
 
 suite('Debug Configuration Resolve Paths', () => {
 	const debugConfigProvider = new GoDebugConfigurationProvider();
-	test('resolve ~ in cwd', () => {
+	test('resolve ~ in cwd', async () => {
 		const config = {
 			name: 'Launch',
 			type: 'go',
@@ -478,11 +488,11 @@
 			cwd: '~/main.go'
 		};
 
-		debugConfigProvider.resolveDebugConfiguration(undefined, config);
+		await debugConfigProvider.resolveDebugConfiguration(undefined, config);
 		assert.notStrictEqual(config.cwd, '~/main.go');
 	});
 
-	test('do not resolve workspaceFolder or fileDirname', () => {
+	test('do not resolve workspaceFolder or fileDirname', async () => {
 		const config = {
 			name: 'Launch',
 			type: 'go',
@@ -492,7 +502,7 @@
 			cwd: '${workspaceFolder}'
 		};
 
-		debugConfigProvider.resolveDebugConfiguration(undefined, config);
+		await debugConfigProvider.resolveDebugConfiguration(undefined, config);
 
 		assert.strictEqual(config.cwd, '${workspaceFolder}');
 		assert.strictEqual(config.program, '${fileDirname}');
@@ -832,7 +842,7 @@
 
 suite('Debug Configuration Auto Mode', () => {
 	const debugConfigProvider = new GoDebugConfigurationProvider();
-	test('resolve auto to debug with non-test file', () => {
+	test('resolve auto to debug with non-test file', async () => {
 		const config = {
 			name: 'Launch',
 			type: 'go',
@@ -841,12 +851,12 @@
 			program: '/path/to/main.go'
 		};
 
-		debugConfigProvider.resolveDebugConfiguration(undefined, config);
+		await debugConfigProvider.resolveDebugConfiguration(undefined, config);
 		assert.strictEqual(config.mode, 'debug');
 		assert.strictEqual(config.program, '/path/to/main.go');
 	});
 
-	test('resolve auto to debug with test file', () => {
+	test('resolve auto to debug with test file', async () => {
 		const config = {
 			name: 'Launch',
 			type: 'go',
@@ -855,7 +865,7 @@
 			program: '/path/to/main_test.go'
 		};
 
-		debugConfigProvider.resolveDebugConfiguration(undefined, config);
+		await debugConfigProvider.resolveDebugConfiguration(undefined, config);
 		assert.strictEqual(config.mode, 'test');
 		assert.strictEqual(config.program, '/path/to');
 	});
@@ -863,7 +873,7 @@
 
 suite('Debug Configuration Default DebugAdapter', () => {
 	const debugConfigProvider = new GoDebugConfigurationProvider();
-	test("default debugAdapter should be 'dlv-dap'", () => {
+	test("default debugAdapter should be 'dlv-dap'", async () => {
 		const config = {
 			name: 'Launch',
 			type: 'go',
@@ -872,12 +882,12 @@
 			program: '/path/to/main.go'
 		};
 
-		debugConfigProvider.resolveDebugConfiguration(undefined, config);
+		await debugConfigProvider.resolveDebugConfiguration(undefined, config);
 		const resolvedConfig = config as any;
 		assert.strictEqual(resolvedConfig['debugAdapter'], 'dlv-dap');
 	});
 
-	test("default debugAdapter for remote mode should be always 'legacy'", () => {
+	test("default debugAdapter for remote mode should be always 'legacy'", async () => {
 		const config = {
 			name: 'Attach',
 			type: 'go',
@@ -887,13 +897,13 @@
 			cwd: '/path'
 		};
 
-		const want = 'legacy'; // remote mode works only with legacy mode.
-		debugConfigProvider.resolveDebugConfiguration(undefined, config);
+		const want = 'legacy'; // Remote mode defaults to legacy mode.
+		await debugConfigProvider.resolveDebugConfiguration(undefined, config);
 		const resolvedConfig = config as any;
 		assert.strictEqual(resolvedConfig['debugAdapter'], want);
 	});
 
-	test('debugAdapter=dlv-dap should be ignored for remote mode', () => {
+	test('debugAdapter=dlv-dap is allowed with remote mode', async () => {
 		const config = {
 			name: 'Attach',
 			type: 'go',
@@ -904,9 +914,51 @@
 			cwd: '/path'
 		};
 
-		const want = 'legacy'; // remote mode works only with legacy mode.
-		debugConfigProvider.resolveDebugConfiguration(undefined, config);
+		const want = 'dlv-dap'; // If requested, dlv-dap is preserved.
+		await debugConfigProvider.resolveDebugConfiguration(undefined, config);
 		const resolvedConfig = config as any;
 		assert.strictEqual(resolvedConfig['debugAdapter'], want);
 	});
 });
+
+suite('Debug Configuration Infers Default Mode Property', () => {
+	const debugConfigProvider = new GoDebugConfigurationProvider();
+	test("default mode for launch requests and test Go programs should be 'test'", () => {
+		const config = {
+			name: 'Launch',
+			type: 'go',
+			request: 'launch',
+			program: '/path/to/main_test.go'
+		};
+
+		debugConfigProvider.resolveDebugConfiguration(undefined, config);
+		const resolvedConfig = config as any;
+		assert.strictEqual(resolvedConfig['mode'], 'test');
+	});
+
+	test("default mode for launch requests and non-test Go programs should be 'debug'", () => {
+		const config = {
+			name: 'Launch',
+			type: 'go',
+			request: 'launch',
+			program: '/path/to/main.go'
+		};
+
+		debugConfigProvider.resolveDebugConfiguration(undefined, config);
+		const resolvedConfig = config as any;
+		assert.strictEqual(resolvedConfig['mode'], 'debug');
+	});
+
+	test("default mode for attach requests should be 'local'", () => {
+		const config = {
+			name: 'Attach',
+			type: 'go',
+			request: 'attach',
+			program: '/path/to/main.go'
+		};
+
+		debugConfigProvider.resolveDebugConfiguration(undefined, config);
+		const resolvedConfig = config as any;
+		assert.strictEqual(resolvedConfig['mode'], 'local');
+	});
+});
diff --git a/test/integration/goTest.run.test.ts b/test/integration/goTest.run.test.ts
index f8d8ddf..23d6833 100644
--- a/test/integration/goTest.run.test.ts
+++ b/test/integration/goTest.run.test.ts
@@ -13,7 +13,7 @@
 
 	let testExplorer: GoTestExplorer;
 
-	suite('Profile', () => {
+	suite.skip('Profile', () => {
 		const sandbox = sinon.createSandbox();
 		const ctx = MockExtensionContext.new();
 
diff --git a/test/integration/goversion.test.ts b/test/integration/goversion.test.ts
index a199e1d..6688277 100644
--- a/test/integration/goversion.test.ts
+++ b/test/integration/goversion.test.ts
@@ -6,7 +6,7 @@
  * Licensed under the MIT License. See LICENSE in the project root for license information.
  *--------------------------------------------------------*/
 
-import * as assert from 'assert';
+import assert from 'assert';
 import { describe, it } from 'mocha';
 import * as sinon from 'sinon';
 import * as vscode from 'vscode';
diff --git a/test/integration/index.ts b/test/integration/index.ts
index 9f4fb2a..e0b0433 100644
--- a/test/integration/index.ts
+++ b/test/integration/index.ts
@@ -4,8 +4,8 @@
  * Copyright (C) Microsoft Corporation. All rights reserved.
  * Licensed under the MIT License. See LICENSE in the project root for license information.
  *--------------------------------------------------------*/
-import * as glob from 'glob';
-import * as Mocha from 'mocha';
+import glob from 'glob';
+import Mocha from 'mocha';
 import * as path from 'path';
 export function run(): Promise<void> {
 	const options: Mocha.MochaOptions = {
diff --git a/test/integration/install.test.ts b/test/integration/install.test.ts
index 8d514e7..3602022 100644
--- a/test/integration/install.test.ts
+++ b/test/integration/install.test.ts
@@ -5,7 +5,7 @@
  *--------------------------------------------------------*/
 
 import AdmZip = require('adm-zip');
-import * as assert from 'assert';
+import assert from 'assert';
 import * as config from '../../src/config';
 import { inspectGoToolVersion, installTools } from '../../src/goInstallTools';
 import { getConfiguredTools, getTool, getToolAtVersion } from '../../src/goTools';
@@ -160,7 +160,7 @@
 				{ name: 'guru', versions: ['v1.0.0'], wantVersion: 'v1.0.0' },
 				{
 					name: 'dlv-dap',
-					versions: ['v1.0.0', 'master'],
+					versions: ['v1.0.0', getTool('dlv-dap').defaultVersion!],
 					wantVersion: 'v' + getTool('dlv-dap').latestVersion!.toString()
 				}
 			],
@@ -175,7 +175,7 @@
 				{ name: 'guru', versions: ['v1.0.0'], wantVersion: 'v1.0.0' },
 				{
 					name: 'dlv-dap',
-					versions: ['v1.0.0', 'master'],
+					versions: ['v1.0.0', getTool('dlv-dap').defaultVersion!],
 					wantVersion: 'v' + getTool('dlv-dap').latestVersion!.toString()
 				}
 			],
diff --git a/test/integration/pickProcess.test.ts b/test/integration/pickProcess.test.ts
index 1172ba7..7bba8ee 100644
--- a/test/integration/pickProcess.test.ts
+++ b/test/integration/pickProcess.test.ts
@@ -3,7 +3,7 @@
  * Licensed under the MIT License. See LICENSE in the project root for license information.
  *--------------------------------------------------------*/
 
-import * as assert from 'assert';
+import assert from 'assert';
 import { AttachItem, compareByProcessId, mergeExecutableAttachItem, parseGoVersionOutput } from '../../src/pickProcess';
 import { parseLsofProcesses } from '../../src/utils/lsofProcessParser';
 
diff --git a/test/integration/stateUtils.test.ts b/test/integration/stateUtils.test.ts
index be93197..32a78af 100644
--- a/test/integration/stateUtils.test.ts
+++ b/test/integration/stateUtils.test.ts
@@ -4,7 +4,7 @@
  * Licensed under the MIT License. See LICENSE in the project root for license information.
  *--------------------------------------------------------*/
 
-import * as assert from 'assert';
+import assert from 'assert';
 import * as vscode from 'vscode';
 import {
 	getMementoKeys,
diff --git a/test/integration/statusbar.test.ts b/test/integration/statusbar.test.ts
index b8dcf5f..b01e7db 100644
--- a/test/integration/statusbar.test.ts
+++ b/test/integration/statusbar.test.ts
@@ -6,7 +6,7 @@
  * Licensed under the MIT License. See LICENSE in the project root for license information.
  *--------------------------------------------------------*/
 
-import * as assert from 'assert';
+import assert from 'assert';
 import * as fs from 'fs-extra';
 import { describe, it } from 'mocha';
 import * as os from 'os';
diff --git a/test/integration/test.test.ts b/test/integration/test.test.ts
index 0896ea0..3dd87f5 100644
--- a/test/integration/test.test.ts
+++ b/test/integration/test.test.ts
@@ -6,7 +6,7 @@
 
 'use strict';
 
-import * as assert from 'assert';
+import assert from 'assert';
 import { getGoConfig } from '../../src/config';
 import { computeTestCommand, getTestFlags, goTest } from '../../src/testUtils';
 import { rmdirRecursive } from '../../src/util';
diff --git a/test/integration/utils.test.ts b/test/integration/utils.test.ts
index b9102b6..c13a939 100644
--- a/test/integration/utils.test.ts
+++ b/test/integration/utils.test.ts
@@ -5,7 +5,7 @@
  * Licensed under the MIT License. See LICENSE in the project root for license information.
  *--------------------------------------------------------*/
 
-import * as assert from 'assert';
+import assert from 'assert';
 import * as vscode from 'vscode';
 import { GoVersion, guessPackageNameFromFile, removeDuplicateDiagnostics, substituteEnv } from '../../src/util';
 import path = require('path');
diff --git a/test/integration/welcome.test.ts b/test/integration/welcome.test.ts
index 48aff48..2834ac3 100644
--- a/test/integration/welcome.test.ts
+++ b/test/integration/welcome.test.ts
@@ -4,7 +4,7 @@
  *--------------------------------------------------------*/
 
 import vscode = require('vscode');
-import * as assert from 'assert';
+import assert from 'assert';
 import { shouldShowGoWelcomePage } from '../../src/goMain';
 import { extensionId } from '../../src/const';
 import { WelcomePanel } from '../../src/welcome';
diff --git a/test/testdata/codelens/codelens_go118_test.go b/test/testdata/codelens/codelens_go118_test.go
new file mode 100644
index 0000000..bd76567
--- /dev/null
+++ b/test/testdata/codelens/codelens_go118_test.go
@@ -0,0 +1,17 @@
+//go:build go1.18
+// +build go1.18
+
+package main
+
+import (
+	"testing"
+)
+
+func FuzzFunc(f *testing.F) {
+}
+
+func Fuzz(f *testing.F) {
+}
+
+func TestGo118(t *testing.T) {
+}
diff --git a/test/unit/NNDict.test.ts b/test/unit/NNDict.test.ts
index 1ee5351..7d68841 100644
--- a/test/unit/NNDict.test.ts
+++ b/test/unit/NNDict.test.ts
@@ -3,7 +3,7 @@
  * Licensed under the MIT License. See LICENSE in the project root for license information.
  *--------------------------------------------------------*/
 
-import * as assert from 'assert';
+import assert from 'assert';
 import { NearestNeighborDict, Node } from '../../src/avlTree';
 
 suite('NearestNeighborDict Tests', () => {
diff --git a/test/unit/goDebug.test.ts b/test/unit/goDebug.test.ts
index e92072b..1ce6737 100644
--- a/test/unit/goDebug.test.ts
+++ b/test/unit/goDebug.test.ts
@@ -3,7 +3,7 @@
  * Licensed under the MIT License. See LICENSE in the project root for license information.
  *--------------------------------------------------------*/
 
-import * as assert from 'assert';
+import assert from 'assert';
 import { findPathSeparator, normalizeSeparators } from '../../src/debugAdapter/goDebug';
 
 suite('NormalizeSeparators Tests', () => {
diff --git a/test/unit/logger.test.ts b/test/unit/logger.test.ts
index 1cbc970..763bfaa 100644
--- a/test/unit/logger.test.ts
+++ b/test/unit/logger.test.ts
@@ -3,7 +3,7 @@
  * Licensed under the MIT License. See LICENSE in the project root for license information.
  *--------------------------------------------------------*/
 
-import * as assert from 'assert';
+import assert from 'assert';
 import sinon = require('sinon');
 import { Logger } from '../../src/goLogging';
 
diff --git a/test/unit/mutex.test.ts b/test/unit/mutex.test.ts
index 57818d1..b00258f 100644
--- a/test/unit/mutex.test.ts
+++ b/test/unit/mutex.test.ts
@@ -3,7 +3,7 @@
  * Licensed under the MIT License. See LICENSE in the project root for license information.
  *--------------------------------------------------------*/
 
-import * as assert from 'assert';
+import assert from 'assert';
 import { Mutex } from '../../src/utils/mutex';
 
 suite('Mutex Tests', () => {
diff --git a/tools/allTools.ts.in b/tools/allTools.ts.in
index 0c31e4d..e6377b8 100644
--- a/tools/allTools.ts.in
+++ b/tools/allTools.ts.in
@@ -115,7 +115,8 @@
 		modulePath: 'mvdan.cc/gofumpt',
 		replacedByGopls: true,
 		isImportant: false,
-		description: 'Formatter'
+		description: 'Formatter',
+		defaultVersion: 'v0.1.1'
 	},
 	'gofumpt': {
 		name: 'gofumpt',
@@ -221,7 +222,7 @@
 		replacedByGopls: false,
 		isImportant: true,
 		description: 'Go debugger & debug adapter (Delve DAP)',
-		defaultVersion: 'master', // Always build from the master.
+		defaultVersion: '%s', // pinned version
 		minimumGoVersion: semver.coerce('1.12'), // dlv requires 1.12+ for build
 		latestVersion: semver.parse('%s'),
 		latestVersionTimestamp: moment('%s', 'YYYY-MM-DD')
@@ -242,4 +243,4 @@
 		isImportant: false,
 		description: 'Extract to functions and variables'
 	}
-};
\ No newline at end of file
+};
diff --git a/tools/generate.go b/tools/generate.go
index 4f0948e..e3169d1 100644
--- a/tools/generate.go
+++ b/tools/generate.go
@@ -15,6 +15,7 @@
 import (
 	"bytes"
 	"encoding/json"
+	"errors"
 	"flag"
 	"fmt"
 	"io"
@@ -23,6 +24,7 @@
 	"os"
 	"os/exec"
 	"path/filepath"
+	"regexp"
 	"sort"
 	"strings"
 
@@ -235,6 +237,12 @@
 	if err != nil {
 		log.Fatal(err)
 	}
+	// Due to https://github.com/golang/vscode-go/issues/1682, we cannot use
+	// pseudo-version as the pinned version reliably.
+	dlvRevOrStable := dlvVersion.Version
+	if rev, err := pseudoVersionRev(dlvVersion.Version); err == nil { // pseudo-version
+		dlvRevOrStable = rev
+	}
 
 	// Check for the latest gopls version.
 	versions, err := listAllModuleVersions("golang.org/x/tools/gopls")
@@ -269,7 +277,7 @@
 	}
 
 	// TODO(suzmue): change input to json and avoid magic string printing.
-	toolsString := fmt.Sprintf(string(data), goplsVersion.Version, goplsVersion.Time[:len("YYYY-MM-DD")], goplsVersionPre.Version, goplsVersionPre.Time[:len("YYYY-MM-DD")], dlvVersion.Version, dlvVersion.Time[:len("YYYY-MM-DD")])
+	toolsString := fmt.Sprintf(string(data), goplsVersion.Version, goplsVersion.Time[:len("YYYY-MM-DD")], goplsVersionPre.Version, goplsVersionPre.Time[:len("YYYY-MM-DD")], dlvRevOrStable, dlvVersion.Version, dlvVersion.Time[:len("YYYY-MM-DD")])
 
 	// Write tools section.
 	b.WriteString(toolsString)
@@ -685,3 +693,19 @@
 	}
 	return b.String()
 }
+
+// pseudoVersionRev extracts the revision info if the given version is pseudo version.
+// We wanted to use golang.org/x/mod/module.PseudoVersionRev, but couldn't due to
+// an error in the CI. This is a workaround.
+//
+// It assumes the version string came from the proxy, so a valid, canonical version
+// string. Thus, the check for pseudoversion is not as robust as golang.org/x/mod/module
+// offers.
+func pseudoVersionRev(ver string) (rev string, _ error) {
+	var pseudoVersionRE = regexp.MustCompile(`^v[0-9]+\.(0\.0-|\d+\.\d+-([^+]*\.)?0\.)\d{14}-[A-Za-z0-9]+(\+[0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*)?$`)
+	if strings.Count(ver, "-") < 2 || !pseudoVersionRE.MatchString(ver) {
+		return "", errors.New("not a pseudo version")
+	}
+	j := strings.LastIndex(ver, "-")
+	return ver[j+1:], nil
+}
diff --git a/tools/installtools/main.go b/tools/installtools/main.go
new file mode 100644
index 0000000..99a2def
--- /dev/null
+++ b/tools/installtools/main.go
@@ -0,0 +1,146 @@
+// Binary installtools is a helper that installs Go tools extension tests depend on.
+package main
+
+import (
+	"fmt"
+	"os"
+	"os/exec"
+	"path"
+	"path/filepath"
+	"runtime"
+	"strings"
+)
+
+var tools = []struct {
+	path    string
+	version string
+	dest    string
+}{
+	// TODO: auto-generate based on allTools.ts.in.
+	{"golang.org/x/tools/gopls", "", ""},
+	{"github.com/acroca/go-symbols", "", ""},
+	{"github.com/cweill/gotests/gotests", "", ""},
+	{"github.com/davidrjenni/reftools/cmd/fillstruct", "", ""},
+	{"github.com/haya14busa/goplay/cmd/goplay", "", ""},
+	{"github.com/stamblerre/gocode", "", "gocode-gomod"},
+	{"github.com/mdempsky/gocode", "", ""},
+	{"github.com/ramya-rao-a/go-outline", "", ""},
+	{"github.com/rogpeppe/godef", "", ""},
+	{"github.com/sqs/goreturns", "", ""},
+	{"github.com/uudashr/gopkgs/v2/cmd/gopkgs", "", ""},
+	{"github.com/zmb3/gogetdoc", "", ""},
+	{"honnef.co/go/tools/cmd/staticcheck", "", ""},
+	{"golang.org/x/tools/cmd/gorename", "", ""},
+	{"github.com/go-delve/delve/cmd/dlv", "master", "dlv-dap"},
+	{"github.com/go-delve/delve/cmd/dlv", "", ""},
+}
+
+func main() {
+	ver, err := goVersion()
+	if err != nil {
+		exitf("failed to find go version: %v", err)
+	}
+	bin, err := goBin()
+	if err != nil {
+		exitf("failed to determine go tool installation directory: %v", err)
+	}
+	if ver < 1 {
+		exitf("unsupported go version: 1.%v", ver)
+	} else if ver < 16 {
+		err = installTools(bin, "get")
+	} else {
+		err = installTools(bin, "install")
+	}
+	if err != nil {
+		exitf("failed to install tools: %v", err)
+	}
+}
+
+func exitf(format string, args ...interface{}) {
+	fmt.Fprintf(os.Stderr, format, args...)
+	os.Exit(1)
+}
+
+// goVersion returns an integer N if go's version is 1.N.
+func goVersion() (int, error) {
+	cmd := exec.Command("go", "list", "-e", "-f", `{{context.ReleaseTags}}`, "--", "unsafe")
+	cmd.Env = append(os.Environ(), "GO111MODULE=off")
+	out, err := cmd.Output()
+	if err != nil {
+		return 0, fmt.Errorf("go list error: %v", err)
+	}
+	result := string(out)
+	if len(result) < 3 {
+		return 0, fmt.Errorf("bad ReleaseTagsOutput: %q", result)
+	}
+	// Split up "[go1.1 go1.15]"
+	tags := strings.Fields(result[1 : len(result)-2])
+	for i := len(tags) - 1; i >= 0; i-- {
+		var version int
+		if _, err := fmt.Sscanf(tags[i], "go1.%d", &version); err != nil {
+			continue
+		}
+		return version, nil
+	}
+	return 0, fmt.Errorf("no parseable ReleaseTags in %v", tags)
+}
+
+// goBin returns the directory where the go command will install binaries.
+func goBin() (string, error) {
+	if gobin := os.Getenv("GOBIN"); gobin != "" {
+		return gobin, nil
+	}
+	out, err := exec.Command("go", "env", "GOPATH").Output()
+	if err != nil {
+		return "", err
+	}
+	gopaths := filepath.SplitList(strings.TrimSpace(string(out)))
+	if len(gopaths) == 0 {
+		return "", fmt.Errorf("invalid GOPATH: %s", out)
+	}
+	return filepath.Join(gopaths[0], "bin"), nil
+}
+
+func installTools(binDir, installCmd string) error {
+	dir := ""
+	if installCmd == "get" { // run `go get` command from an empty directory.
+		dir = os.TempDir()
+	}
+	env := append(os.Environ(), "GO111MODULE=on")
+	for _, tool := range tools {
+		ver := tool.version
+		if ver == "" {
+			ver = "latest"
+		}
+		path := tool.path + "@" + ver
+		cmd := exec.Command("go", installCmd, path)
+		cmd.Env = env
+		cmd.Dir = dir
+		fmt.Println("go", installCmd, path)
+		if out, err := cmd.CombinedOutput(); err != nil {
+			return fmt.Errorf("installing %v: %s\n%v", path, out, err)
+		}
+		loc := filepath.Join(binDir, binName(tool.path))
+		if tool.dest != "" {
+			newLoc := filepath.Join(binDir, binName(tool.dest))
+			if err := os.Rename(loc, newLoc); err != nil {
+				return fmt.Errorf("copying %v to %v: %v", loc, newLoc, err)
+			}
+			loc = newLoc
+		}
+		fmt.Println("\tinstalled", loc)
+	}
+	return nil
+}
+
+func binName(toolPath string) string {
+	b := path.Base(toolPath)
+	if runtime.GOOS == "windows" {
+		return b + ".exe"
+	}
+	return b
+}
+
+func runWithGoInstall() error {
+	return nil
+}
diff --git a/tsconfig.json b/tsconfig.json
index df30337..1b9c156 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -3,9 +3,9 @@
 		"module": "commonjs",
 		"outDir": "out",
 		"sourceMap": true,
-		"target": "es6",
+		"target": "es2017",
 		"lib": [
-			"es2015"
+			"es2017"
 		],
 		//"strict": true,
 		"noImplicitAny": true,
@@ -13,6 +13,7 @@
 		"alwaysStrict": true,
 		"strictBindCallApply": true,
 		"strictFunctionTypes": true,
+		"esModuleInterop": true,
 		//"strictNullChecks": true,
 		//"strictPropertyInitialization": true,
 	},
diff --git a/typings/json-rpc2.d.ts b/typings/json-rpc2.d.ts
index 3bee3d0..8aa65c9 100644
--- a/typings/json-rpc2.d.ts
+++ b/typings/json-rpc2.d.ts
@@ -1,11 +1,14 @@
-declare module "json-rpc2" {
+declare module 'json-rpc2' {
 	export interface RPCConnection {
-		call<T>(command: string, args: any[], callback: (err: Error, result:T) => void): void;
+		call<T>(command: string, args: any[], callback: (err: Error, result: T) => void): void;
+		on(event: 'connect', cb: () => {}): this;
+		on(event: 'error', cb: (err: Error) => {}): this;
+		on(event: 'close', cb: (hadError: boolean) => {}): this;
+		on(event: string, cb: Function): this;
 	}
-	
+
 	export class Client {
 		static $create(port: number, addr: string): Client;
-		connectSocket(callback: (err: Error, conn: RPCConnection) => void): void;
-		on(handler: 'error', callback: (err: Error) => void): void;
+		connectSocket(): RPCConnection;
 	}
-}
\ No newline at end of file
+}