This is an archive of the discontinued LLVM Phabricator instance.

[lldb/Core] Fix incomplete type variable dereferencing crash.
ClosedPublic

Authored by mib on Jul 7 2020, 10:38 AM.

Details

Reviewers
jingham
labath
Summary

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>

Diff Detail

Event Timeline

mib created this revision.Jul 7 2020, 10:38 AM
JDevlieghere added inline comments.
lldb/source/Core/ValueObject.cpp
691

Style-nit: I think few people love early returns a much as I do, but here I think the llvm-way of checking a pointer is would be preferable over a very-late-early-exit:

if (auto* synth_valobj = GetSyntheticValue()) {
  valobj =
        synth_valobj->GetChildAtIndex(synthetic_index, synthetic_array_member)
            .get();
}

Additionally, I'm not sure if this should be auto according to the LLVM coding rules.

davide added a subscriber: davide.Jul 7 2020, 10:50 AM

Aside from cosmetics, I'm not entirely sure this is the correct fix. Why are we calling this code _at all_ if the type is incomplete?

Aside from cosmetics, I'm not entirely sure this is the correct fix. Why are we calling this code _at all_ if the type is incomplete?

Doing so allows one to write a synthetic child provider that provides the fields for an incomplete type. This is useful if you don't have debug info for a given type but know its layouts by some other means.

mib added a comment.Jul 7 2020, 11:05 AM

Aside from cosmetics, I'm not entirely sure this is the correct fix. Why are we calling this code _at all_ if the type is incomplete?

The code is called because some incomplete types can actually be typedefs. In this case, we use the pointee type to create the ValueObject child (in ValueObject::CreateChildAtIndex)

It sounds like that would be worth adding as a comment.

Aside from cosmetics, I'm not entirely sure this is the correct fix. Why are we calling this code _at all_ if the type is incomplete?

Doing so allows one to write a synthetic child provider that provides the fields for an incomplete type. This is useful if you don't have debug info for a given type but know its layouts by some other means.

Interesting, thanks. Do we have an example of when this triggers?

mib updated this revision to Diff 276152.Jul 7 2020, 11:27 AM
  • Addressed style comment.
  • Added a comment to give more context.
mib added a comment.Jul 7 2020, 11:33 AM

Aside from cosmetics, I'm not entirely sure this is the correct fix. Why are we calling this code _at all_ if the type is incomplete?

Doing so allows one to write a synthetic child provider that provides the fields for an incomplete type. This is useful if you don't have debug info for a given type but know its layouts by some other means.

Interesting, thanks. Do we have an example of when this triggers?

This change was first introduced by D79554, with the CFDictionaryRef formatter. They reused the same logic as NSCFDictionary but needed this to generate the ValueObject's children.

jingham accepted this revision.Jul 7 2020, 11:33 AM

Other than a quibble about using _sp suffix, this is fine.

lldb/source/Core/ValueObject.cpp
693

We usually use _sp suffix for shared pointers.

This revision is now accepted and ready to land.Jul 7 2020, 11:33 AM
mib updated this revision to Diff 276157.Jul 7 2020, 11:36 AM
  • Addressed Jim's comment.
mib closed this revision.Jul 7 2020, 11:41 AM

Patch landed in 7177e63fb554 !

labath added a comment.Jul 8 2020, 4:28 AM

Thanks for fixing this.

lldb/source/Core/ValueObject.cpp
690

Sorry for the pedantry, but the wording "LLDB will try to ..." makes me think that there is some other part of lldb which "tries to use the synthetic value", and this code is somehow responding to that behavior.
But IIUC, this *is* the code which is using the synthetic value. In that case, it would be enough to say "In case of an incomplete type, try to use the synthetic value to ...".

mib marked 3 inline comments as done.Jul 8 2020, 5:04 AM
lldb/test/API/functionalities/target_var/TestTargetVar.py