Skip to content

Commit c848250

Browse files
committed
Improve the data formatter UX if an array is uninitialized.
Global variables in Swift are lazy initialized and often zeroed out before the first access. This can be confusing to users, so this patch modifies the array dataformatter to recognize a null array. rdar://132736658
1 parent 37a037b commit c848250

File tree

5 files changed

+35
-6
lines changed

5 files changed

+35
-6
lines changed

lldb/source/Plugins/Language/Swift/SwiftArray.cpp

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ SwiftArrayNativeBufferHandler::SwiftArrayNativeBufferHandler(
114114
}
115115

116116
bool SwiftArrayNativeBufferHandler::IsValid() {
117-
return m_metadata_ptr != LLDB_INVALID_ADDRESS &&
117+
return m_metadata_ptr != LLDB_INVALID_ADDRESS && m_metadata_ptr &&
118118
m_first_elem_ptr != LLDB_INVALID_ADDRESS && m_capacity >= m_size &&
119119
m_elem_type.IsValid();
120120
}
@@ -437,10 +437,7 @@ SwiftArrayBufferHandler::CreateBufferHandler(ValueObject &static_valobj) {
437437
handler.reset(new SwiftArrayBridgedBufferHandler(
438438
process_sp, masked_storage_location));
439439
}
440-
441-
if (handler && handler->IsValid())
442-
return handler;
443-
return nullptr;
440+
return handler;
444441
} else {
445442
CompilerType elem_type(
446443
valobj.GetCompilerType().GetArrayElementType(exe_scope));
@@ -457,6 +454,12 @@ bool lldb_private::formatters::swift::Array_SummaryProvider(
457454
if (!handler)
458455
return false;
459456

457+
if (!handler->IsValid()) {
458+
// FIXME: This should be an out-of-band llvm::Error return value.
459+
stream << "<uninitialized>";
460+
return true;
461+
}
462+
460463
auto count = handler->GetCount();
461464

462465
stream.Printf("%zu value%s", count, (count == 1 ? "" : "s"));
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
SWIFT_SOURCES := main.swift
2+
SWIFTFLAGS_EXTRAS := -parse-as-library
3+
include Makefile.rules
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import lldb
2+
from lldbsuite.test.decorators import *
3+
import lldbsuite.test.lldbtest as lldbtest
4+
import lldbsuite.test.lldbutil as lldbutil
5+
6+
7+
class TestSwiftArrayUninitialized(lldbtest.TestBase):
8+
@swiftTest
9+
def test(self):
10+
"""Test unitialized global arrays"""
11+
self.build()
12+
lldbutil.run_to_source_breakpoint(
13+
self, 'break here', lldb.SBFileSpec('main.swift'))
14+
self.expect("target variable -- array_unused", substrs=['<uninitialized>'])
15+
self.expect("target variable -- array_used_empty", substrs=['0 values'])
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
var array_unused : [Int] = [1,2,3]
2+
var array_used_empty : [Int] = []
3+
@main struct Main {
4+
static func main() {
5+
print(array_used_empty)
6+
print("break here")
7+
}
8+
}

lldb/test/API/lang/swift/nsarray_code_running_formatter/main.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ func main() {
2323
var tb = Test() as Array + []
2424

2525
print("second stop") //% self.expect('frame variable -d run -- t', substrs=['t = 0x', 'NSArray = {', 'NSObject = {'])
26-
//% self.expect('frame variable -d run -- ta', substrs=['ta = {', '_buffer = {', '_storage =', 'rawValue = 0x'])
26+
//% self.expect('frame variable -d run -- ta', substrs=['ta = <uninitialized>', '_buffer = {', '_storage =', 'rawValue = 0x'])
2727
//% self.expect('frame variable -d run -- tb', substrs=['tb = 1 value {', '"abc"'])
2828
//% self.expect('po t', substrs=['0 : abc'])
2929
//% self.expect('po ta', substrs=['0 : abc'])

0 commit comments

Comments
 (0)