[lldb/Core] Fix crash in ValueObject::CreateChildAtIndex

The patch fixes a crash in ValueObject::CreateChildAtIndex caused by a
null pointer dereferencing. This is a corner case that is happening when
trying to dereference a variable with an incomplete type, and this same
variable doesn't have a synthetic value to get the child ValueObject.

If this happens, lldb will now return a null pointer that will results
in an error message.

rdar://65181171

Signed-off-by: Med Ismail Bennani <medismail.bennani@gmail.com>
This commit is contained in:
Med Ismail Bennani 2020-07-07 18:45:30 +02:00
parent 9dfea03517
commit 7177e63fb5
6 changed files with 20 additions and 56 deletions

View File

@ -687,10 +687,15 @@ ValueObject *ValueObject::CreateChildAtIndex(size_t idx,
language_flags);
}
if (!valobj && synthetic_array_member)
valobj = GetSyntheticValue()
// In case of an incomplete type, LLDB will try to use the ValueObject's
// synthetic value to create the child ValueObject.
if (!valobj && synthetic_array_member) {
if (ValueObjectSP synth_valobj_sp = GetSyntheticValue()) {
valobj = synth_valobj_sp
->GetChildAtIndex(synthetic_index, synthetic_array_member)
.get();
}
}
return valobj;
}

View File

@ -1,5 +1,3 @@
include Makefile.rules
C_SOURCES := main.c
a.out: globals.ll
$(CC) $(CFLAGS) -g -c $^ -o globals.o
$(LD) $(LDFLAGS) -g globals.o -o $@
include Makefile.rules

View File

@ -20,3 +20,5 @@ class targetCommandTestCase(TestBase):
self.build()
lldbutil.run_to_name_breakpoint(self, 'main')
self.expect("target variable i", substrs=['i', '42'])
self.expect("target variable var", patterns=['\(incomplete \*\) var = 0[xX](0)*dead'])
self.expect("target variable var[0]", error=True, substrs=["can't find global variable 'var[0]'"])

View File

@ -1,6 +0,0 @@
int i = 42;
int *p = &i;
int main() {
return *p;
}

View File

@ -1,42 +0,0 @@
source_filename = "globals.c"
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-apple-macosx10.14.0"
@i = global i32 42, align 4
@p = global i32* @i, align 8, !dbg !0, !dbg !6
; Function Attrs: noinline nounwind optnone ssp uwtable
define i32 @main() #0 !dbg !15 {
entry:
%retval = alloca i32, align 4
store i32 0, i32* %retval, align 4
%0 = load i32*, i32** @p, align 8, !dbg !18
%1 = load i32, i32* %0, align 4, !dbg !18
ret i32 %1, !dbg !18
}
attributes #0 = { noinline nounwind optnone ssp uwtable }
!llvm.dbg.cu = !{!2}
!llvm.module.flags = !{!10, !11, !12, !13}
!llvm.ident = !{!14}
!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression(DW_OP_deref))
!1 = distinct !DIGlobalVariable(name: "i", scope: !2, file: !3, line: 1, type: !9, isLocal: false, isDefinition: true)
!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, emissionKind: FullDebug, globals: !5)
!3 = !DIFile(filename: "globals.c", directory: "/")
!4 = !{}
!5 = !{!0, !6}
!6 = !DIGlobalVariableExpression(var: !7, expr: !DIExpression())
!7 = distinct !DIGlobalVariable(name: "p", scope: !2, file: !3, line: 2, type: !8, isLocal: false, isDefinition: true)
!8 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !9, size: 64)
!9 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
!10 = !{i32 2, !"Dwarf Version", i32 4}
!11 = !{i32 2, !"Debug Info Version", i32 3}
!12 = !{i32 1, !"wchar_size", i32 4}
!13 = !{i32 7, !"PIC Level", i32 2}
!14 = !{!"clang version 8.0.0 (trunk 340838) (llvm/trunk 340843)"}
!15 = distinct !DISubprogram(name: "main", scope: !3, file: !3, line: 4, type: !16, isLocal: false, isDefinition: true, scopeLine: 4, isOptimized: false, unit: !2, retainedNodes: !4)
!16 = !DISubroutineType(types: !17)
!17 = !{!9}
!18 = !DILocation(line: 5, scope: !15)

View File

@ -0,0 +1,7 @@
int i = 42;
int *p = &i;
struct incomplete;
struct incomplete *var = (struct incomplete *)0xdead;
int main() { return *p; }