This is an archive of the discontinued LLVM Phabricator instance.

Add dyld to sanitizer procmaps on darwin
ClosedPublic

Authored by fjricci on May 8 2017, 8:15 AM.

Details

Summary

Sanitizer procmaps uses dyld apis to iterate over the list of images
in the process. This is much more performan than manually recursing
over all of the memory regions in the process, however, dyld does
not report itself in the list of images. In order to prevent reporting
leaks from dyld globals and to symbolize dyld functions in stack traces,
this patch special-cases dyld and ensures that it is added to the
list of modules.

This is accomplished by recursing through the memory map of the process
until a dyld Mach header is found. While this recursion is expensive,
it is run before the full set of images has been loaded in the process,
so only a few calls are required. The result is cached so that it never
needs to be searched for when the full process memory map exists, as this
would be incredibly slow, on the order of minutes for leak sanitizer with
only 25 or so libraries loaded.

Diff Detail

Repository
rL LLVM

Event Timeline

fjricci created this revision.May 8 2017, 8:15 AM
fjricci edited the summary of this revision. (Show Details)May 8 2017, 8:15 AM
fjricci updated this revision to Diff 98172.May 8 2017, 8:22 AM

Small refactor

fjricci updated this revision to Diff 98175.May 8 2017, 8:32 AM

Consolidate diff a bit

alekseyshl added inline comments.May 8 2017, 2:13 PM
lib/sanitizer_common/sanitizer_procmaps_mac.cc
235 ↗(On Diff #98175)

Shouldn't we check err == KERN_SUCCESS before accessing vm_region_recurse_64 results?

237 ↗(On Diff #98175)

This means that dyld_hdr at some point contains a pointer to something other than dyld and might even stay that way if something goes wrong in this loop.

250 ↗(On Diff #98175)

How about using local static var initialization?

static const struct mach_header *get_dyld_hdr() {
  static struct mach_header *header = get_dyld_image_header();
  return header;
}

and then use get_dyld_hdr() everywhere instead of dyld_hdr and get_dyld_image_header()?

fjricci updated this revision to Diff 98316.May 9 2017, 9:52 AM

Use function to wrap dyld header static var and check for recurse error

alekseyshl accepted this revision.May 9 2017, 3:56 PM
This revision is now accepted and ready to land.May 9 2017, 3:56 PM
This revision was automatically updated to reflect the committed changes.
fjricci reopened this revision.May 10 2017, 9:48 AM

Looks like we can't use the wrapper function for the static variable, because we don't always have access to the __cxa_guard functions. I reverted the commit for now, but I think the solution is to move the cached dyld header back to a static global var.

This revision is now accepted and ready to land.May 10 2017, 9:48 AM

Looks like we can't use the wrapper function for the static variable, because we don't always have access to the __cxa_guard functions. I reverted the commit for now, but I think the solution is to move the cached dyld header back to a static global var.

Right... I'd still keep the current code structure though, replace local static header var with static global, that's it.

fjricci updated this revision to Diff 98485.May 10 2017, 10:16 AM

Use static global to avoid use of cxa guard

This revision was automatically updated to reflect the committed changes.