This is an archive of the discontinued LLVM Phabricator instance.

FuncUnwinders: remove "current_offset" from function arguments
ClosedPublic

Authored by labath on Apr 17 2019, 9:21 AM.

Details

Summary

This argument was added back in 2010 (r118882) to support the ability to unwind
from functions whose eh_frame entry does not cover the entire range of
the function.

However, due to the caching happening in FuncUnwinders, this solution is
very fragile. FuncUnwinders will cache the plan it got from eh_frame
regardless of the value of the current_offset, so our ability to unwind
from a given function depended what was the value of "current_offset" the
first time that this function was called.

Furthermore, since the "image show-unwind" command did not know what's
the right offset to pass, this created an unfortunate situation where
"image show-unwind" would show no valid plans for a function, even
though they were available and being used.

In this patch I implement the feature slightly differently. Instead of
giving just a base address to the eh_frame unwinder, I give it the
entire range we are interested in. Then, I change the unwinder to return
the first plan that covers (even partially) that range. This way even a
partial plan will be returned, regardless of the address in the function
where we are stopped at.

This solution is still not 100% correct, as it will not handle a
function which is covered by two independent fde entries. However, I
don't expect anybody will write this kind of functions, and this wasn't
handled by the previous implementation either. If this is ever needed in
the future. The eh_frame unwinder can be extended to return "composite"
unwind plans created by merging sevelar fde entries.

I also create a test which triggers this scenario. As doing this is
virtually impossible without hand-written assembly, the test only works
on x86 linux.

Diff Detail

Repository
rL LLVM

Event Timeline

labath created this revision.Apr 17 2019, 9:21 AM

Thanks for digging in to this Pavel. I haven't had time to look over the patch today, but I'd like to; I'll make time for it in the next couple days if that's OK.

Sure, that's no problem. Thanks for letting me know.

BTW, I have a couple more patches in the general unwinding area (part of the breakpad unwinding thing), but I still need to clean those up before they can be put up for review.

jasonmolenda accepted this revision.Apr 22 2019, 3:08 PM

Sorry for the delay in looking at this. It looks like a good change, an improvement on the original for sure. I've never seen multiple eh_frame FDEs for a single function, so that's fine. The .ARM.exidx format and Apple's compact unwind format can theoretically have multiple different unwind plans for a single function - but I've never seen it done in practice. More commonly, a single unwind plan will be used for multiple functions that have the same unwind state. (these two formats don't describe prologue/epilogues - they only describe the unwind state in the middle of the function where exceptions can be thrown)

This revision is now accepted and ready to land.Apr 22 2019, 3:08 PM

Thanks for the review. Don't worry about the delay -- it has actually coincided with the public holidays on this side of the globe, so I was not working anyway. (but the delay wasn't long even if I had worked) :)

This revision was automatically updated to reflect the committed changes.
Herald added a project: Restricted Project. · View Herald TranscriptApr 23 2019, 2:55 AM