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 upPerformanceObserver option buffered:true causes a double-borrow crash #25589
Comments
|
I see nothing obvious to cause this, but there are a couple uses of .clone() in the code that I imagine might be shallow-copying cells they are supposed to be deep-copying, and someone more familiar with reference semantics in Servo's cell types might want to look at those first. |
|
Fun fact - on recent revisions of master, you can build with |
|
That being said, I suspect the use of |
|
Oh, does the following let mut entries not itself drop the earlier let entries? |
|
You were correct; test is now timing out safely for some other reason instead of crashing. |
Make performance observers take "type" and "buffered" options without panicking. <!-- Please describe your changes on the following line: --> I updated the observe() method to align with spec, and fixed the borrow duration bug @jdm pointed out in #25589 so it wouldn't cause a hard crash. Some tests go from failing to passing, but others go from early failing to later timeout; performance observers still aren't doing the right thing in all cases. --- <!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `___` with appropriate data: --> - [X] `./mach build -d` does not report any errors - [X] `./mach test-tidy` does not report any errors - [X] These changes fix #24781 and fix #25589 <!-- Either: --> - [X] There are tests for these changes <!-- Also, please make sure that "Allow edits from maintainers" checkbox is checked, so that we can help you if you get stuck somewhere along the way.--> <!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->
Make performance observers take "type" and "buffered" options without panicking. <!-- Please describe your changes on the following line: --> I updated the observe() method to align with spec, and fixed the borrow duration bug @jdm pointed out in #25589 so it wouldn't cause a hard crash. Some tests go from failing to passing, but others go from early failing to later timeout; performance observers still aren't doing the right thing in all cases. --- <!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `___` with appropriate data: --> - [X] `./mach build -d` does not report any errors - [X] `./mach test-tidy` does not report any errors - [X] These changes fix #24781 and fix #25589 <!-- Either: --> - [X] There are tests for these changes <!-- Also, please make sure that "Allow edits from maintainers" checkbox is checked, so that we can help you if you get stuck somewhere along the way.--> <!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->
Make performance observers take "type" and "buffered" options without panicking. <!-- Please describe your changes on the following line: --> I updated the observe() method to align with spec, and fixed the borrow duration bug @jdm pointed out in #25589 so it wouldn't cause a hard crash. Some tests go from failing to passing, but others go from early failing to later timeout; performance observers still aren't doing the right thing in all cases. --- <!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `___` with appropriate data: --> - [X] `./mach build -d` does not report any errors - [X] `./mach test-tidy` does not report any errors - [X] These changes fix #24781 and fix #25589 <!-- Either: --> - [X] There are tests for these changes <!-- Also, please make sure that "Allow edits from maintainers" checkbox is checked, so that we can help you if you get stuck somewhere along the way.--> <!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->
Make performance observers take "type" and "buffered" options without panicking. <!-- Please describe your changes on the following line: --> I updated the observe() method to align with spec, and fixed the borrow duration bug @jdm pointed out in #25589 so it wouldn't cause a hard crash. Some tests go from failing to passing, but others go from early failing to later timeout; performance observers still aren't doing the right thing in all cases. --- <!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `___` with appropriate data: --> - [X] `./mach build -d` does not report any errors - [X] `./mach test-tidy` does not report any errors - [X] These changes fix #24781 and fix #25589 <!-- Either: --> - [X] There are tests for these changes <!-- Also, please make sure that "Allow edits from maintainers" checkbox is checked, so that we can help you if you get stuck somewhere along the way.--> <!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->
The spec now only allows
bufferedin combination with thetypeoption and not theentryTypesoption, and since we don't support thetypeoption yet, we're failing early in all the WPT tests that usebufferedand not getting to the actual behavior being tested. This crash thus needs a modified test to detect.In the course of #24781 I saw this crash and I wanted to make sure I was uncovering a pre-existing bug rather than creating a new one, so I modified performance-timeline/multiple-buffered-flag-observers.any.js. This modified test is non-spec-compliant since it's combining
entryTypeswithbuffered, but it demonstrates the problem when run on our current master which still allows that combination.Modified test code
promise_test(() => { // The first promise waits for one buffered flag observer to receive 3 entries. const promise1 = new Promise(resolve1 => { let numObserved1 = 0; new PerformanceObserver((entryList, obs) => { // This buffered flag observer is constructed after a regular observer detects a mark. new PerformanceObserver(list => { numObserved1 += list.getEntries().length; if (numObserved1 == 3) resolve1(); }).observe({entryTypes: ['mark'], buffered: true}); obs.disconnect(); }).observe({entryTypes: ['mark']}); performance.mark('foo'); }); // The second promise waits for another buffered flag observer to receive 3 entries. const promise2 = new Promise(resolve2 => { step_timeout(() => { let numObserved2 = 0; // This buffered flag observer is constructed after a delay of 100ms. new PerformanceObserver(list => { numObserved2 += list.getEntries().length; if (numObserved2 == 3) resolve2(); }).observe({entryTypes: ['mark'], buffered: true}); }, 100); performance.mark('bar'); }); performance.mark('meow'); // Pass if and only if both buffered observers received all 3 mark entries. return Promise.all([promise1, promise2]); }, 'Multiple PerformanceObservers with buffered flag see all entries');It appears that some inappropriate sharing is happening between one PerformanceObserver's entry list and the buffer of entries that another PerformanceObserver is supposed to see, so when one PerformanceObserver tries to clear its list on
.disconnect()it's re-borrowing an already borrowed value.