This is an archive of the discontinued LLVM Phabricator instance.

[sanitizer] Track architecture and UUID of modules in LoadedModule
ClosedPublic

Authored by kubamracek on Nov 14 2016, 1:02 PM.

Details

Summary

When we enumerate loaded modules, we only track the module name and base address, which then has several problems on macOS. Dylibs and executables often have several architecture slices and not storing which architecture/UUID is actually loaded creates problems with symbolication: A file path + offset isn't enough to correctly symbolicate, since the offset can be valid in multiple slices. This is especially common for Haswell+ X86_64 machines, where x86_64h slices are preferred, but if one is not available, a regular x86_64 is loaded instead. But the same issue exists for i386 vs. x86_64 as well.

This patch adds tracking of arch and UUID for each LoadedModule. At this point, this information isn't used in reports, but this is the first step. The goal is to correctly identify which slice is loaded in symbolication, and also to output this information in reports so that we can tell which exact slices were loaded in post-mortem analysis.

Diff Detail

Repository
rL LLVM

Event Timeline

kubamracek updated this revision to Diff 77867.Nov 14 2016, 1:02 PM
kubamracek retitled this revision from to [sanitizer] Track architecture and UUID of modules in LoadedModule.
kubamracek updated this object.
kubamracek added reviewers: dvyukov, kcc, zaks.anna, eugenis.
kubamracek set the repository for this revision to rL LLVM.
kubamracek added a project: Restricted Project.
kubamracek added a subscriber: llvm-commits.
zaks.anna edited edge metadata.Nov 17 2016, 4:29 PM

Could you add a test at least for the architecture or will you be testing this in subsequent patches?

lib/sanitizer_common/sanitizer_procmaps.h
40 ↗(On Diff #77867)

Maybe use default arguments here?

lib/sanitizer_common/sanitizer_procmaps_freebsd.cc
53 ↗(On Diff #77867)

It would be good to add asserts saying that support for passing non-null arch and uuid is not implemented for freebsd and linux.

kubamracek updated this revision to Diff 78823.Nov 21 2016, 8:01 PM
kubamracek edited edge metadata.
kubamracek removed rL LLVM as the repository for this revision.

Addressing review comments. Adding a unit test.

filcab added a subscriber: filcab.Nov 22 2016, 9:15 AM
filcab added inline comments.
lib/sanitizer_common/sanitizer_common.h
686 ↗(On Diff #78823)

Why not just return uuid_?

lib/sanitizer_common/sanitizer_procmaps_mac.cc
139 ↗(On Diff #78823)

How about an outer switch/case and then ternary ops/more ifs/another switch if needed?

156 ↗(On Diff #78823)

Should we assert that we always find a UUID?

lib/sanitizer_common/tests/sanitizer_procmaps_test.cc
66 ↗(On Diff #78823)

Are the unit tests only run on X86(-64)? Never on ARM? Interesting.
Can you add a comment, please?

Updating patch.

Should we assert that we always find a UUID?

No, I don't think so. The linker emits a LC_UUID load command by default, but you can suppress this with -no_uuid. Not sure why you'd ever want to do that, but a Mach-O is valid even without a UUID.

Are the unit tests only run on X86(-64)? Never on ARM?

That's currently correct: On Darwin we can only run unit tests locally on the machine that builds compiler-rt, and I'm not sure but I think the same holds for Linux as well.

filcab edited edge metadata.Nov 29 2016, 8:08 AM

Almost LGTM, but I have some questions:
How are you planning on using the ModuleArch part? Would it be better (see my inline comment) to just save the cputype + cpusubtype?
IIUC, you can only have a slice per arch (type+subtype?).
Are you planning on always relying on ModuleArch (or something similar) all the time, or only as a fallback, if no UUID is available?

lib/sanitizer_common/sanitizer_procmaps_mac.cc
122 ↗(On Diff #78920)

I wonder if we want a CHECK(0); here (or the opposite, a check that the subtype is one of those two). Same for the ARM ones.

How are you planning on using the ModuleArch part? Would it be better (see my inline comment) to just save the cputype + cpusubtype?

An immediate plan is to use ModuleArch for symbolication. When you just have module name + address, that's not enough to symbolicate, because the address might be valid in multiple slices in the module file on disk. Both atos and llvm-symbolizer suffer from this and it's especially painful on Haswell+ Intel machines, where plenty of modules (including the ASan and TSan dylibs) have both the x86_64 and x86_64h slices and basically each pointer is usually valid in both slices. I'm simply planning to pass the arch (as a string most likely) to atos and to llvm-symbolizer and to produce this in reports (again as a string). I don't think the CPU type+subtype is useful for this. And the set of archs that Darwin supports is very small. I think that type+subtype is too Mach-O specific to store it in LoadedModule.

IIUC, you can only have a slice per arch (type+subtype?).

That's right.

Are you planning on always relying on ModuleArch (or something similar) all the time, or only as a fallback, if no UUID is available?

I'm planning to use the ModuleArch all the time to correctly select the slice when symbolicating.

The plan for UUIDs is related, but slightly different. We have a few requests from people who use ASan and TSan in CI and/or process the text reports in various ways. They want to be able to pass ASan/TSan reports to symbolication servers. All of the existing debug symbols server support on macOS relies on module UUIDs. My plan is to have an option (maybe on by default, maybe not) that includes UUIDs of modules involved in the text report.

I'll send patches for review for this and the previously mentioned symbolication change soon.

kubamracek edited edge metadata.
zaks.anna accepted this revision.Dec 1 2016, 3:35 PM
zaks.anna edited edge metadata.

LGTM

This revision is now accepted and ready to land.Dec 1 2016, 3:35 PM
filcab accepted this revision.Dec 2 2016, 9:54 AM
filcab edited edge metadata.

LGTM too

This revision was automatically updated to reflect the committed changes.