This is an archive of the discontinued LLVM Phabricator instance.

[UBSan] Allow UBSan location to store frames returned by symbolizer.
ClosedPublic

Authored by samsonov on Feb 10 2015, 6:12 PM.

Details

Summary

__ubsan::getFunctionLocation() used to issue a call to symbolizer, and
convert the result (SymbolizedStack) to one of UBSan structures:
SourceLocation, ModuleLocation or MemoryLocation. This:
(1) is inefficient: we do an extra allocation/deallocation to copy data,
while we can instead can just pass SymbolizedStack around (which
contains all the necessary data).
(2) leaks memory: strings stored in SourceLocation/MemoryLocation are
never deallocated, and Filipe Cabecinhas suggests this causes crashes
of UBSan-ified programs in the wild.

Instead, let Location store a pointer to SymbolizedStack object, and
make sure it's properly deallocated when UBSan handler exits.

ModuleLocation is made obsolete by this change, and is deleted.

Diff Detail

Repository
rL LLVM

Event Timeline

samsonov updated this revision to Diff 19726.Feb 10 2015, 6:12 PM
samsonov retitled this revision from to [UBSan] Allow UBSan location to store frames returned by symbolizer..
samsonov updated this object.
samsonov edited the test plan for this revision. (Show Details)
samsonov added reviewers: rsmith, filcab.
samsonov added a subscriber: Unknown Object (MLST).
filcab edited edge metadata.Feb 10 2015, 6:35 PM

LGTM with the call to InternalFree.

lib/ubsan/ubsan_diag.h
29 ↗(On Diff #19726)

Aren't we still leaking the SymbolizedStack object, here? (as well as in the destructor and reset() (which call clear()))
I guess we're missing a call to InternalFree()

samsonov added inline comments.Feb 10 2015, 7:18 PM
lib/ubsan/ubsan_diag.h
29 ↗(On Diff #19726)

SymbolizedStack::ClearAll() calls InternalFree(this), so it shouldn't be necessary.

Ah, yes. Thanks.

Although, wouldn't calling free() on the this pointer be undefined behavior? After we (conceptually) return from InternalFree, we have an invalid this pointer. Wouldn't this be UB? We're not calling methods on it, but we end up inside a member function (however briefly) with an invalid this pointer.

I couldn't find it in the standard, but I'm sure @rsmith knows the answer :-)

"delete this" is a common pattern and I believe we're fine here provided we're careful enough and don't access the object after InternalFree() statement.

This revision was automatically updated to reflect the committed changes.