aboutsummaryrefslogtreecommitdiff
path: root/lldb/source/Commands/CommandObjectWatchpoint.cpp
diff options
context:
space:
mode:
authorMed Ismail Bennani <ismail@bennani.ma>2023-06-07 16:51:45 -0700
committerMed Ismail Bennani <ismail@bennani.ma>2023-06-07 16:52:11 -0700
commit0dd62ace2ee2fafcb9a08953db1b9e4e20428e28 (patch)
treeb80d2cdf645d102a3b2eab5d38510c1b4f665a50 /lldb/source/Commands/CommandObjectWatchpoint.cpp
parent94e75469597f197f9c4b45baa6c8a576c78dbd02 (diff)
downloadllvm-0dd62ace2ee2fafcb9a08953db1b9e4e20428e28.zip
llvm-0dd62ace2ee2fafcb9a08953db1b9e4e20428e28.tar.gz
llvm-0dd62ace2ee2fafcb9a08953db1b9e4e20428e28.tar.bz2
[lldb] Disable variable watchpoints when going out of scope
If we use a variable watchpoint with a condition using a scope variable, if we go out-of-scope, the watpoint remains active which can the expression evaluator to fail to parse the watchpoint condition (because of the missing varible bindings). This was discovered after `watchpoint_callback.test` started failing on the green dragon bot. This patch should address that issue by setting an internal breakpoint on the return addresss of the current frame when creating a variable watchpoint. The breakpoint has a callback that will disable the watchpoint if the the breakpoint execution context matches the watchpoint execution context. This is only enabled for local variables. This patch also re-enables the failing test following e1086384e584. rdar://109574319 Differential Revision: https://reviews.llvm.org/D151366 Signed-off-by: Med Ismail Bennani <ismail@bennani.ma>
Diffstat (limited to 'lldb/source/Commands/CommandObjectWatchpoint.cpp')
-rw-r--r--lldb/source/Commands/CommandObjectWatchpoint.cpp37
1 files changed, 22 insertions, 15 deletions
diff --git a/lldb/source/Commands/CommandObjectWatchpoint.cpp b/lldb/source/Commands/CommandObjectWatchpoint.cpp
index b73c9a2..a4929ea 100644
--- a/lldb/source/Commands/CommandObjectWatchpoint.cpp
+++ b/lldb/source/Commands/CommandObjectWatchpoint.cpp
@@ -9,6 +9,7 @@
#include "CommandObjectWatchpoint.h"
#include "CommandObjectWatchpointCommand.h"
+#include <memory>
#include <vector>
#include "llvm/ADT/StringRef.h"
@@ -20,6 +21,7 @@
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandOptionArgumentTable.h"
#include "lldb/Interpreter/CommandReturnObject.h"
+#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/Variable.h"
#include "lldb/Symbol/VariableList.h"
#include "lldb/Target/StackFrame.h"
@@ -950,27 +952,32 @@ protected:
error.Clear();
WatchpointSP watch_sp =
target->CreateWatchpoint(addr, size, &compiler_type, watch_type, error);
- if (watch_sp) {
- watch_sp->SetWatchSpec(command.GetArgumentAtIndex(0));
- watch_sp->SetWatchVariable(true);
- if (var_sp && var_sp->GetDeclaration().GetFile()) {
+ if (!watch_sp) {
+ result.AppendErrorWithFormat(
+ "Watchpoint creation failed (addr=0x%" PRIx64 ", size=%" PRIu64
+ ", variable expression='%s').\n",
+ addr, static_cast<uint64_t>(size), command.GetArgumentAtIndex(0));
+ if (const char *error_message = error.AsCString(nullptr))
+ result.AppendError(error_message);
+ return result.Succeeded();
+ }
+
+ watch_sp->SetWatchSpec(command.GetArgumentAtIndex(0));
+ watch_sp->SetWatchVariable(true);
+ if (var_sp) {
+ if (var_sp->GetDeclaration().GetFile()) {
StreamString ss;
// True to show fullpath for declaration file.
var_sp->GetDeclaration().DumpStopContext(&ss, true);
watch_sp->SetDeclInfo(std::string(ss.GetString()));
}
- output_stream.Printf("Watchpoint created: ");
- watch_sp->GetDescription(&output_stream, lldb::eDescriptionLevelFull);
- output_stream.EOL();
- result.SetStatus(eReturnStatusSuccessFinishResult);
- } else {
- result.AppendErrorWithFormat(
- "Watchpoint creation failed (addr=0x%" PRIx64 ", size=%" PRIu64
- ", variable expression='%s').\n",
- addr, (uint64_t)size, command.GetArgumentAtIndex(0));
- if (error.AsCString(nullptr))
- result.AppendError(error.AsCString());
+ if (var_sp->GetScope() == eValueTypeVariableLocal)
+ watch_sp->SetupVariableWatchpointDisabler(m_exe_ctx.GetFrameSP());
}
+ output_stream.Printf("Watchpoint created: ");
+ watch_sp->GetDescription(&output_stream, lldb::eDescriptionLevelFull);
+ output_stream.EOL();
+ result.SetStatus(eReturnStatusSuccessFinishResult);
return result.Succeeded();
}