This is an archive of the discontinued LLVM Phabricator instance.

[Clang][Bundler] Fix for a hang when unbundling fat binary
ClosedPublic

Authored by sdmitriev on Aug 22 2019, 9:03 AM.

Details

Summary

clang-offload-bundler tool may hang under certain conditions when it extracts a subset of all available device bundles from the fat binary that is handled by the BinaryFileHandler. This patch fixes this problem.

Diff Detail

Repository
rL LLVM

Event Timeline

sdmitriev created this revision.Aug 22 2019, 9:03 AM
Herald added a project: Restricted Project. · View Herald Transcript
Herald added a subscriber: cfe-commits. · View Herald Transcript

Could you provide some more details about the problem?

Sure. The main unbundling loop looks as follows (see loop on line 745)

while (!Worklist.empty()) {
  StringRef CurTriple = FH.get()->ReadBundleStart(Input);

  if (CurTriple.empty())
    break;

  auto Output = Worklist.find(CurTriple);
  if (Output == Worklist.end()) {
    continue;
  } 
 ...
}

Here Worklist is a collection of bundles that need to be extracted, and FH is the object implementing FileHandler interface. FileHandler::ReadBundleStart() returns the name of the bundle FH currently points to. As you can see in the loop above if the name returned by that call is not in the set of bundles that need to be extracted, we just call ReadBundleStart next time assuming that FileHandler would advance to the next bundle on each ReadBundleStart call. That assumption is correct for all FileHandler implementations except BinaryFileHandler which does not advance to the next bundle when this method is called. As a result we are going into an infinite loop if we need to skip a bundle for the file handled by the BinaryFileHandler . This patch just fixes this problem in the BinaryFileHandler implementation.

sdmitriev marked an inline comment as done.Aug 27 2019, 1:15 PM
sdmitriev added inline comments.
clang/tools/clang-offload-bundler/ClangOffloadBundler.cpp
301 ↗(On Diff #217232)

Just noticed that this line now looks redundant and should be removed.

sdmitriev updated this revision to Diff 217485.Aug 27 2019, 1:40 PM
ABataev added inline comments.Aug 27 2019, 1:44 PM
clang/tools/clang-offload-bundler/ClangOffloadBundler.cpp
295 ↗(On Diff #217485)

Maybe just:

const BundleInfo &Bundle = *CurBundleInfo;
std::advance(CurBundleInfo, 1);
return Bundle.first();

instead of all these changes?

sdmitriev marked an inline comment as done.Aug 27 2019, 1:48 PM
sdmitriev added inline comments.
clang/tools/clang-offload-bundler/ClangOffloadBundler.cpp
295 ↗(On Diff #217485)

It could be done like this if CurBundleInfo was not used in ReadBundle.

This revision is now accepted and ready to land.Aug 27 2019, 2:07 PM
This revision was automatically updated to reflect the committed changes.
Herald added a project: Restricted Project. · View Herald TranscriptAug 27 2019, 2:48 PM