Skip to content

Commit 3328ee5

Browse files
committed
[lldb] Suppress persistent result when running po
Remove the persistent result variable after executing `po`. Without this change, the following behavior happens: ``` (lldb) p thing (NSObject *) $0 = 0x600000008000 (lldb) po thing <NSObject: 0x600000008000> (lldb) p thing (NSObject *) $2 = 0x600000008000 (lldb) p $1 (NSObject *) $1 = 0x600000008000 ``` Even though `po` hides the persistent result variable, it's still created - as $1 in this example. It can be accessed even though its existence is not evident. With this change, the persistent result is removed after the object description has printed. Instead, this is the behavior: ``` (lldb) p thing (NSObject *) $0 = 0x600000008000 (lldb) po thing <NSObject: 0x600000008000> (lldb) p thing (NSObject *) $1 = 0x600000008000 ``` The difference here is that the `po` doens't silently create a persistent result. Differential Revision: https://reviews.llvm.org/D144044
1 parent b3215c8 commit 3328ee5

File tree

4 files changed

+44
-0
lines changed

4 files changed

+44
-0
lines changed

lldb/source/Commands/CommandObjectExpression.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "lldb/Target/Process.h"
2222
#include "lldb/Target/StackFrame.h"
2323
#include "lldb/Target/Target.h"
24+
#include "lldb/lldb-private-enumerations.h"
2425

2526
using namespace lldb;
2627
using namespace lldb_private;
@@ -346,6 +347,9 @@ EvaluateExpressionOptions
346347
CommandObjectExpression::GetEvalOptions(const Target &target) {
347348
EvaluateExpressionOptions options;
348349
options.SetCoerceToId(m_varobj_options.use_objc);
350+
if (m_command_options.m_verbosity ==
351+
eLanguageRuntimeDescriptionDisplayVerbosityCompact)
352+
options.SetSuppressPersistentResult(m_varobj_options.use_objc);
349353
options.SetUnwindOnError(m_command_options.unwind_on_error);
350354
options.SetIgnoreBreakpoints(m_command_options.ignore_breakpoints);
351355
options.SetKeepInMemory(true);
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
OBJC_SOURCES := main.m
2+
3+
include Makefile.rules
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
"""
2+
Test behavior of `po` and persistent results.
3+
"""
4+
5+
import lldb
6+
from lldbsuite.test.lldbtest import *
7+
from lldbsuite.test import lldbutil
8+
9+
10+
class TestCase(TestBase):
11+
def setUp(self):
12+
TestBase.setUp(self)
13+
self.build()
14+
lldbutil.run_to_source_breakpoint(self, "break here", lldb.SBFileSpec("main.m"))
15+
16+
def test_po_does_not_print_persistent_result(self):
17+
"""Test `po` doesn't advertise a persistent result variable."""
18+
self.expect("po obj", matching=False, substrs=["$0 = "])
19+
20+
def test_po_does_not_keep_persistent_result(self):
21+
"""Test `po` doesn't leak a persistent result variable."""
22+
self.expect("po obj")
23+
# Verify `po` used a temporary persistent result. In other words, there
24+
# should be no $0 at this point.
25+
self.expect("expression $0", error=True)
26+
self.expect("expression obj", substrs=["$0 = "])
27+
28+
def test_expression_description_verbosity(self):
29+
"""Test printing object description _and_ opt-in to persistent results."""
30+
self.expect("expression -O -vfull -- obj", substrs=["$0 = "])
31+
self.expect("expression $0", substrs=["$0 = "])
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#import <objc/NSObject.h>
2+
3+
int main() {
4+
NSObject *obj = [NSObject new];
5+
return 0; // break here
6+
}

0 commit comments

Comments
 (0)