Join GitHub today
GitHub is home to over 50 million developers working together to host and review code, manage projects, and build software together.
Sign upMake ScriptMemoryFailsafe use as_unsafe_cell #4692
Comments
|
@jdm Just trying to find an easy bug for my first servo fix. Not sure I understand this one. Should we call as_unsafe_cell instead of borrow_mut in the line below? |
|
Replacing both of the borrow_mut calls in that function is the intent here. As for reproducing the crash, I suggest adding a |
|
@jdm Thanks for your help. Still learning the ropes. This is my PR that just adds a panic! for console.log I created a simple page that makes a console.log call: https://dl.dropboxusercontent.com/u/4710867/v3brainstorming/template/index.html I compile servo and run it: ./mach run https://dl.dropboxusercontent.com/u/4710867/v3brainstorming/template/index.html This is the output I'm getting: http://pastebin.mozilla.org/8369054 I don't see any reference to "borrow values that are already borrowed". Am I doing everything correctly? |
|
Yes, you are, and it appears I was mistaken, assuming that was the output of a build without the changes to |
|
That being said, I think this is still a valuable change to make even if I'm having trouble coming up with reproducible ways of demonstrating its effectiveness. |
|
@jdm More noob questions. In this case: https://github.com/servo/servo/blob/master/components/script/script_task.rs#L249 Can I call as_unsafe_cell directly? Do I have to implement a new method that calls as_unsafe_cell like this one? Can I just call one of the existing ones? https://github.com/servo/servo/blob/master/components/script/dom/bindings/cell.rs#L32 |
|
Oh right, we have our wrapper type. You'll want to add a new method to it that calls through to as_unsafe_cell, like you proposed. |
|
@jdm. Thanks for your help. This is where I'm at: https://github.com/dmarcos/servo/tree/issue4692 I added a method borrow_for_script_deallocation to DOMRefCell. I'm sure you have a better name for it. I'm not sure what to do with the assert. |
|
I think you can just assert SCRIPT; we don't have any guanratees about the state of the GC when we try to reclaim memory. |
|
Continuing from #4690, I just realized that the call to |
|
@jdm I let you make the call. It doesn't really matter to me. I just want to land my first patch on servo :). Do I keep working on this or I look for a new easy bug? I'm open to suggestions if you know of another easy one that might be interesting. |
|
I would really like to have Servo stop aborting whenever there's a panic in the script task. Let's add another method to Page that does the same as |
|
@jdm Okay. Just to check I understood. Do I keep mut_js_info and add another method that calls as_unsafe_cell right? What would be a good name for the method? |
|
Let's just call it unsafe_mut_js_info for now. |
|
@jdm Ok. So I got a patch working: https://github.com/dmarcos/servo/tree/issue4692 I spent some time making the compiler happy (any tricks to make compilation faster?). I'm still wrapping my head around type casting, memory allocation/deallocation and borrowing concepts in Rust. I spent too much time in JS land in the last couple of years :). I'm sure you can suggest a cleaner way to do what I did. Below the outputs with and without my patch when running my test page that calls windows.close() on loading: https://dl.dropboxusercontent.com/u/4710867/v3brainstorming/template/index.html There are no "DOMRefCell already mutably borrowed' messages anymore: OUTPUT WITH PATCH https://pastebin.mozilla.org/8407151 OUTPUT WITHOUT PATCH (master) https://pastebin.mozilla.org/8407148 What do I do next to make my patch worth of being merged? |
|
Hmm, there are a couple things I would change there. First, I don't believe |
|
@jdm Thanks for helping with this.
I'm getting the following compilation error for borrow_for_script_deallocation: dom/bindings/cell.rs:48:9: 48:44 error: cannot borrow immutable borrowed content as mutable How should I turn the immutable return value into mutable? Just looked for examples in the servo code base but haven't found any. |
|
You should use |
|
@jsm Thanks! It compiles now. After removing the changes in https://pastebin.mozilla.org/8410108 vs no patch (master): https://pastebin.mozilla.org/8407148 What else do you want me to do? |
|
|
|
@jdm Sure. I run this on lldb and this is the output I get: https://pastebin.mozilla.org/8422656 It doesn't look meaningful to me. Should I be building servo on debug mode or something like this? How do I do it? |
|
Is that the result of |
|
@jdm This is the result of |
|
This is repeated ad infinitum:
|
|
Ok, what happens if you set a breakpoint on rust_panic? You can skip the first one (that's the borrow-related one), but the backtrace of subsequent ones should be interesting. |
|
@jdm This is what I'm getting (You can see the whole lldb sequence of commands): https://pastebin.mozilla.org/8424649 I see DOMRefCell referenced there but still looks pretty cryptic to me. |
|
@jdm It seems that it gets stuck on Garbage Collection cycles. I don't understand how my changes are affecting garbage collection |
|
I'm pretty sure you want |
|
@jdm I'm building to run lldb one more time. Any tricks to make compilation faster? Any option you can recommend that I should use? |
|
@jdm This is what I got: https://pastebin.mozilla.org/8428521 It doesn't stop on the breakpoint a second time. After doing 'c' once I get the stack overflow |
|
Huh, that's really quite peculiar. I'll clone your branch and see if I can reproduce. |
|
@jdm Yeah please go ahead. Let me know what you find. I'm just curious to understand what's going on besides looking forward to landing a first patch :) This is the branch: |
|
I figured it out! The assertion in LiveDOMReference's destructor is failing (and this shows up in one of your previous logs), and this causes an endless chain of failure because the destructor attempts to keep executing over and over. You can just delete the whole destructor (dom/bindings/refcounted.rs), since the assertion is not actually particularly useful. |
|
@jdm Sweet! Just got rid of the destructor. I see different behavior though with and without the patch. Without the patch the program aborts and with it it doesn't seem to exit, I have to quit manually. Is this expected? Below the outputs. Without the patch (master): https://pastebin.mozilla.org/8429537 With the patch: https://pastebin.mozilla.org/8429616 I pushed the changes to the branch: |
|
I noticed that too. It turns out it's because we route key events from the compositor to the current script task and back, to allow the focused element to consume events if necessary. In practice, this means |
The ScriptMemoryFailsafe is supposed to be able to reclaim all JS-related memory in the event that a script task panics. This usually doesn't work, since it tries to borrow RefCell values that are often already borrowed when panics occur, so we end up aborting Servo. We can avoid this by calling
as_unsafe_cellinstead ofborrow_mutin ScriptMemoryFailsafe's destructor; this is safe since we know that no other Rust code will be interacting with those values.http://doc.servo.org/core/cell/struct.RefCell.html#method.as_unsafe_cell