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

Evaluating objects in devtools panics #6724

Closed
samfoo opened this issue Jul 24, 2015 · 12 comments
Closed

Evaluating objects in devtools panics #6724

samfoo opened this issue Jul 24, 2015 · 12 comments

Comments

@samfoo
Copy link
Contributor

@samfoo samfoo commented Jul 24, 2015

./mach run http://google.com --devtools

Connecting with Firefox devtools and then evaluating any object (e.g. document or window) panics the devtools task.

thread 'ScriptTask PipelineId(0)' panicked at 'object values unimplemented', /Users/sam/projects/servo/components/script/devtools.rs:50
stack backtrace:
   1:        0x102d637a5 - sys::backtrace::write::hde88a3e3a343e9f8zms
   2:        0x102d66d95 - panicking::on_panic::h8c73c8f1e33f6d60hIw
   3:        0x102d54882 - rt::unwind::begin_unwind_inner::h781ff1cd39e7f47etqw
   4:        0x100f003ec - rt::unwind::begin_unwind::h15770877120634109354
   5:        0x101789dcc - devtools::handle_evaluate_js::hf8d8e4268a15ef34FY4
   6:        0x101781250 - script_task::ScriptTask::handle_msg_from_devtools::h3c951bf348a2287bxW2
   7:        0x10175849e - script_task::ScriptTask::handle_msgs::hde3428ec29da044dGI2
   8:        0x101752441 - script_task::ScriptTask::start::h4783a580cf5c8363wI2
   9:        0x10174da45 - script_task::ScriptTask.ScriptTaskFactory::create::closure.134253
  10:        0x10174cca4 - task::spawn_named_with_send_on_failure::closure.134247
  11:        0x10174cbc4 - boxed::F.FnBox<A>::call_box::h2611840778800251138
  12:        0x100f0dfe0 - boxed::Box<FnBox<A, Output $u3d$$u20$R$GT$$u2b$$u20$Send$u20$$u2b$$u20$$u27$a$GT$.FnOnce$LT$A$GT$::call_once::h14693085358217845385
  13:        0x100f0da52 - thread::Builder::spawn_inner::closure.98608
  14:        0x100f0d9ce - rt::unwind::try::try_fn::__rust_abi::h8177367170001023707
  15:        0x100f0d969 - rt::unwind::try::try_fn::h8177367170001023707
  16:        0x102d68798 - rust_try_inner
  17:        0x102d68785 - rust_try
  18:        0x102d61d45 - rt::unwind::try::inner_try::h9e58480e93edc0cdmmw
  19:        0x100f0d8c8 - rt::unwind::try::h11073724077922564883
  20:        0x100f0d701 - thread::Builder::spawn_inner::closure.98557
  21:        0x100f0e36d - boxed::F.FnBox<A>::call_box::h5636230815545634927
  22:        0x102d6575d - sys::thread::Thread::new::thread_start::hf153915745363fa7wKv
  23:     0x7fff904de267 - _pthread_body
  24:     0x7fff904de1e4 - _pthread_start
error: devtools actor stopped responding
thread 'Constellation' panicked at 'called `Result::unwrap()` on an `Err` value: "SendError(..)"', src/libcore/result.rs:731
stack backtrace:
   1:        0x102d637a5 - sys::backtrace::write::hde88a3e3a343e9f8zms
   2:        0x102d66d95 - panicking::on_panic::h8c73c8f1e33f6d60hIw
   3:        0x102d54882 - rt::unwind::begin_unwind_inner::h781ff1cd39e7f47etqw
   4:        0x102d54ee9 - rt::unwind::begin_unwind_fmt::h9c0f8818a5804071zpw
   5:        0x102d6676c - rust_begin_unwind
   6:        0x102d8f695 - panicking::panic_fmt::h205f328075c6fc3cneC
   7:        0x101fcc1fb - result::Result<T, E>::unwrap::h5435619241656079582
   8:        0x101fcc3ee - pipeline::Pipeline::force_exit::h4aa03399d83aa6c4cpd
   9:        0x100627395 - constellation::Constellation<LTF, STF>::close_pipeline::h3521612086826290407
  10:        0x10062542d - constellation::Constellation<LTF, STF>::handle_failure_msg::h10865159116871904329
  11:        0x100615be9 - constellation::Constellation<LTF, STF>::handle_request::h5498979617141514060
  12:        0x10060ff98 - constellation::Constellation<LTF, STF>::run::h5118925239686868095
  13:        0x1005a62e5 - constellation::Constellation<LTF, STF>::start::closure.9848
  14:        0x1005a532c - task::spawn_named::closure.9841
  15:        0x1005a5254 - boxed::F.FnBox<A>::call_box::h1820792377988725481
  16:        0x1005a4cc0 - boxed::Box<FnBox<A, Output $u3d$$u20$R$GT$$u2b$$u20$Send$u20$$u2b$$u20$$u27$a$GT$.FnOnce$LT$A$GT$::call_once::h13389399701390328953
  17:        0x1005a4732 - thread::Builder::spawn_inner::closure.9813
  18:        0x1005a46ae - rt::unwind::try::try_fn::__rust_abi::h17700210914073968490
  19:        0x1005a4649 - rt::unwind::try::try_fn::h17700210914073968490
  20:        0x102d68798 - rust_try_inner
  21:        0x102d68785 - rust_try
  22:        0x102d61d45 - rt::unwind::try::inner_try::h9e58480e93edc0cdmmw
  23:        0x1005a45a8 - rt::unwind::try::h14919764121984243442
  24:        0x1005a43e1 - thread::Builder::spawn_inner::closure.9762
  25:        0x1005a4fdd - boxed::F.FnBox<A>::call_box::h14823684526542255053
  26:        0x102d6575d - sys::thread::Thread::new::thread_start::hf153915745363fa7wKv
  27:     0x7fff904de267 - _pthread_body
  28:     0x7fff904de1e4 - _pthread_start
thread 'StorageManager' panicked at 'called `Result::unwrap()` on an `Err` value: RecvError', src/libcore/result.rs:731
stack backtrace:
   1:        0x102d637a5 - sys::backtrace::write::hde88a3e3a343e9f8zms
   2:        0x102d66d95 - panicking::on_panic::h8c73c8f1e33f6d60hIw
   3:        0x102d54882 - rt::unwind::begin_unwind_inner::h781ff1cd39e7f47etqw
   4:        0x102d54ee9 - rt::unwind::begin_unwind_fmt::h9c0f8818a5804071zpw
   5:        0x102d6676c - rust_begin_unwind
   6:        0x102d8f695 - panicking::panic_fmt::h205f328075c6fc3cneC
   7:        0x102386450 - result::Result<T, E>::unwrap::h11400035761813964212
   8:        0x102383f23 - storage_task::StorageManager::start::hecbe625afc3088f8Nfh
   9:        0x102383e45 - storage_task::StorageTask.StorageTaskFactory::new::closure.32083
  10:        0x102383d1e - task::spawn_named::closure.32077
  11:        0x102383c75 - boxed::F.FnBox<A>::call_box::h15748374251615744040
  12:        0x1021beb30 - boxed::Box<FnBox<A, Output $u3d$$u20$R$GT$$u2b$$u20$Send$u20$$u2b$$u20$$u27$a$GT$.FnOnce$LT$A$GT$::call_once::h6047560300349904354
  13:        0x1021be5a2 - thread::Builder::spawn_inner::closure.17305
  14:        0x1021be51e - rt::unwind::try::try_fn::__rust_abi::h14670310686226058315
  15:        0x1021be4b9 - rt::unwind::try::try_fn::h14670310686226058315
  16:        0x102d68798 - rust_try_inner
  17:        0x102d68785 - rust_try
  18:        0x102d61d45 - rt::unwind::try::inner_try::h9e58480e93edc0cdmmw
  19:        0x1021be418 - rt::unwind::try::h10446798129399980646
  20:        0x1021be251 - thread::Builder::spawn_inner::closure.17254
  21:        0x1021beebd - boxed::F.FnBox<A>::call_box::h17345501370248332910
  22:        0x102d6575d - sys::thread::Thread::new::thread_start::hf153915745363fa7wKv
  23:     0x7fff904de267 - _pthread_body
  24:     0x7fff904de1e4 - _pthread_start
