[Lldb-commits] [lldb] Don't cause a premature UpdateIfNeeded when checking in SBValue::GetSP (PR #80222)
via lldb-commits
lldb-commits at lists.llvm.org
Wed Jan 31 16:27:29 PST 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-lldb
Author: None (jimingham)
<details>
<summary>Changes</summary>
Don't cause a premature UpdateIfNeeded when checking whether an otherwise invalid SBValue with a useful error should be handed out from GetSP.
This is a follow-on to e8a2fd5e7be2. In that change, I used GetError to check for an error at the beginning of GetSP, before checking for a valid Target or a stopped Process. But GetError calls UpdateIfNeeded. Normally that's not a problem as somewhere along UpdateIfNeeded the code will realize it can't update and return w/o doing any harm.
But when running lldb in a multithreaded environment (e.g. in Xcode) if you are very unlucky you can get the update to start before you proceed and then just stall waiting to get access to gdb-remote while the process is running.
The change is to add ValueObject::CheckError that returns the error w/o UpdatingIfNeeded, and use that in SBValue::GetSP in the places where we would normally return an invalid SP.
I tried to make a test for this but it's unobservable unless you are very unlucky, and I couldn't figure out a way to be consistently unlucky.
---
Full diff: https://github.com/llvm/llvm-project/pull/80222.diff
2 Files Affected:
- (modified) lldb/include/lldb/Core/ValueObject.h (+5)
- (modified) lldb/source/API/SBValue.cpp (+11-6)
``````````diff
diff --git a/lldb/include/lldb/Core/ValueObject.h b/lldb/include/lldb/Core/ValueObject.h
index 4c0b0b2dae6cd..db8023618b7f6 100644
--- a/lldb/include/lldb/Core/ValueObject.h
+++ b/lldb/include/lldb/Core/ValueObject.h
@@ -458,7 +458,12 @@ class ValueObject {
virtual bool GetDeclaration(Declaration &decl);
// The functions below should NOT be modified by subclasses
+ // This gets the current error for this ValueObject, it may update the value
+ // to ensure that the error is up to date.
const Status &GetError();
+
+ // Check the current error state without updating the value:
+ const Status &CheckError() { return m_error; }
ConstString GetName() const { return m_name; }
diff --git a/lldb/source/API/SBValue.cpp b/lldb/source/API/SBValue.cpp
index 89d26a1fbe282..182ae669d880b 100644
--- a/lldb/source/API/SBValue.cpp
+++ b/lldb/source/API/SBValue.cpp
@@ -114,13 +114,12 @@ class ValueImpl {
lldb::ValueObjectSP value_sp = m_valobj_sp;
Target *target = value_sp->GetTargetSP().get();
- // If this ValueObject holds an error, then it is valuable for that.
- if (value_sp->GetError().Fail())
- return value_sp;
-
- if (!target)
+ if (!target) {
+ // If we can't get the target, the error might still be useful:
+ if (value_sp->CheckError().Fail())
+ return value_sp;
return ValueObjectSP();
-
+ }
lock = std::unique_lock<std::recursive_mutex>(target->GetAPIMutex());
ProcessSP process_sp(value_sp->GetProcessSP());
@@ -128,7 +127,13 @@ class ValueImpl {
// We don't allow people to play around with ValueObject if the process
// is running. If you want to look at values, pause the process, then
// look.
+ // However, if this VO already had an error, then that is worth showing
+ // the user. However, we can't update it so use CheckError not GetError.
error.SetErrorString("process must be stopped.");
+
+ if (value_sp->CheckError().Fail())
+ return value_sp;
+
return ValueObjectSP();
}
``````````
</details>
https://github.com/llvm/llvm-project/pull/80222
More information about the lldb-commits
mailing list