This is an archive of the discontinued LLVM Phabricator instance.

[lldb] Make sure the value of `eSymbolContextVariable` is not conflicting with `RESOLVED_FRAME_CODE_ADDR`
ClosedPublic

Authored by akyrtzi on Nov 30 2022, 5:11 PM.

Diff Detail

Event Timeline

akyrtzi created this revision.Nov 30 2022, 5:11 PM
Herald added a project: Restricted Project. · View Herald TranscriptNov 30 2022, 5:11 PM
akyrtzi requested review of this revision.Nov 30 2022, 5:11 PM
Herald added a project: Restricted Project. · View Herald TranscriptNov 30 2022, 5:11 PM
aprantl accepted this revision.Nov 30 2022, 5:14 PM

I *think* this is what the code intended, yes.

This revision is now accepted and ready to land.Nov 30 2022, 5:14 PM

I'm not as sure about this. I think the idea was that eSymbolContextEverything would have a value like 0b1111 and so we know only 4 bits (in my example here) are used for the eSymbolContext* enums. StackFrame's m_flags wants to use the bits above that range for RESOLVED_FRAME_CODE_ADDR, RESOLVED_FRAME_ID_SYMBOL_SCOPE, GOT_FRAME_BASE, RESOLVED_VARIABLES, RESOLVED_GLOBAL_VARIABLES flags. So it's setting RESOLVED_FRAME_CODE_ADDR to (in my example) 0b10000, leaving those 4 low bits free to indicate the eSymbolContext values. That is, we would have

0bnnnn0000 start of eSymbolContext range
0bnnnn1111 end of eSymbolContext range
0b0001mmmm RESOLVED_FRAME_CODE_ADDR
0b0010mmmm RESOLVED_FRAME_ID_SYMBOL_SCOPE
0b0011mmmm GOT_FRAME_BASE
0b0100mmmm RESOLVED_VARIABLES
0b0101mmmm RESOLVED_GLOBAL_VARIABLES

The idea is to have two unrelated set of flags in this single m_flags which I am suspicious of how necessary that is, tbh. In a typical big multi threaded GUI app you might have 20-30 threads with 40-50 stack frames, that's like 1500 StackFrames. I think we keep the stack frame list from the previous step when stepping, so twice that. Having an extra uint32_t for 3k StackFrame objects does not concern me.

I agree that having eSymbolContextVariable be outside the range of eSymbolContextEverything breaks this scheme, but I don't think this is the correct fix.

a simple fix would be to stick the 5 extra flags the top of the 32-bit m_flags and hope that eSymbolContext* doesn't go that high. I wonder if there's some compile time error that could check that eSymbolContextEverything is less than a certain value or something like that.

aprantl requested changes to this revision.Dec 1 2022, 10:42 AM

I'll defer to @jasonmolenda

This revision now requires changes to proceed.Dec 1 2022, 10:42 AM

FWIW I think the only change needed to the original patch is to keep using #define RESOLVED_FRAME_CODE_ADDR (uint32_t(eSymbolContextEverything + 1)) but switch to the new eSymbolContextLastItem that is defined. Possibly the comment about what this code is doing could be made a little clearer, because it is definitely not. :)

FWIW I think the only change needed to the original patch is to keep using #define RESOLVED_FRAME_CODE_ADDR (uint32_t(eSymbolContextEverything + 1)) but switch to the new eSymbolContextLastItem that is defined. Possibly the comment about what this code is doing could be made a little clearer, because it is definitely not. :)

Thank you for the feedback, but it's unclear to me what you mean, are you saying leave the #define RESOLVED_FRAME_CODE_ADDR line unmodified? If yes, what does "switch to the new eSymbolContextLastItem" mean?

FWIW I think the only change needed to the original patch is to keep using #define RESOLVED_FRAME_CODE_ADDR (uint32_t(eSymbolContextEverything + 1)) but switch to the new eSymbolContextLastItem that is defined. Possibly the comment about what this code is doing could be made a little clearer, because it is definitely not. :)

Thank you for the feedback, but it's unclear to me what you mean, are you saying leave the #define RESOLVED_FRAME_CODE_ADDR line unmodified? If yes, what does "switch to the new eSymbolContextLastItem" mean?

@jasonmolenda 🙏?

FWIW I think the only change needed to the original patch is to keep using #define RESOLVED_FRAME_CODE_ADDR (uint32_t(eSymbolContextEverything + 1)) but switch to the new eSymbolContextLastItem that is defined. Possibly the comment about what this code is doing could be made a little clearer, because it is definitely not. :)

Thank you for the feedback, but it's unclear to me what you mean, are you saying leave the #define RESOLVED_FRAME_CODE_ADDR line unmodified? If yes, what does "switch to the new eSymbolContextLastItem" mean?

@jasonmolenda 🙏?

Ah sorry for not replying Argyrios, just to be explicit I was thinking something like

diff --git a/lldb/include/lldb/lldb-enumerations.h b/lldb/include/lldb/lldb-enumerations.h
index c46ef4bf361..9020c0f4d9f 100644
--- a/lldb/include/lldb/lldb-enumerations.h
+++ b/lldb/include/lldb/lldb-enumerations.h
@@ -377,2 +377,5 @@ FLAGS_ENUM(SymbolContextItem){
     eSymbolContextVariable = (1u << 7),
+
+    // Keep this last and up-to-date for what the last enum value is.
+    eSymbolContextLastItem = ((eSymbolContextVariable << 1) - 1u),
 };
diff --git a/lldb/source/Target/StackFrame.cpp b/lldb/source/Target/StackFrame.cpp
index b600ffe9520..a7f87dbb1c5 100644
--- a/lldb/source/Target/StackFrame.cpp
+++ b/lldb/source/Target/StackFrame.cpp
@@ -46,3 +46,7 @@ using namespace lldb_private;
 // context (m_sc) already.
-#define RESOLVED_FRAME_CODE_ADDR (uint32_t(eSymbolContextEverything + 1))
+// RESOLVED_FRAME_CODE_ADDR adds 1 to the value of eSymbolContextLastItem,
+// assuming this is an all-ones value indicating the positions used by
+// eSymbolContext entries.  We want to define some flags outside that range of
+// bits for our use.
+#define RESOLVED_FRAME_CODE_ADDR (uint32_t(eSymbolContextLastItem + 1))
 #define RESOLVED_FRAME_ID_SYMBOL_SCOPE (RESOLVED_FRAME_CODE_ADDR << 1)

(I haven't tested this or anything) what do you think.

I prefer my original version because:

  • eSymbolContextLastItem is not an appropriate name for collection of bits, it should be named like eSymbolContextReallyEverything or something, which then makes things a bit confusing due to having multiple "everything" enums.
  • I like the code consistency and readability of all RESOLVED_* macros here being shifts by one of the previous bit. When I first read this code I had to stop and think about why RESOLVED_FRAME_CODE_ADDR is different than the rest; "eSymbolContextLastItem << 1" is clearer to understand IMO, particularly in the context of the other macros.

I prefer my original version because:

  • eSymbolContextLastItem is not an appropriate name for collection of bits, it should be named like eSymbolContextReallyEverything or something, which then makes things a bit confusing due to having multiple "everything" enums.
  • I like the code consistency and readability of all RESOLVED_* macros here being shifts by one of the previous bit. When I first read this code I had to stop and think about why RESOLVED_FRAME_CODE_ADDR is different than the rest; "eSymbolContextLastItem << 1" is clearer to understand IMO, particularly in the context of the other macros.

You're right. In my mind, I mixed the two of our solutions together and that would not work. Your solution is consistent and will work. Please land your change, sorry for the distraction.

jasonmolenda accepted this revision.Dec 5 2022, 1:16 PM
This revision was not accepted when it landed; it landed in state Needs Revision.Dec 5 2022, 1:54 PM
This revision was automatically updated to reflect the committed changes.