This is an archive of the discontinued LLVM Phabricator instance.

Add MemoryMappedSection struct for two-level memory map iteration
ClosedPublic

Authored by fjricci on Jul 14 2017, 10:24 AM.

Details

Summary

This will allow sanitizer_procmaps on mac to expose section information.

Only scan global sections containing data in LSan on darwin

__DATA segments on Darwin contain a large number of separate sections,
many of which cannot actually contain pointers, and contain const values or
objc metadata. Not scanning sections which cannot contain pointers significantly
improves performance.

On a medium-sized (~4000 files) internal project, I saw a speedup of about 30%
in standalone LSan's execution time (30% improvement in the time spent running
LSan, not the total program time).

Diff Detail

Repository
rL LLVM

Event Timeline

fjricci created this revision.Jul 14 2017, 10:24 AM
fjricci updated this revision to Diff 106660.Jul 14 2017, 10:25 AM

Fix a typo

alekseyshl added inline comments.Jul 14 2017, 1:57 PM
lib/sanitizer_common/sanitizer_procmaps.h
67 ↗(On Diff #106660)

Is it possible to drop has_sections and MemoryMappedSection, and add the current section info right here, under #if MAC? No other but Mac specific code will need to be changed.

If it turns out to be beneficial to have MemoryMappedSection defined, well, maybe define it inside the MemoryMappedSegment, under the same #if and call it just Segment?

That would lead to a platform specific function AddSegmentAddressRange(MemoryMappedSegment *segment, LoadedModule *module); and all the Mac specific stuff will be contained in _mac files.

What do you think? It's totally possible I miss some details precluding us from doing so.

fjricci added inline comments.Jul 14 2017, 2:15 PM
lib/sanitizer_common/sanitizer_procmaps.h
67 ↗(On Diff #106660)

Hmm, I'm not sure I completely understand what you mean. The reason why the MemoryMappedSection is a separate struct is because each MemoryMappedSegment will have multiple MemoryMappedSection's (at least on Darwin), so there isn't a 1:1 correspondence. The MemoryMappedSection is also quite a bit lighter-weight/smaller than using a full MemoryMappedSegment struct for each section.

I'm alright with moving Section inside of MemoryMappedSegment.

I thought about making the MemoryMappedSection Darwin-specific (and I'm still open to it), but that will cause issues if we ever end up with non-platform specific code that needs to iterate at the level of a section (something like tsan etc). I *think* that this shouldn't ever happen, because any code that can tell the difference between a section and a segment will probably be mac-specific code by definition.

fjricci added inline comments.Jul 14 2017, 2:26 PM
lib/sanitizer_common/sanitizer_procmaps.h
67 ↗(On Diff #106660)

Ahh, there's another piece I forgot about in terms of has_section. The original reason why I added it is that not all Darwin segments contain sections, and in the case where there are no sections, you need to use the address range for the segment itself. So even if we move things into darwin-specific ifdefs, we'll still need has_section.

fjricci updated this revision to Diff 106722.Jul 14 2017, 3:33 PM

Address comments and remove MemoryMappedSection class

fjricci updated this revision to Diff 106723.Jul 14 2017, 3:42 PM

Fix whitespace

alekseyshl accepted this revision.Jul 14 2017, 4:16 PM

Looks good, thank you!

lib/sanitizer_common/sanitizer_procmaps.h
60 ↗(On Diff #106723)

Move private under #if

This revision is now accepted and ready to land.Jul 14 2017, 4:16 PM
fjricci added inline comments.Jul 14 2017, 4:21 PM
lib/sanitizer_common/sanitizer_procmaps.h
60 ↗(On Diff #106723)

Unfortunately, the linter complains if you don't have a blank line before private. It looks a bit odd to me to have:

#if SANITIZER_MAC

private:
  friend class MemoryMappingLayout;

What do you think?

alekseyshl added inline comments.Jul 14 2017, 4:46 PM
lib/sanitizer_common/sanitizer_procmaps.h
60 ↗(On Diff #106723)

It's fine with me, it's better than NOLINT comment or private: outside of the #if

fjricci added inline comments.Jul 14 2017, 5:11 PM
lib/sanitizer_common/sanitizer_procmaps.h
60 ↗(On Diff #106723)

Sounds good.

This revision was automatically updated to reflect the committed changes.
MatzeB added a subscriber: MatzeB.Jul 18 2017, 3:56 PM

Various greendragon builds started to timeout when running unittests after this commit. Any idea what causes this? Should we revert the commit to bring the builders back?

Example: http://lab.llvm.org:8080/green/job/clang-stage2-configure-Rlto_check/17551/console

...
PASS: AddressSanitizer-x86_64-darwin :: TestCases/Darwin/dump_registers.cc (911 of 2593)
Build timed out (after 45 minutes). Marking the build as aborted.
Set build name.
New build name is 'r308348 (#17551)'
Variable with name 'BUILD_DISPLAY_NAME' already exists, current value: 'r308348 (#17551)', new value: 'r308348 (#17551)'
Build was aborted
Recording test results
ERROR: Step ‘Publish JUnit test result report’ failed: No test report files were found. Configuration error?

Interesting to me that this would cause timeouts, but yeah, I'll revert and look into it.

fjricci reopened this revision.EditedJul 18 2017, 4:52 PM

Reverted as rL308394 and rL308395

This revision is now accepted and ready to land.Jul 18 2017, 4:52 PM

Reverted as rL308394 and rL308395

Thank you!

fjricci updated this revision to Diff 107340.Jul 19 2017, 10:37 AM

Fix 10.11 buildbots by masking dyld section addresses

This is already done for segment vmaddr's and needs to be done for sections as well

fjricci requested review of this revision.Jul 19 2017, 10:37 AM
fjricci edited edge metadata.
fjricci updated this revision to Diff 107545.Jul 20 2017, 10:31 AM
fjricci edited the summary of this revision. (Show Details)
fjricci removed a subscriber: MatzeB.

Use blacklist instead of whitelist

fjricci updated this revision to Diff 107548.Jul 20 2017, 10:33 AM

Remove accidental arcanist squash

This revision was automatically updated to reflect the committed changes.
kcc added inline comments.Jul 20 2017, 11:09 AM
lib/sanitizer_common/sanitizer_procmaps.h
60 ↗(On Diff #107548)

Folks, please avoid ifdefs like this.
I'd appreciate if you can refactor the code to get rid of this ifdef (e.g move stuff to a separate file)

fjricci added inline comments.Jul 20 2017, 11:14 AM
lib/sanitizer_common/sanitizer_procmaps.h
60 ↗(On Diff #107548)

This file already has quite a few OS-based #ifdefs in it (which is why I didn't think adding another would be problematic). Is it worth trying to refactor in a way that they all go away, or just this one in particular?

kcc added inline comments.Jul 20 2017, 11:52 AM
lib/sanitizer_common/sanitizer_procmaps.h
60 ↗(On Diff #107548)

already has quite a few OS-based #ifdefs

Not too many in fact.
And when there are N bad things in a file it's not always an excuse to add (N+1)-th

Is it worth trying to refactor in a way that they all go away

Yes, please. It's the same amount of work anyway.
E.g. declare a private object

MemoryMappingLayoutRep *rep

and implement MemoryMappingLayoutRep in OS-specific files.

fjricci added inline comments.Jul 20 2017, 11:56 AM
lib/sanitizer_common/sanitizer_procmaps.h
60 ↗(On Diff #107548)

Makes sense. Will work on this. I wonder if we could get things to a point where we started enforcing lint rules against platform-specific ifdefs (unless some are actually unavoidable).