Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

getObject: (-32603) Unexpected DWDS error for getObject: Unsupported operation: Only libraries, instances, classes, and scripts are supported for getObject #2446

Closed
Jordan-Nelson opened this issue Jun 11, 2024 · 11 comments
Assignees
Labels
dart-debug-extension P2 A bug or feature request we're likely to work on triaged

Comments

@Jordan-Nelson
Copy link

I am unable to view a getter in Dart's dev tools with the following app on web only. I am unsure if this is supposed to work, but I don't see why it shouldn't.

Screenshot 2024-06-11 at 5 40 38 PM

Steps to repro:

  1. create a flutter app with the code below
  2. run app on web
  3. set break point on the print statement
  4. view the local vars in dev tools
import 'package:flutter/material.dart';

class CustomHttpRequest {
  const CustomHttpRequest(this.bytes);
  final List<int> bytes;
  Stream<List<int>> get body => Stream.value(bytes);
}

void main() {
  runApp(const MyApp());
}

class MyApp extends StatefulWidget {
  const MyApp({super.key});
  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(),
        body: Center(
          child: Column(
            children: [
              FilledButton(
                onPressed: () {
                  const r = CustomHttpRequest([1, 2, 3]);
                  print('r body: ${r.body}');
                },
                child: const Text('request'),
              ),
            ],
          ),
        ),
      ),
    );
  }
}
@CoderDake
Copy link

Error thrown here:

throw UnsupportedError('Only libraries, instances, classes, and scripts '
'are supported for getObject');

We'll have to take a closer look into how we might be able to grab that information and pass it along.

@Lorenzobettega
Copy link

I encountered the same issue in my code when I attempted to cast() an Object List.
The debugger showed a generic error in the devTools for web.
my flutter doctor: [√] Chrome - develop for the web
I'm thinking that this is related to the old issue: #2297
image

@bkonyi
Copy link
Collaborator

bkonyi commented Jul 31, 2024

@elliette seems to think this is an issue that has come up before. She'll share the context if she can find it, but otherwise we'll have to dig in to this to figure out what's going on.

@bkonyi bkonyi added P2 A bug or feature request we're likely to work on triaged labels Jul 31, 2024
@elliette
Copy link
Contributor

This is the issue I was thinking of:

This seems like a separate issue though

@derekxu16
Copy link
Member

derekxu16 commented Aug 2, 2024

Thank you for the reproduction instructions, @Jordan-Nelson. The problem here is that the ability to request an instance of a _ControllerStream is currently broken. Here's how I created a minimal reproduction of this problem using DWDS test cases:

  1. I added final stream = Stream.value(1); after this line.

  2. After this line, I added the following test case:

     test('for a stream', () async {
       final remote = await inspector.jsEvaluate(
         libraryVariableExpression('stream', compilationMode),
       );
       final instance = await inspector.instanceFor(remote);
       expect(instance!.kind, InstanceKind.kPlainInstance);
       final classRef = instance.classRef!;
       expect(classRef.name, '_ControllerStream<int>');
       expect(inspector.isDisplayableObject(instance), isTrue);
     });
    
  3. After this line, I added the following test case:

     test('for a stream', () async {
       final remoteObject = await inspector.jsEvaluate(
         libraryVariableExpression('stream', compilationMode),
       );
       final ref = await inspector.instanceRefFor(remoteObject);
       expect(ref!.kind, InstanceKind.kPlainInstance);
       final classRef = ref.classRef!;
       expect(classRef.name, '_ControllerStream<int>');
       expect(
         classRef.id,
         'classes|dart:async|_ControllerStream<int>',
       );
       expect(inspector.isDisplayableObject(ref), isTrue);
     });
    

test/instances/instance_test.dart fails when run after making the changes above. Here's an excerpt from the logs:

