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 upFix frame-pointer stackwalking #22637
Conversation
|
@jdm r? In the end I could sort-of reliably reproduce the crash(go to https://newyorktimes.com, wait a bit, then click on a link, wait some more), and it seemed to be caused by the pointer dereferencing at https://github.com/servo/servo/pull/22637/files#diff-71911b06e513640e808c4586db0ee8bcR109. Adding this additional check seems to prevent it, and it makes sense since it's a check that is done in gecko as well. Gecko seems to do one more check which is still lacking here, the |
| @@ -112,6 +112,9 @@ unsafe fn frame_pointer_stack_walk(regs: Registers) -> NativeStack { | |||
| if let Err(()) = native_stack.process_register(*pc, *stack) { | |||
| break; | |||
| } | |||
| if next <= current { | |||
This comment has been minimized.
This comment has been minimized.
|
I got the crash again after all, so this requires further investigation... |
|
It should be possible to cast a pointer to usize and perform the same & 3 != 0 check. |
|
Ok so I think I finally solved the issue. The problem seemed to be that during a stack walk, the frame pointer would "suddenly" jump to point to a place very high in the stack, I'm guessing before the beginning(higher than the beginning). Actually, when cast to For example, the frame pointer would in a previous step of the walk look like:
and then at the next, look like:
While |
|
@jdm thoughts on this? I didn't add the It seems that the frame pointer stack walk differs a bit from the one in Gecko(I'm for example perplexed why Gecko seems to check for |
|
Let's go ahead and add the & 3 check as well; Gecko's implementation is well-tested, and it would be frustrating to encounter a non-pointer value later that causes a crash in the wild. |
| // Reached the end of the stack. | ||
| break; | ||
| } | ||
| if (usize::max_value() / current as usize) <= 1 { |
This comment has been minimized.
This comment has been minimized.
jdm
Jan 25, 2019
Member
We can call pthread_get_stacksize_np to determine the other end of the stack. That seems like it will be more reliable than this heuristic.
This comment has been minimized.
This comment has been minimized.
gterzian
Jan 26, 2019
•
Author
Member
I replaced this with if current as usize >= stackaddr.add(stacksize * 8) as usize, with the thinking behind * 8 being 64 bit mac... Does that make sense? It does catch the problem, as can be seen from the below print statement:
println!("Current {:?} stacksize: {:?} stackaddr {:?} test {:?} fp: {:?}", current as usize, stacksize as usize, stackaddr as usize, stackaddr.add(stacksize * 4) as usize, regs.frame_ptr as usize);
Current 123145415937664 stacksize: 2097152 stackaddr 123145407516672 test 123145415905280 fp: 123145415937664
Current 123145415937904 stacksize: 2097152 stackaddr 123145407516672 test 123145415905280 fp: 123145415937664
Current 123145415937952 stacksize: 2097152 stackaddr 123145407516672 test 123145415905280 fp: 123145415937664
Current 123145415938080 stacksize: 2097152 stackaddr 123145407516672 test 123145415905280 fp: 123145415937664
Current 123145415938160 stacksize: 2097152 stackaddr 123145407516672 test 123145415905280 fp: 123145415937664
Current 123145415938448 stacksize: 2097152 stackaddr 123145407516672 test 123145415905280 fp: 123145415937664
Current 123145415938560 stacksize: 2097152 stackaddr 123145407516672 test 123145415905280 fp: 123145415937664
Current 123145415939536 stacksize: 2097152 stackaddr 123145407516672 test 123145415905280 fp: 123145415937664
Current 123145415940096 stacksize: 2097152 stackaddr 123145407516672 test 123145415905280 fp: 123145415937664
Current 123145415940288 stacksize: 2097152 stackaddr 123145407516672 test 123145415905280 fp: 123145415937664
Current 123145415940384 stacksize: 2097152 stackaddr 123145407516672 test 123145415905280 fp: 123145415937664
Current 123145415940432 stacksize: 2097152 stackaddr 123145407516672 test 123145415905280 fp: 123145415937664
Current 123145415940496 stacksize: 2097152 stackaddr 123145407516672 test 123145415905280 fp: 123145415937664
Current 123145415940576 stacksize: 2097152 stackaddr 123145407516672 test 123145415905280 fp: 123145415937664
Current 123145415940688 stacksize: 2097152 stackaddr 123145407516672 test 123145415905280 fp: 123145415937664
Current 123145415940760 stacksize: 2097152 stackaddr 123145407516672 test 123145415905280 fp: 123145415937664
Current 18446181128325699968 stacksize: 2097152 stackaddr 123145407516672 test 123145415905280 fp: 123145415937664
|
Sorry about the delay; for some reason I thought this was still in progress. |
|
@jdm I've added the check, and used |
b40f863
to
dadf943
| @@ -112,6 +121,9 @@ unsafe fn frame_pointer_stack_walk(regs: Registers) -> NativeStack { | |||
| if let Err(()) = native_stack.process_register(*pc, *stack) { | |||
| break; | |||
| } | |||
| if (next <= current) && (next as usize & 3 != 0) { | |||
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
gterzian
Jan 29, 2019
Author
Member
Thanks, during development I actually had those into two separate if with print statements to see which one would hit, and when I collapsed them into one at the end I off-course made a mistake!
|
@bors-servo delegate+ |
|
|
|
@bors-servo r=jdm |
|
|
Fix frame-pointer stackwalking <!-- Please describe your changes on the following line: --> This seems to fix the problem, it's a check that is also done at https://dxr.mozilla.org/mozilla-central/rev/c2593a3058afdfeaac5c990e18794ee8257afe99/mozglue/misc/StackWalk.cpp#904 --- <!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `___` with appropriate data: --> - [ ] `./mach build -d` does not report any errors - [ ] `./mach test-tidy` does not report any errors - [ ] These changes fix #22604 (GitHub issue number if applicable) <!-- Either: --> - [ ] There are tests for these changes OR - [ ] These changes do not require tests because ___ <!-- 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. --> <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/22637) <!-- Reviewable:end -->
|
|
|
|
@bors-servo retry #21067 |
Fix frame-pointer stackwalking <!-- Please describe your changes on the following line: --> This seems to fix the problem, it's a check that is also done at https://dxr.mozilla.org/mozilla-central/rev/c2593a3058afdfeaac5c990e18794ee8257afe99/mozglue/misc/StackWalk.cpp#904 --- <!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `___` with appropriate data: --> - [ ] `./mach build -d` does not report any errors - [ ] `./mach test-tidy` does not report any errors - [ ] These changes fix #22604 (GitHub issue number if applicable) <!-- Either: --> - [ ] There are tests for these changes OR - [ ] These changes do not require tests because ___ <!-- 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. --> <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/22637) <!-- Reviewable:end -->
|
|
gterzian commentedJan 6, 2019
•
edited by SimonSapin
This seems to fix the problem, it's a check that is also done at https://dxr.mozilla.org/mozilla-central/rev/c2593a3058afdfeaac5c990e18794ee8257afe99/mozglue/misc/StackWalk.cpp#904
./mach build -ddoes not report any errors./mach test-tidydoes not report any errorsThis change is