@samfoo samfoo changed the title Evaluating some (any?) variable in devtools panics Evaluating some objects in devtools panics Jul 24, 2015
@samfoo samfoo changed the title Evaluating some objects in devtools panics Evaluating objects in devtools panics Jul 24, 2015
@jdm
Copy link
Member

@jdm jdm commented Jul 24, 2015

Yep, the objects case is harder than others because we need to retain references to JS objects for as long as they might be able to be referenced by the devtools client. The fix here is:

  • rather than panicking in devtools::handle_evaluate_js, send an ActorValue reply that includes a randomly-generated uuid
  • create a new ObjectActor type that implements the Actor trait in the devtools crate.
  • add a String entry to ActorValue and use the value of JS_GetClass on the JS object, then fetch the class name (http://doc.servo.org/js/jsapi/struct.JSClass.html)
  • use this new class name in the ActorValue handler in http://mxr.mozilla.org/servo/source/components/devtools/actors/console.rs
  • when an ActorValue reply is received, check if the UUID is present in the script_actors hashtable in ActorRegistry. If not, register a new ObjectActor and add the association between the UUID and the new actor's name.

This should get us to the point where we get a reasonable first response from a JS object return value (in the form "[object Whatever]") and set the stage for being able to investigate properties of the object in the future.

@HarryLovesCode
Copy link
Contributor

@HarryLovesCode HarryLovesCode commented Aug 7, 2015

@jdm I'll take this if you don't mind (unless it's actively being worked on of course). I assume it's ok to tell the linter to ignore unsafe blocks inside handle_evaluate_js since we're calling JS_GetClass right?

@jdm
Copy link
Member

@jdm jdm commented Aug 7, 2015

Correct! Please do take it on :)

@jdm jdm added the C-assigned label Aug 7, 2015
@HarryLovesCode
Copy link
Contributor

@HarryLovesCode HarryLovesCode commented Aug 8, 2015

@jdm Is there anyway a test could be written for this?

@jdm
Copy link
Member

@jdm jdm commented Aug 8, 2015

Not without #5971 unfortunately.

@HarryLovesCode
Copy link
Contributor

@HarryLovesCode HarryLovesCode commented Aug 8, 2015

Should JS_GetClass() really return Proxy for these?

screen shot 2015-08-07 at 9 11 50 pm

I would have thought it should output Object.constructor.name or something similar.

@jdm
Copy link
Member

@jdm jdm commented Aug 8, 2015

Mmm, good point. I hoped that we could use https://dxr.mozilla.org/mozilla-central/source/js/src/jsfriendapi.h#182 instead (since it handles proxies properly), but it doesn't appear to be exported publically. We probably want to do the equivalent of .toString() on the object.

@jdm
Copy link
Member

@jdm jdm commented Aug 8, 2015

Nevermind, it's actually there but github won't show me all 12,000 lines that make up the file. Go ahead and use jsapi::ObjectClassName:

pub unsafe extern "C" fn ObjectClassName(cx: *mut JSContext,
                                         obj: HandleObject) -> *const i8 {
@HarryLovesCode
Copy link
Contributor

@HarryLovesCode HarryLovesCode commented Aug 8, 2015

Awesome!

screen shot 2015-08-08 at 12 44 54 pm

I sort of skipped over the last point of what you said about the script_actors hashmap. Is there any reason we should use that over the actors hashmap?

// console.rs
let actor_name = match registry.contains(&uuid) {
    true => registry.find::<ObjectActor>(&uuid).name(),
    false => ObjectActor::create(registry, uuid),
};
// object.rs
impl ObjectActor {
    pub fn create(registry: &ActorRegistry, new_uuid: String) -> String {
        let actor_name = registry.new_name("object");
        let actor = ObjectActor {
            name: actor_name.clone(),
            uuid: new_uuid,
        };

        registry.register_later(box actor);
        actor_name
    }
}
// actor.rs
pub fn contains(&self, name: &str) -> bool {
    self.actors.contains_key(&name.to_string())
 }

I figured we'd want to use ACTOR_REGISTRY.handle_message for the new ObjectActor, but I might have been mistaken.

@jdm
Copy link
Member

@jdm jdm commented Aug 8, 2015

The difficulty is that we use names like "object5" for actors in the devtools task, but script tells us about JS objects using names like "34B7E350-A535-426E-BB0E-535AFBAA65AE". The hashmap gives us a mapping between those two. This will allow us to use more informative names in the future (like "tab2/object5", for example), which yields easier debugging.

@HarryLovesCode
Copy link
Contributor

@HarryLovesCode HarryLovesCode commented Aug 8, 2015

So then when we create an ObjectActor, we should...

  • use register_later (to add it to ActorRegistry.actors) or even just register
  • use register_script_actor (to add it to ActorRegistry.script_actors)

so we can map between them like you said?

Similar to this piece of inspector.rs?

@jdm
Copy link
Member

@jdm jdm commented Aug 8, 2015

Correct! I forgot about that prior art.

bors-servo pushed a commit that referenced this issue Aug 9, 2015
Allows object evaluation in devtools -- Closes #6724

The purpose of this is to fix how objects were previously evaluated in
the developer tools.

- Before this, evaluating an object such as the `window` would `panic!`
- After this, evaluating an object such as the `window` outputs `[object
  Window]`

A few things to note:

- This commit contains `unsafe` code.
- This does not contain a test because the developer tools cannot be properly tested until #5971 lands.

<!-- Reviewable:start -->
[<img src="https://reviewable.io/review_button.png" height=40 alt="Review on Reviewable"/>](https://reviewable.io/reviews/servo/servo/7101)
<!-- Reviewable:end -->
bors-servo pushed a commit that referenced this issue Aug 10, 2015
Allows object evaluation in devtools -- Closes #6724

The purpose of this is to fix how objects were previously evaluated in
the developer tools.

- Before this, evaluating an object such as the `window` would `panic!`
- After this, evaluating an object such as the `window` outputs `[object
  Window]`

A few things to note:

- This commit contains `unsafe` code.
- This does not contain a test because the developer tools cannot be properly tested until #5971 lands.

<!-- Reviewable:start -->
[<img src="https://reviewable.io/review_button.png" height=40 alt="Review on Reviewable"/>](https://reviewable.io/reviews/servo/servo/7101)
<!-- Reviewable:end -->
fabricedesre added a commit to fabricedesre/servo that referenced this issue Aug 14, 2015
The purpose of this is to fix how objects were previously evaluated in
the developer tools.

- Before this, evaluating an object such as the `window` would `panic!`
- After this, evaluating an object such as the `window` outputs `[object
  Window]`

A few things to note:

- This commit contains `unsafe` code.
- This does not contain a test because the developer tools cannot be properly tested until servo#5971 lands.
josiahdaniels added a commit to josiahdaniels/servo that referenced this issue Sep 28, 2015
The purpose of this is to fix how objects were previously evaluated in
the developer tools.

- Before this, evaluating an object such as the `window` would `panic!`
- After this, evaluating an object such as the `window` outputs `[object
  Window]`

A few things to note:

- This commit contains `unsafe` code.
- This does not contain a test because the developer tools cannot be properly tested until servo#5971 lands.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
3 participants
You can’t perform that action at this time.