[FINE] ClassMetadata: Could not create class metadata for {type: object, className: _ControllerStream.new, description: _ControllerStream.new, objectId: -56064532640991652.1.2}:
Unexpected error from chrome devtools:
text: Uncaught
exception:
  preview: null
  description: Error
    at Object.throw_ [as throw] (http://localhost:41141/packages/build_web_compilers/src/dev_compiler/dart_sdk.js:9456:11)
    at [_subscribe] (http://localhost:41141/packages/build_web_compilers/src/dev_compiler/dart_sdk.js:39649:21)
    at [_createSubscription] (http://localhost:41141/packages/build_web_compilers/src/dev_compiler/dart_sdk.js:36508:46)
    at _ControllerStream.new.listen (http://localhost:41141/packages/build_web_compilers/src/dev_compiler/dart_sdk.js:36474:53)
    at get length (http://localhost:41141/packages/build_web_compilers/src/dev_compiler/dart_sdk.js:23587:14)
    at Object._get (http://localhost:41141/packages/build_web_compilers/src/dev_compiler/dart_sdk.js:9356:18)
    at Object.getObjectMetadata (http://localhost:41141/packages/build_web_compilers/src/dev_compiler/dart_sdk.js:9190:23)
    at _ControllerStream.new.<anonymous> (<anonymous>:4:23)
  type: object
  value: null
attempted JS eval: `        function(arg) {
          const sdk = require('dart_sdk');
          const dart  = sdk.dart;
          return dart.getObjectMetadata(arg);
        }
      `

It looks some DDC changes will be needed to fix this. @Markzipan and @nshahan, can you take a look at this when you get the chance?

Edit: I originally didn't include step 3 in my reproduction instructions becuase I didn't think it was necessary, but it turns out that it is.

@nshahan
Copy link
Contributor

nshahan commented Aug 9, 2024

@natebiggs
I don't think this is directly related to your async rewrites change but maybe your experience could help identify where this is failing and why?

@biggs0125
Copy link
Contributor

I tried to repro this locally using the instructions @derekxu16 listed above but I was unable to. What version of Dart are you using when seeing this failure?

@derekxu16
Copy link
Member

I just tried running it again and saw the same error.

❯ dart --version
Dart SDK version: 3.6.0-134.0.dev (dev) (Fri Aug 9 01:02:59 2024 -0700) on "linux_x64"

@biggs0125
Copy link
Contributor

Chatted with @derekxu16 offline and we realized this failure is only reproducible if you also add the following to the test group 'instanceRef' in instance_common.dart:

test('for a stream', () async {
  final remoteObject = await inspector.jsEvaluate(
    libraryVariableExpression('stream', compilationMode),
  );
  final ref = await inspector.instanceRefFor(remoteObject);
  expect(ref!.kind, InstanceKind.kPlainInstance);
  final classRef = ref.classRef!;
  expect(classRef.name, '_ControllerStream<int>');
  expect(
    classRef.id,
    'classes|dart:async|_ControllerStream<int>',
  );
  expect(inspector.isDisplayableObject(ref), isTrue);
});

@biggs0125
Copy link
Contributor

Okay I was able to figure out that the issue here is with this invocation of the length getter on the _ControllerStream object.

_ControllerStream only allows one subscription at a time and each call to length subscribes to the stream.

The issue here is that we are calling the length getter on every object being debugged. As outlined by the vm service we should only be invoking a length getter for specific types. I'm opening a CL in DDC to fix this.

@biggs0125
Copy link
Contributor

Landing this fix: https://dart-review.googlesource.com/c/sdk/+/380220

This fix should get included in the next Dart release. Until then users will get errors if the same Stream object is queried multiple times.

copybara-service bot pushed a commit to dart-lang/sdk that referenced this issue Aug 13, 2024
The DDC runtime invokes the 'length' getter on every object for which debug info is requested. This includes objects where the 'length' getter may be present but not intended to be called. (e.g. a Stream object).

The vm_service outlines specific guidelines for the 'length' value of a debug instance ref:
https://github.com/dart-lang/sdk/blob/main/pkg/vm_service/lib/src/vm_service.dart#L4621

This updates the runtime debugger logic to align with the vm_service expectations.

Bug: dart-lang/webdev#2446
Change-Id: Ia567cdc7df12957834b61a8fe1ac54e02a180f13
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/380220
Reviewed-by: Nicholas Shahan <nshahan@google.com>
Commit-Queue: Nate Biggs <natebiggs@google.com>
derekxu16 added a commit to derekxu16/webdev that referenced this issue Sep 12, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
dart-debug-extension P2 A bug or feature request we're likely to work on triaged
Projects
None yet
Development

No branches or pull requests

8 participants