我写了一个llvm callgraphscc pass
,它非常简单如下:
bool MyCallGraphSCCPass::runOnSCC(CallGraphSCC& SCC) {
for (CallGraphSCC::iterator it = SCC.begin(); it != SCC.end(); it++) {
CallGraphNode* node = *it;
Function* func = node->getFunction();
}
return false;
}
这很好用。但是,如果我想打印每个函数的名称如下:
bool MyCallGraphSCCPass::runOnSCC(CallGraphSCC& SCC) {
for (CallGraphSCC::iterator it = SCC.begin(); it != SCC.end(); it++) {
CallGraphNode* node = *it;
Function* func = node->getFunction();
func->getName();
}
return false;
}
然后它可以编译(显然),但是当我使用opt
来运行它时,会出现如下错误:
0 opt 0x0000000001603412 llvm::sys::PrintStackTrace(_IO_FILE*) + 34
1 opt 0x0000000001602cb4
2 libpthread.so.0 0x00007fd3155f8cb0
3 opt 0x00000000014a86e0 llvm::AttributeSet::getAttributes(unsigned int) const + 0
4 opt 0x00000000014a8748 llvm::AttributeSet::hasAttribute(unsigned int, llvm::Attribute::AttrKind) const + 8
5 call_graph_scc_pass.so 0x00007fd3146062ad test::MyCallGraphSCCPass::runOnSCC(llvm::CallGraphSCC&) + 61
6 opt 0x00000000012aa9aa
7 opt 0x0000000001591188 llvm::legacy::PassManagerImpl::run(llvm::Module&) + 904
8 opt 0x000000000059387b main + 2811
9 libc.so.6 0x00007fd31482976d __libc_start_main + 237
10 opt 0x00000000005b700d
Stack dump:
0. Program arguments: opt -load call_graph_scc_pass.so -scc
1. Running pass 'CallGraph Pass Manager' on module '<stdin>'.
Segmentation fault (core dumped)
有人可以帮我这个吗?
答案 0 :(得分:0)
您应该检查CallGraph
中的功能是否为isDeclaration()
。
答案 1 :(得分:0)
这是因为node->getFunction()
可能会返回一个空指针,并且您在取消引用之前无需检查它。
没有内部链接的情况下,模块中所有功能的调用图都添加了CallGraphNode
。这是因为有可能 从另一个模块调用。当然,这是无法从当前模块到达的,因此调用者函数为null。
如果功能地址用于直接调用以外的其他功能(例如存储到内存中),则还会添加CallGraphNode
。稍后可能会以无法静态跟踪调用方的方式对其进行调用,因此此处的功能字段也为null。