Skip to content

dap-debug does not launch the selected device in Flutter project #222

@odi-so

Description

@odi-so

Describe the bug
In Flutter project, dap-debug will ask the debug configuration template, and then ask the device to debug/run.
But it does not launch the selected device.
It launches the first device regardless of device selection.
So I checked the source.

In VSCode, toolArgs is set with device-id as followed:

    {
        "dartCodeDebugSessionID": "session-6b87a",
        "type": "dart",
        "request": "launch",
        "program": "/Users/---/Development/Samples/Flutter/namer_app/lib/main.dart",
        "projectRootPath": "/Users/---/Development/Samples/Flutter/namer_app",
        "cwd": "/Users/---/Development/Samples/Flutter/namer_app",
        "name": "Flutter (macOS)",
        "deviceId": "macos",
        "deviceName": "macOS (darwin)",
        "toolEnv": {
            "FLUTTER_HOST": "VSCode",
            "PUB_ENVIRONMENT": "vscode.dart-code",
            "FLUTTER_ROOT": "/Users/---/.bin/flutter"
        },
        "sendLogsToClient": true,
        "sendCustomProgressEvents": true,
        "allowAnsiColorOutput": true,
        "additionalProjectPaths": [
            "/Users/---/Development/Samples/Flutter/namer_app"
        ],
        "args": [],
        "vmAdditionalArgs": [],
        "toolArgs": [
            "-d",    <--------------------- this line
            "macos", <--------------------- this line
            "--devtools-server-address",
            "http://127.0.0.1:9100/",
            "-v"
        ],
        "vmServicePort": 0,
        "dartSdkPath": "/Users/---/.bin/flutter/bin/cache/dart-sdk",
        "maxLogLineLength": 2000,
        "debugSdkLibraries": false,
        "debugExternalPackageLibraries": false,
        "showDartDeveloperLogs": true,
        "evaluateGettersInDebugViews": true,
        "showGettersInDebugViews": true,
        "evaluateToStringInDebugViews": true,
        "flutterSdkPath": "/Users/---/.bin/flutter",
        "useInspectorNotificationsForWidgetErrors": true,
        "showMemoryUsage": false,
        "debuggerType": 2
    }

But lsp-dart-dap sends empty toolArgs as followed:

Sending: 
{
  "command": "launch",
  "arguments": {
    "type": "flutter",
    "name": "Flutter :: Debug<5>",
    "request": "launch",
    "dartSdkPath": "/Users/---/.bin/flutter/bin/cache/dart-sdk/",
    "maxLogLineLength": 2000,
    "cwd": "/Users/---/Development/Samples/Flutter/namer_app",
    "vmAdditionalArgs": [],
    "toolArgs": [], <--------------------- this line
    "vmServicePort": 0,
    "debugExternalLibraries": null,
    "debugSdkLibraries": null,
    "evaluateGettersInDebugViews": true,
    "evaluateToStringInDebugViews": true,
    "flutterSdkPath": "/Users/---/.bin/flutter/",
    "flutterTrackWidgetCreation": true,
    "useFlutterStructuredErrors": true,
    "useWriteServiceInfo": true,
    "debuggerHandlesPathsEverywhereForBreakpoints": true,
    "flutterMode": "debug",
    "program": "/Users/---/Development/Samples/Flutter/namer_app/lib/main.dart",
    "deviceId": "5F0BF254-92C6-450D-85DC-CF24D42C5962",
    "deviceName": "iPhone 15",
    "flutterPlatform": "default"
  },
  "type": "request",
  "seq": 2
}

In lsp-dart-dap--populate-flutter-start-file-args, toolArgs will be set with device-id if toolArgs is absent as followed:

(defun lsp-dart-dap--populate-flutter-start-file-args (conf)
  "Populate CONF with the required arguments for Flutter debug."
  (let ((pre-conf (-> conf
                      lsp-dart-dap--base-debugger-args
                      (dap--put-if-absent :type "flutter")
                      (dap--put-if-absent :flutterMode "debug")
                      (dap--put-if-absent :program (or (lsp-dart-get-project-entrypoint)
                                                       (buffer-file-name))))))
    (lambda (start-debugging-callback)
      (lsp-dart-dap--flutter-get-or-start-device
       (-lambda ((&hash "id" device-id "name" device-name))
         (funcall start-debugging-callback
                  (-> pre-conf
                      (dap--put-if-absent :deviceId device-id)
                      (dap--put-if-absent :deviceName device-name)
                      (dap--put-if-absent :dap-server-path (if (lsp-dart-dap-use-sdk-debugger-p)
                                                               (append (lsp-dart-flutter-command) (list "debug_adapter" "-d" device-id))
                                                             lsp-dart-dap-flutter-debugger-program))
                      (dap--put-if-absent :flutterPlatform "default")
                      (dap--put-if-absent :toolArgs `("-d" ,device-id))
                      (dap--put-if-absent :name (concat "Flutter (" device-name ")")))))))))

But toolArgs is not absent here.
It's set in lsp-dart-dap--base-debugger-args with the value of defcustom lsp-dart-dap-tool-args.
And the default value of lsp-dart-dap-tool-args is [] as followed:

(defcustom lsp-dart-dap-tool-args []
  "Additional args for the dart or flutter tool"
  :group 'lsp-dart
  :type '(repeat string))

So toolArgs will be always the value of lsp-dart-dap-toolArgs in lsp-dart-dap--populate-flutter-start-file-args.

I suppose that toolArgs should be added to the previous values instead of setting a new value if absent, because someone wants to set lsp-dart-dap-tool-args with certain values and device-id by user selection should be added to the values.

Workaround
I set lsp-dart-dap-tool-args to nil.
Then, dap-debug launches the selected device as followed:

Sending: 
{
  "command": "launch",
  "arguments": {
    "type": "flutter",
    "name": "Flutter :: Debug<7>",
    "request": "launch",
    "dartSdkPath": "/Users/---/.bin/flutter/bin/cache/dart-sdk/",
    "maxLogLineLength": 2000,
    "cwd": "/Users/---/Development/Samples/Flutter/namer_app",
    "vmAdditionalArgs": [],
    "toolArgs": [
      "-d",   <--------------------- this line
      "macos" <--------------------- this line
    ],
    "vmServicePort": 0,
    "debugExternalLibraries": null,
    "debugSdkLibraries": null,
    "evaluateGettersInDebugViews": true,
    "evaluateToStringInDebugViews": true,
    "flutterSdkPath": "/Users/---/.bin/flutter/",
    "flutterTrackWidgetCreation": true,
    "useFlutterStructuredErrors": true,
    "useWriteServiceInfo": true,
    "debuggerHandlesPathsEverywhereForBreakpoints": true,
    "flutterMode": "debug",
    "program": "/Users/---/Development/Samples/Flutter/namer_app/lib/main.dart",
    "deviceId": "macos",
    "deviceName": "macOS",
    "flutterPlatform": "default"
  },
  "type": "request",
  "seq": 2
}

Note
I checked that the issue is reproducible with latest melpa packages.

To Reproduce

  1. Start dap-debug of Flutter project
  2. Select debug configuration template. In my case, it is ("Flutter :: Debug" :type "flutter" :name "Flutter :: Debug").
  3. Select any device which is not the first device.
  4. The first device launches regardsless of device selection.

Expected behavior
dap-debug should launch the selected device.

Version
[LSP Dart] 1.24.3 at 2024.06.01 @ Emacs 29.3
[Dart SDK] Dart SDK version: 3.4.1 (stable) (Tue May 21 15:46:25 2024 +0000) on "macos_x64"

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions