LLVM:如果需要 CallGraphWrapperPass,Clang 不会 运行 通过

LLVM: Clang does not run Pass if CallGraphWrapperPass is a requirement

我为 llvm 编写了以下 pass

using namespace llvm;

namespace {
    struct SkeletonPass : public FunctionPass {
        static char ID;
        SkeletonPass() : FunctionPass(ID) {}

        void getAnalysisUsage(AnalysisUsage &AU) const {
            AU.addRequired<CallGraphWrapperPass>();
            AU.setPreservesAll();
        }

        virtual bool runOnFunction(Function &F) {
            errs() << "Function: " << F.getName() << "!\n";

            CallGraph &CG = getAnalysis<CallGraphWrapperPass>().getCallGraph();

            return false;
        }
    };
} 

char SkeletonPass::ID = 0;
static RegisterPass<SkeletonPass> X("skeleton", "text");

如果我用

执行这段代码
opt -load ./libSkeletonPass.so -skeleton test.bc > /dev/null 

我得到了正确的输出。 (test.bc可以忽略)

根据这个厉害blog,下一个命令

clang -Xclang -load -Xclang ./libSkeletonPass.so test.c

应该也可以,只要我们将最后一行替换为:

static void registerSkeletonPass(const PassManagerBuilder &,
                         legacy::PassManagerBase &PM) {
  PM.add(new SkeletonPass());
}
static RegisterStandardPasses
  RegisterMyPass(PassManagerBuilder::EP_EarlyAsPossible,
                 registerSkeletonPass);

问题 是 clang 崩溃和 returns 这个错误:

...
clang-3.8: error: unable to execute command: Segmentation fault (core dumped)
clang-3.8: error: clang frontend command failed due to signal (use -v to see invocation)
...

没有所有 CallGraphWrapperPass 引用 clang 执行 pass 正确。

我是 llvm 的新手,所以我错过了什么吗?

系统:Linux 4.4.0(64 位)

clang 版本: 3.8.1

解决方案是将 EP_EarlyAsPossible 更改为 EP_EnabledOnOptLevel0。