microsoft / vscode-debugadapter-node

Debug adapter protocol and implementation for VS Code.
Other
271 stars 77 forks source link

VSCode client not sending `ConfigurationDone` request #303

Closed sdankel closed 8 months ago

sdankel commented 8 months ago

I have set supportsConfigurationDoneRequest to true.

I see the Initialize Request from the client, and my DAP server responds. There are several BreakpointLocations requests corresponding to the breakpoints I've set in the VSCode UI, and the server responds. From the documentation, I would then expect to see the ConfigurationDone request sent from the client, however, it isn't sent.

I'm probably doing something wrong, but from my logs in the DAP server I can't see it. Is there a way for me to view logs from the DAP client in VSCode?

My DAP sever is written in Rust with dap-rs. I can put together a minimal example of the issue if needed. If the issue is with dap-rs, it would really help to have the client logs to debug this. Thank you!

connor4312 commented 8 months ago

You can register debug adapter trackers from your extension and log requests/responses using its methods. Logs or a minimal repro would be helpful. Thanks!

sdankel commented 8 months ago

Here are the server logs:

Ok(Initialize(Capabilities { supports_configuration_done_request: Some(false), supports_function_breakpoints: Some(true), supports_conditional_breakpoints: None, supports_hit_conditional_breakpoints: None, supports_evaluate_for_hovers: None, exception_breakpoint_filters: None, supports_step_back: None, supports_set_variable: None, supports_restart_frame: None, supports_goto_targets_request: None, supports_step_in_targets_request: None, supports_completions_request: None, completion_trigger_characters: None, supports_modules_request: None, additional_module_columns: None, supported_checksum_algorithms: None, supports_restart_request: None, supports_exception_options: None, supports_value_formatting_options: None, supports_exception_info_request: None, support_terminate_debuggee: None, support_suspend_debuggee: None, supports_delayed_stack_trace_loading: None, supports_loaded_sources_request: None, supports_log_points: None, supports_terminate_threads_request: None, supports_set_expression: None, supports_terminate_request: None, supports_data_breakpoints: None, supports_read_memory_request: None, supports_write_memory_request: None, supports_disassemble_request: None, supports_cancel_request: None, supports_breakpoint_locations_request: Some(true), supports_clipboard_context: None, supports_stepping_granularity: None, supports_instruction_breakpoints: None, supports_exception_filter_options: None, supports_single_thread_execution_requests: None }))
Request { seq: 2, command: Launch(LaunchRequestArguments { no_debug: None, restart_data: None, additional_data: Some(Object {"__configurationTarget": Number(6), "__sessionId": String("6ba9eb4b-b473-40c6-a0d3-a7e536be679c"), "name": String("Sway Server"), "program": String("/Users/sophiedankel/Development/sway-playground/projects/swaypad/src/main.sw"), "request": String("launch"), "type": String("mock")}) }) }
Ok(Launch)
Request { seq: 3, command: BreakpointLocations(BreakpointLocationsArguments { source: Source { name: Some("main.sw"), path: Some("/Users/sophiedankel/Development/sway-playground/projects/swaypad/src/main.sw"), source_reference: None, presentation_hint: None, origin: None, sources: None, adapter_data: None, checksums: None }, line: 5, column: None, end_line: None, end_column: None }) }
Ok(BreakpointLocations(BreakpointLocationsResponse { breakpoints: [BreakpointLocation { line: 5, column: None, end_line: None, end_column: None }] }))
Request { seq: 4, command: BreakpointLocations(BreakpointLocationsArguments { source: Source { name: Some("main.sw"), path: Some("/Users/sophiedankel/Development/sway-playground/projects/swaypad/src/main.sw"), source_reference: None, presentation_hint: None, origin: None, sources: None, adapter_data: None, checksums: None }, line: 13, column: None, end_line: None, end_column: None }) }
Ok(BreakpointLocations(BreakpointLocationsResponse { breakpoints: [BreakpointLocation { line: 5, column: None, end_line: None, end_column: None }, BreakpointLocation { line: 13, column: None, end_line: None, end_column: None }] }))
connor4312 commented 8 months ago

I think you're missing at least a few things from that log; VS Code does not generally request breakpoint locations without first setting a breakpoint.

sdankel commented 8 months ago

debug-repro.zip

Attached is the minimal rust project. You'll need to have the rust toolchain and cargo installed to build it. You can install the DAP server binary with cd <root of the unzipped project> and cargo install --path .

This is the snippet in plugin's package.json:

    "debuggers": [
      {
        "type": "mock",
        "label": "Mock Debug",
        "program": "<path/to>/.cargo/bin/debug-repro", // change the path for your machine
        "languages": [""], // change this to the test project language
        "configurationAttributes": {
          "launch": {
            "required": [
              "program"
            ],
            "properties": {
              "program": {
                "type": "string",
                "description": "Absolute path to a text file.",
                "default": "${file}"
              }
            }
          },
          "attach": {
            "required": [
              "program"
            ],
            "properties": {
              "program": {
                "type": "string",
                "description": "Absolute path to a text file.",
                "default": "${file}"
              }
            }
          }
        }
      }
    ]

and launch.json in the sample project:

{
    "version": "0.2.0",
    "configurations": [
        {
        "type": "mock",
        "request": "launch",
        "name": "DAP Server",
        "program": "${file}"
    }]
}
sdankel commented 8 months ago

I think you're missing at least a few things from that log; VS Code does not generally request breakpoint locations without first setting a breakpoint.

Correct, I have 2 breakpoints set in my test file.

sdankel commented 8 months ago

I tried out the DAP tracker, by adding this to my extension:

  debug.registerDebugAdapterTrackerFactory('*', {
    createDebugAdapterTracker: () => ({
      onDidSendMessage: m => {
        if (m.type === 'response') {
          log.info('DAP response:', m);
        } else if (m.type === 'event') {
          log.info('DAP event:', m);
        } else {
          log.info('DAP msg:', m);
        }
      },
      onWillReceiveMessage: m => {
        log.info('DAP onWillReceiveMessage:', m);
      }
    })});

I can see the logs now, and there is no configuration done event being sent from the client's perspective either. Here are the relevant logs.

DAP response to initialize request clearly has supportsConfigurationDoneRequest: true

INFO [1/9/2024, 12:17:46 PM]: DAP response: {
  seq: 3,
  type: 'response',
  request_seq: 1,
  success: true,
  command: 'initialize',
  body: {
    supportsConfigurationDoneRequest: true,
    supportsBreakpointLocationsRequest: true
  },
  error: null
}

The last onWillReceiveMessage message from the client is breakpointLocations, not configurationDone

INFO [1/9/2024, 12:17:46 PM]: DAP onWillReceiveMessage: {
  command: 'breakpointLocations',
  arguments: {
    source: {
      name: 'main.sw',
      path: '/Users/sophiedankel/Development/sway-playground/projects/swaypad/src/main.sw'
    },
    line: 14
  },
  type: 'request',
  seq: 5
}

Please let me know if the repro example I provided works for you. I'm not sure how to debug this further. @connor4312

sdankel commented 8 months ago

I figured out what I was doing wrong. I misinterpreted the docs - I thought that the InitializeResponse was the same as the Initialize event, so I wasn't sending the event. When I send the Initialize event after the InitializeResponse, I get the ConfigurationDone request.

connor4312 commented 8 months ago

Glad you got it figured out! I hadn't gotten around to trying the repro yet since the holidays