我将为LLVM 2.9编写的LLVM插件(LLFI)移植到最新版本的LLVM / Clang。
在使用断言启用的LLVM3.2构建测试我的插件时,我收到以下错误:
opt: /home/kzvr/ubc/llfi/llvm3/llvmsrc/lib/IR/Instructions.cpp:281:
void llvm::CallInst::init(llvm::Value*, llvm::ArrayRef<llvm::Value*>,
const llvm::Twine&): Assertion `(i >= FTy->getNumParams() ||
FTy->getParamType(i) == Args[i]->getType()) && "Calling a function with a bad
signature!"' failed.
0 opt 0x00000000017931a6 llvm::sys::PrintStackTrace(_IO_FILE*) + 38
1 opt 0x0000000001793423
2 opt 0x0000000001792e7b
3 libpthread.so.0 0x00007f0c0279fff0
4 libc.so.6 0x00007f0c018a91b5 gsignal + 53
5 libc.so.6 0x00007f0c018abfc0 abort + 384
6 libc.so.6 0x00007f0c018a2301 __assert_fail + 241
7 opt 0x00000000016e78c4 llvm::CallInst::init(llvm::Value*, llvm::ArrayRef<llvm::Value*>, llvm::Twine const&) + 402
8 LLFI.so 0x00007f0c0165adcb
9 LLFI.so 0x00007f0c0165aa83
10 LLFI.so 0x00007f0c016581c5
11 opt 0x000000000171c02c llvm::FPPassManager::doFinalization(llvm::Module&) + 88
12 opt 0x000000000171c449 llvm::MPPassManager::runOnModule(llvm::Module&) + 1013
13 opt 0x000000000171c8a6 llvm::PassManagerImpl::run(llvm::Module&) + 254
14 opt 0x000000000171cc01 llvm::PassManager::run(llvm::Module&) + 39
15 opt 0x000000000087a089 main + 5591
16 libc.so.6 0x00007f0c01895c8d __libc_start_main + 253
17 opt 0x000000000086bf59
在插件代码中我有很多调用llvm :: CallInst :: Create,基于上面的内容,我相信其中至少有一个执行不正确。他们几乎都是这样的:
ArrayRef<Value*> arrayArgs(args);
Instruction* callInst = CallInst::Create( injectFunc, arrayArgs, fiName, insertInst);
其中args是std :: vector,injectFunc是llvm :: Constant *,fiName是std :: string,insertInst是llvm :: Instruction *
问题是,作为一个LLVM新手,我不知道如何从这一点缩小我的bughunt。所以我有几个问题:
在此先感谢您的帮助,我希望这个问题不要太模糊。
答案 0 :(得分:6)
关于如何调试LLVM断言错误的最佳提示 - 标题中的问题 - 是读取断言的代码:)
消息 - “调用签名错误的函数!” - 有点模棱两可,但看看实际的断言条件(失败)你可以看出问题是什么:
i >= FTy->getNumParams() || FTy->getParamType(i) == Args[i]->getType()
因此,您要么提供太多参数,要么其中一个参数与函数所期望的类型不同。您还可以查看断言位置,Instructions.cpp第281行,以查看上下文的周围代码。
要解决这个问题,我首先要看一下函数类型是什么(一种简单的方法就是在函数或函数类型上调用->dump()
,它会将它打印到stdout )。然后我将这些类型与我发送给CallInst的类型进行比较(->dump()
也将在那里工作)。另外,根据预期的参数数量验证参数的数量。
关于你剩下的问题:
args
向量作为第二个参数传递。您的用法正确,但这不是断言失败的原因。