This is an archive of the discontinued LLVM Phabricator instance.

Replace StackID's operator "<" with a function returning FrameComparison
Needs ReviewPublic

Authored by tatyana-krasnukha on Dec 1 2021, 3:50 AM.

Details

Summary

"false" result of the operator can imply not only "the frame is not younger". When CFAs are equal, StackID's operator "<" can only compare symbol contexts of the same function. Otherwise, it also returns false.

In the case I described in D114861, two different frames can have the same CFA, and then the operator's result may be incorrect. "thread step-*" commands get broken in this case.

This patch replaces the operator that can return only boolean value with the function that returns a value of lldb::FrameComparison type. It also updates thread plans to use this function instead of the operator.

Diff Detail

Repository
rLLDB LLDB

Event Timeline

tatyana-krasnukha requested review of this revision.Dec 1 2021, 3:50 AM

I don't really know what to make of this, but adding Jim for the thread plan changes.

IIUC, the crux of this change is having the comparison able to return eFrameCompareUnknown when the < operator was returning "less than", and the handling of Unknown in the various thread plans. Is that right? There's so much formal change here it's hard to see what you are actually doing.
So the functional parts of the change are just the couple of places where you added eFrameCompareUnknown handling that does an additional "pc" compare. Is that right? If so, that seems fine to me, though it would be much nicer if there were examples we could use to test this new behavior.

I actually like having the CompareTo rather than doing a bunch if if ==, then else if < then else. So that part seems good. But it's a little hard to grok the extent of this change.

lldb/source/Target/StackID.cpp
33

It would be easier to read this if the operator== were above CompareTo rather than below it. The first thing this function does is call the == comparator, so it would be nice to have that right next to where it's called.

It's seems a little odd at first to still have the == operator, you'd thing CompareTo should handle everything and then the == should just be lhs.CompareTo(rhs) == eFrameCompareEqual but the CompareTo computation does work that's not needed for ==, so actually that part is fine.

lldb/source/Target/ThreadPlanStepOut.cpp
513

"Current" is confusing, since in the context of frames we use it as part of "Currently Selected Frame" most often, which this is not treating. This has also become a somewhat obscure function, so it definitely needs some comment saying why this computation does what the function name says it does.

lldb/source/Target/ThreadPlanStepRange.cpp
219

This doesn't seem like a good use of auto. In an IDE it's nice to be able to do "Jump to definition" to see the options here, which is harder to do with auto than with the actual type.

Herald added a project: Restricted Project. · View Herald TranscriptJul 15 2022, 12:41 PM

It might also be good to document that CompareTo doesn't try to calculate, and will never return eFrameCompareSameParent. A StackID can't do that because it doesn't really know how to unwind from itself, so that's a pretty sensible restriction, but it makes it easier to reason about all the places where CompareTo is called and SameParent isn't handled.