Skip to content

Breakpoints in Dart SDK code are not hit #3551

Closed

Description

@bleroux

I tried to put breakpoints in Dart SDK code but those breakpoints are ignored.

To reproduce this I setup an environment with :

  • A fresh SDK installation : Dart SDK version: 2.15.0-68.0.dev (dev) (Wed Sep 1 05:51:32 2021 -0700) on "linux_x64"
  • A fresh Dart project created from DartCode command Dart: New Project and selecting simple-console template
  • Try to put a breakpoint in print source code

I used two ways to put this breakpoint :
1 - Using 'Go to definition' and add the breakpoint
2 - Launching a debug session and 'Step into' to reach Dart SDK source code and add the breakpoint

Two breakpoints were created with different paths, neither works :
BreakpointsList

DartCode debugging logs :
Dart-Code-Log-2021-08-05 13-41-24.txt

Corresponding session in video :
https://user-images.githubusercontent.com/840911/132003058-ce293e04-b9d7-4642-bc9e-2889701ea086.mp4

Activity

  1. DanTup commented on Sep 6, 2021

    @DanTup
    Member

    @bkonyi do you know if this is expected to work? I was certain it did (except for Flutter), but I can repro this and it doesn't work. When you Go-to-Definition you end up in a file like inside the SDK folder which results in us sending a breakpoint like this:

    {
    	"id": "10",
    	"jsonrpc": "2.0",
    	"method": "addBreakpointWithScriptUri",
    	"params": {
    		"isolateId": "isolates/996847484333475",
    		"scriptUri": "file:///Users/danny/Dev/Dart%20SDKs/v2.13.4/lib/core/print.dart",
    		"line": 9
    	}
    }
    

    The breakpoint is never resolved/never hit when printing though.

  2. added this to the On Deck milestone on Sep 6, 2021
  3. added
    in dartRelates to running Dart programs
    in debuggingRelates to the debug adapter or process of running debug sessions
    and removed
    in dartRelates to running Dart programs
    on Sep 6, 2021
  4. bleroux commented on Sep 8, 2021

    @bleroux
    Author

    Comments in flutter/flutter#27189 are very informative and still relevant.

    I tried the following dirty hack in Dart-Code/src/debug/dart_debug_impl.ts -> setBreakPointsRequest :

    		if (uri === "dart:core/print.dart") {
    		  uri = "org-dartlang-sdk:///sdk/lib/core/print.dart";
    		}

    With this, I'm able to add a breakpoint in print method for a Dart project. But it doesn't work for a Flutter project.

    It seems there are two distinct issues :

    • dart: URIs should be converted before calling VM Service addBreakpointWithScriptUri RPC
    • org-dartlang-sdk:///sdk/lib/core/print.dart is not the right URI when running on Flutter embedded SDK
  5. DanTup commented on Sep 8, 2021

    @DanTup
    Member

    dart: URIs should be converted before calling VM Service addBreakpointWithScriptUri RPC

    I'm not certain this is the correct place to fix this versus the VM. When we step into dart:core/print.dart, the VM uses dart:core/print.dart as the URI of the script:

    {
    	"jsonrpc": "2.0",
    	"result": {
    		"type": "Stack",
    		"frames": [
    			{
    				"type": "Frame",
    				"kind": "Regular",
    				"location": {
    					"type": "SourceLocation",
    					"script": {
    						"type": "@Script",
    						"fixedId": true,
    						"id": "libraries/@0150898/scripts/dart%3Acore%2Fprint.dart/0",
    						"uri": "dart:core/print.dart", // <------------------------------ see here
    						"_kind": "kernel"
    					},
    					"tokenPos": 321
    				},
    

    It seems sensible that addBreakpointWithScriptUri should accept this as a script URI, which is what we're currently sending:

    {
    	"id": "49",
    	"jsonrpc": "2.0",
    	"method": "addBreakpointWithScriptUri",
    	"params": {
    		"isolateId": "isolates/3306004115768255",
    		"scriptUri": "dart:core/print.dart",
    		"line": 10
    	}
    }
    

    Handling this in the VM would fix it for all editors rather than just VS Code (I also don't think VS Code should need to understand the internals of what org-dartlang-sdk is - it feels like an implementation detail we shouldn't rely on). I'd like @bkonyi's opinion about this before adding workarounds here (not least because the DAP is moving to the SDK so any workaround would end up being replicated there too).

  6. bleroux commented on Sep 8, 2021

    @bleroux
    Author

    I fully agree with you @DanTup : when I wrote "URIs should be converted before calling VM Service addBreakpointWithScriptUri RPC", I described the issue not what should be done to fix it 😄

    I too think that it would be better to fix this issue at the VM level, otherwhise all debugging clients (DartCode, IntelliJ Plugin, DevTools, ...) will have to provide their own workaround.

    I will try to dig deeper to see what can be done with other VM Service RPC (getScripts, getSourceReport, ...)

  7. bkonyi commented on Sep 8, 2021

    @bkonyi

    Yeah, this should almost certainly be fixed in the VM.

    Dealing with breakpoint resolution within SDK code is a pain since the VM doesn't always reference the code on disk. At the very least, for the standalone VM, I'm 99% sure we always load SDK code from a pre-built snapshot so breakpoints need to be set using the org-dartlang-sdk:// URIs, as the VM doesn't know (or care) where the actual source exists on disk. As for Flutter, I'm not sure exactly how those are referenced as things are packaged differently. I'll have to take a closer look.

  8. bleroux commented on Sep 8, 2021

    @bleroux
    Author

    @bkonyi Yes, breakpoint resolution is a pain 😅
    I'm digging in the VM code and it seems there are some inconsistencies in Script URLs resolution. When done with my investigation I will create an issue on Dart SDK repo to have your opinion.

    @DanTup Found some code in flutter/intellij dealing with BreakpointsUri : https://github.com/flutter/flutter-intellij/blob/4bd532c5dd021e88a6ad664e8ff8f929475a7796/src/io/flutter/run/FlutterPositionMapper.java#L183
    I don't think it's a fully working workaround for this issue, but it's funny they choosed to add several breakpoints at once.

  9. DanTup commented on Sep 9, 2021

    @DanTup
    Member

    @bkonyi

    Yeah, this should almost certainly be fixed in the VM.

    Ok, I will file some bugs in the SDK later with clear examples of the issue and how to repro.

    Dealing with breakpoint resolution within SDK code is a pain since the VM doesn't always reference the code on disk.

    Yeah, though it's also a pain in the IDE where (while not debugging) we only have file paths from the editor and no good way to map them (at least not without edge cases :-)).

    For one of the cases above though, there's no file path involved - the VM gives us dart:core/print.dart and we download the source from the VM to show the user. Then they add a breakpoint and we send it back as dart:core/print.dart and it still fails. This one seems like it shouldn't really need any mapping anywhere.

    @bleroux

    I don't think it's a fully working workaround for this issue, but it's funny they choosed to add several breakpoints at once.

    We used to do the same in VS Code, but it brings some complications of mapping between a single breakpoint in VS Code and multiple in the VM. Most of the bugs that required doing this (which were breakpoints only working if you sent either file:/// or package: depending on how the file was loaded in the VM) have been fixed by the VM so my preference is to try to continue down that path. Any logic that goes in editors needs duplicating in multiple places, which raises the barrier to a new editor adding debugging support (although, hopefully an SDK-provided DAP will improve that a little).

  10. bleroux commented on Sep 10, 2021

    @bleroux
    Author

    After several days of digging (well worth it, as I learned many things: building a custom Dart SDK, building a custom Dart Code, playing with Dart VM C++ code, and more), I found a very simple hack 🥁 :

    When calling addBreakpointWithScriptUri just replace dart: prefix with / 🤣

    Found this from this VM Code : https://github.com/dart-lang/sdk/blob/main/runtime/vm/object.cc#L12842

    That works nicely for Flutter app. But for Dart apps, it works partially (works only when the breakpoint is added after 'stepping in' and it creates a bug : can't find source in editor when selecting the breakpoint).

    It's just hack in DartCode, but maybe it could be included, considering that :

    • it is a small code change
    • it is a step forward compared to now (breakpoints in SDK don't work at all)
    • fixing this at the VM level is far more complicated (possible regressions, difficulty to test Flutter apps with a custom SDK, etc)

    @DanTup, I will create a PR so you can test this easily, but I don't have a strong opinion on releasing such a hack (maybe behind a flag ?).

    I will also pursue investigation on trying to fix the VMService code.

  11. DanTup commented on Sep 13, 2021

    @DanTup
    Member

    Thanks for the digging! My only concern with shipping this workaround here, is that if it's fixed in the VM in a way that stops /dart:core from working, things wouldn't work right in the version with the SDK fix.

    There's work in progress to move the debug adapters to the SDK which would actually avoid that issue, since the debug adapter code is coupled to the SDK/VM version so it might be less weird there.

    I am curious why it works this way though. If it's just an accidental bug and nobody else is doing this, then perhaps fixing it isn't going to regress anything. I'll file an SDK bug about this shortly though with some details, and wait to hear @bkonyi's opinion before deciding what to do (although if we do ship a workaround, I think it might be better to do just in the SDK DAP, which I hope we're not too far off completing and migrating Dart-Code too).

  12. bleroux commented on Sep 14, 2021

    @bleroux
    Author

    Hi @DanTup , I agree with your concern with shipping this. I think that people really interested by this will be able to use my PR to build a custom DartCode.
    Concerning fixing this at VM level, I will comment on the issue you created to give some details about my digging.
    And great to hear about DAP, I might use it to test the VM Service, as its integration tests look very nice 👍 .

  13. 23 remaining items

  14. modified the milestones: v3.42.0, v3.44.0 on May 25, 2022
  15. modified the milestones: v3.44.0, v3.46.0 on Jun 22, 2022
  16. modified the milestones: v3.46.0, v3.48.0 on Jul 25, 2022
  17. DanTup commented on Aug 25, 2022

    @DanTup
    Member

    This issue has been fixed for some upcoming releases. I tested it today using the current beta version of the Dart SDK (2.18.0), the pre-release v3.47.20220808 version of the Dart extension, and with the dart.previewSdkDaps: true setting.

    When using all of these, the Dart SDK libraryes (such as dart:core) are not mapped back to your local SDK sources (the same ones you get to using Go-to-Definition in the editor), and breakpoints set in those files will be mapped over to dart:core by the debug adapter.

    Screenshot 2022-08-25 at 11 55 55

    Some of these pieces are not released in stable releases yet, and the SDK DAPs will be a gradual roll out over the coming releases (although you can opt-in explicitly with the dart.previewSdkDaps: true setting).

    Please file issues if you still have issues with this once you have confirmed you're on:

    • = v3.47.20220808 of the Dart extension

    • = v2.18.0-271.8.beta of the Dart SDK (or a Flutter SDK that includes this version)

    • The dart.previewSdkDaps setting set to true, or you have confirmed that you've been enabled automatically as part of the gradual rollout (this will include the text "Running SDK DAP" in the log opened by the Dart: Open Extension Log command).
  18. DanTup commented on Aug 30, 2022

    @DanTup
    Member

    I noticed today that this fix does not entirely work when running Flutter apps - they return a different org-darlang-app:/// URI to the Dart SDK.

    I've filed #4128 to track this, and dart-lang/sdk#49863 to find out if it's a bug, and if not exactly what the mapping rules are.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    in debuggingRelates to the debug adapter or process of running debug sessionsis bug

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions