Skip to content

Commit 5477fbc

Browse files
committed
[lldb] Make deleting frame recognizers actually work
Summary: Frame recognizers are stored alongside a flag that indicates whether they were deleted by the user. If the flag is set, they are supposed to be ignored by the rest of the frame recognizer code. 'frame recognizer delete' is supposed to set that flag. 'frame recognizer clear' however actually deletes all frame recognizers (so, it doesn't set the flag but directly deletes them from the list). The current implementation of this concept is pretty broken. `frame recognizer delete` sets the flag, but it somehow thinks that the recognizer id is an index in the recognizer list. That's not true as it's actually just a member of each recognizer entry. So it actually just sets the `deleted` flag for a random other recognizer. The tests for the recognizer still pass as `frame recognizer list` is also broken and just completely ignored the `deleted` flag and lists all recognizers. Also `frame recognizer delete` just ignores if it can't actually delete a recognizer if the id is invalid. I think we can simplify this whole thing by just actually deleting recognizers instead of making sure all code is actually respecting the `deleted` flag. I assume the intention of this was to make sure that all recognizers are getting unique ids over the course of an LLDB session, but as `clear` is actually deleting them and we keep recycling ids, that didn't really work to begin with. This patch deletes the `deleted` flag and just actually deletes the stored recognizer. Also adds the missing error message in case it find a recognizer with a given id. Reviewers: mib Reviewed By: mib Subscribers: abidh, JDevlieghere Differential Revision: https://reviews.llvm.org/D84404
1 parent 302e91b commit 5477fbc

File tree

4 files changed

+35
-13
lines changed

4 files changed

+35
-13
lines changed

lldb/include/lldb/Target/StackFrameRecognizer.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,6 @@ class StackFrameRecognizerManager {
125125
private:
126126
struct RegisteredEntry {
127127
uint32_t recognizer_id;
128-
bool deleted;
129128
lldb::StackFrameRecognizerSP recognizer;
130129
bool is_regexp;
131130
ConstString module;

lldb/source/Commands/CommandObjectFrame.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -999,9 +999,14 @@ class CommandObjectFrameRecognizerDelete : public CommandObjectParsed {
999999
return false;
10001000
}
10011001

1002-
GetSelectedOrDummyTarget()
1003-
.GetFrameRecognizerManager()
1004-
.RemoveRecognizerWithID(recognizer_id);
1002+
if (!GetSelectedOrDummyTarget()
1003+
.GetFrameRecognizerManager()
1004+
.RemoveRecognizerWithID(recognizer_id)) {
1005+
result.AppendErrorWithFormat("'%s' is not a valid recognizer id.\n",
1006+
command.GetArgumentAtIndex(0));
1007+
result.SetStatus(eReturnStatusFailed);
1008+
return false;
1009+
}
10051010
result.SetStatus(eReturnStatusSuccessFinishResult);
10061011
return result.Succeeded();
10071012
}

lldb/source/Target/StackFrameRecognizer.cpp

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -50,17 +50,17 @@ ScriptedStackFrameRecognizer::RecognizeFrame(lldb::StackFrameSP frame) {
5050
void StackFrameRecognizerManager::AddRecognizer(
5151
StackFrameRecognizerSP recognizer, ConstString module,
5252
llvm::ArrayRef<ConstString> symbols, bool first_instruction_only) {
53-
m_recognizers.push_front({(uint32_t)m_recognizers.size(), false, recognizer,
54-
false, module, RegularExpressionSP(), symbols,
53+
m_recognizers.push_front({(uint32_t)m_recognizers.size(), recognizer, false,
54+
module, RegularExpressionSP(), symbols,
5555
RegularExpressionSP(), first_instruction_only});
5656
}
5757

5858
void StackFrameRecognizerManager::AddRecognizer(
5959
StackFrameRecognizerSP recognizer, RegularExpressionSP module,
6060
RegularExpressionSP symbol, bool first_instruction_only) {
61-
m_recognizers.push_front(
62-
{(uint32_t)m_recognizers.size(), false, recognizer, true, ConstString(),
63-
module, std::vector<ConstString>(), symbol, first_instruction_only});
61+
m_recognizers.push_front({(uint32_t)m_recognizers.size(), recognizer, true,
62+
ConstString(), module, std::vector<ConstString>(),
63+
symbol, first_instruction_only});
6464
}
6565

6666
void StackFrameRecognizerManager::ForEach(
@@ -90,9 +90,13 @@ bool StackFrameRecognizerManager::RemoveRecognizerWithID(
9090
uint32_t recognizer_id) {
9191
if (recognizer_id >= m_recognizers.size())
9292
return false;
93-
if (m_recognizers[recognizer_id].deleted)
93+
auto found =
94+
llvm::find_if(m_recognizers, [recognizer_id](const RegisteredEntry &e) {
95+
return e.recognizer_id == recognizer_id;
96+
});
97+
if (found == m_recognizers.end())
9498
return false;
95-
m_recognizers[recognizer_id].deleted = true;
99+
m_recognizers.erase(found);
96100
return true;
97101
}
98102

@@ -116,8 +120,6 @@ StackFrameRecognizerManager::GetRecognizerForFrame(StackFrameSP frame) {
116120
Address current_addr = frame->GetFrameCodeAddress();
117121

118122
for (auto entry : m_recognizers) {
119-
if (entry.deleted)
120-
continue;
121123
if (entry.module)
122124
if (entry.module != module_name)
123125
continue;

lldb/test/API/commands/frame/recognizer/TestFrameRecognizer.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,24 @@ def test_frame_recognizer_1(self):
4444

4545
self.runCmd("frame recognizer delete 0")
4646

47+
# Test that it deleted the recognizer with id 0.
4748
self.expect("frame recognizer list",
4849
substrs=['1: recognizer.MyOtherFrameRecognizer, module a.out, symbol bar (regexp)'])
50+
self.expect("frame recognizer list", matching=False,
51+
substrs=['MyFrameRecognizer'])
52+
53+
# Test that an invalid index and deleting the same index again
54+
# is an error and doesn't do any changes.
55+
self.expect("frame recognizer delete 2", error=True,
56+
substrs=["error: '2' is not a valid recognizer id."])
57+
self.expect("frame recognizer delete 0", error=True,
58+
substrs=["error: '0' is not a valid recognizer id."])
59+
# Recognizers should have the same state as above.
60+
self.expect("frame recognizer list",
61+
substrs=['1: recognizer.MyOtherFrameRecognizer, module a.out, symbol bar (regexp)'])
62+
self.expect("frame recognizer list", matching=False,
63+
substrs=['MyFrameRecognizer'])
64+
4965

5066
self.runCmd("frame recognizer clear")
5167

0 commit comments

Comments
 (0)