New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[SR-9194] expression evaluation permanently retains objects #4350
Comments
jingham@apple.com (JIRA User), you have a dup of this, right? Or is it just a Radar? |
Comment by Jim Ingham (JIRA) I just have a Radar, I linked it to this JIRA. |
Comment by Jim Ingham (JIRA) This isn't terribly important, but SetSuppressPersistentResult doesn't cause a result for the expression not to be produced, all it means is that the name isn't added to the list of known result names for use in future expressions. We still produce the result, and in the case of "po" we need too since we call description on the result as a second step. The name of the variable that is produced is the one it would have had, but if you try to use that name in a future expression you will get an error. This is a C example, but Swift is the same: (lldb) script
>>> options = lldb.SBExpressionOptions()
>>> options.SetSuppressPersistentResult(True)
>>> value = lldb.frame.EvaluateExpression('printf("Hello there")', options)
>>> print value.GetError().Success()
True
>>> print value.GetName()
$0
>>> print value.GetValueAsUnsigned()
11
>>> quit
(lldb) expr $0 + 11
error: use of undeclared identifier '$0' The "result variables" in lldb are constant objects that we store on the lldb side, and re-inject as values if they are needed in subsequent expressions. So suppressing them is just about removing the accounting on lldb's side. Anyway, the code that is retaining the result object is actually part of the expression wrapper that we compile and run to implement calling your expression. We capture the result of the expression by assigning it to a known variable which we read once the expression is over. When we do that swift inserts a retain. What we should really do is to figure out how to capture the result w/o retaining it. That's probably not too hard if the result is a reference to an object. But would be tricky, for instance if the expression was a function call that returned an unretained object, since that might go away at the end of the expression evaluation before we could get our hands on it. I'm actually not sure of an easy way to fix this. |
Thanks for the helpful clarifications! |
Additional Detail from JIRA
md5: eb0ae1889a3f14e971850fa9bde9e1b2
Issue Description:
When evaluating an expression that returns an object, the object will be permanently retained. This is true both using the
expression
command and usingSBFrame.EvaluateExpression()
. From the perspective of usingpo
, this was quite the surprise.My guess is that this is because of persistent variables. I tried to see if this could be worked around using Python, but the following did not work:
The output of
value.path
is$Rn
. So it appears this may not actually be suppressing the persistent variable. This may be a separate but related bug.If this is caused by persistent variables, note that
po
does not print the name of the persistent variable that was created. Which leads to a question: shouldpo
always print the name of the persistent variables created, or shouldpo
always disable persistent variables?The text was updated successfully, but these errors were encountered: