werat added a comment.
In D98370#2709828 <https://reviews.llvm.org/D98370#2709828>, @jingham wrote:
> Be careful here. There are really two kinds of persistent variables:
> "expression results" and variables created in the expression parser. The
> former are by design constant. The idea is that you can use them to
> checkpoint the state of a value and refer to it later. You can use their
> values in expressions, but they aren't supposed to be modifiable. Those are
> the ones called $NUM.
>
> The ones you make in an expression, like:
>
> (lldb) expr int $myVar = 20
>
> on the other hand are modifiable.
What about the values created via `SBValue::Persist()` then? They have names
like `$NUM`, but they can be either of the two you mentioned and more (values
created via `CreateValueFromData` or values acquired via `FindVariable`):
v = frame.EvaluateExpression("...") # `v` is "$0" -- it's an "expression
result" by your classification
vp = v.Persist() # `vp` is "$1" -- I assume it should point the same value
as "$0" and be non-modifiable
--
v = frame.EvaluateExpression("$myVar = 20") # `v` is "$0" -- it's an
"expression result" by your classification
vp = v.Persist() # `vp` is "$1" -- I assume it should point the same value
as "$0" and be non-modifiable
myVar = frame.EvaluateExpression("$myVar") # now `myVar` is "$myVar" -- it's
a "variables created in the expression parser"
myVarP= myVar.Persist() # `myVarP` is "$2" -- ?? Should it point the same
value as `myVar` and be modifiable?
--
v = target.CreateValueFromData(...)
vp = v.Persist() # `vp` is "$0" -- ?? Should it be modifiable? Should it
point to the original `v`?
------
I think at this point I should explain the problem I'm solving from the
beginning.
I have built an expression evaluator for LLDB (and based on LLDB) --
https://github.com/google/lldb-eval. It's much faster than LLDB's
`EvaluateExpression`, but has some limitations -- it doesn't support
user-defined function calls, doesn't allows to evaluate arbitrary C++ code, etc.
It is used in Stadia for Visual Studio debugger
(https://github.com/googlestadia/vsi-lldb) complementing LLDB. Expressions that
are not supported by `lldb-eval` are evaluated by `LLDB`, thus from user
perspective everything "just works". In some situations we need to maintain
some "state", which can be read/written by multiple consecutive expressions.
Simplified example:
EvaluateExpression("$index += 1");
v1 = EvaluateExpression("array[$index]")
EvaluateExpression("$index += 1");
v2 = EvaluateExpression("array[$index]")
In case of `LLDB` we create `$index` via something like `expr $index = 0` and
then the expressions can modify it. In `lldb-eval`, however, we don't want to
use LLDB's persistent variables, so the state is represented via regular map of
`SBValue` objects
(https://werat.dev/blog/blazing-fast-expression-evaluation-for-c-in-lldb/#maintaning-state).
Basically the API is something like this:
state = {"index": some_sbvalue}
EvaluateExpression("index += 1", state);
v1 = EvaluateExpression("array[index]", state)
EvaluateExpression("index += 1", state);
v2 = EvaluateExpression("array[index]", state)
some_sbvalue.GetValue() # == 2
But as I mentioned before, our debugger shell is "smart" and can fallback to
`LLDB` if `lldb-eval` fails to evaluate the expression. If there was a state
involved, it needs to be converted to LLDB's persistent variables. Right now we
workaround this issues by always allocating "state" values in LLDB
(https://github.com/googlestadia/vsi-lldb/blob/0fcbe30a498fac70230efdb815125ee5f6f087bb/YetiVSI/DebugEngine/NatvisEngine/NatvisExpressionEvaluator.cs#L315)
-- this way we don't need to convert it back. However it would be better to
convert only if needed and for that I was hoping to use `SBValue::Persist()`.
The example below doesn't work, but that's what I would like to fix (code is
simplified):
// We can assume here the result is created via something like
`CreateValueFromData()`
//
lldb::SBValue counter = lldb_eval::EvaluateExpression("10");
lldb_eval::ContextVariableList vars = { {"counter", &counter } };
while (counter.GetValueAsUnsigned() > 5) {
lldb_eval::EvaluateExpression("--counter", vars);
}
lldb::SBValue p = counter.Persist(); // Assume `p.GetName()` is "$1"
lldb::SBValue v1 = lldb::EvaluateExpression("$1"); // v1.GetValue() == 5
lldb::SBValue v2 = lldb::EvaluateExpression("--$1"); // v2.GetValue() == 4
Sorry for the long message, I hope it's more clear what I'm trying to do here :)
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D98370/new/
https://reviews.llvm.org/D98370
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits