<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/63648>63648</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
Double free crash when optimize code by custom pass
</td>
</tr>
<tr>
<th>Labels</th>
<td>
new issue
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
XiDianZuoYun
</td>
</tr>
</table>
<pre>
### LLVM version
16.0.6
### Backtrace
`Function: Foo, called 8 times
Function: Bar, called 2 times
Function: Fez, called 1 times
Function: main, called 1 times
double free or corruption (!prev)
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace.
Stack dump:
0. Program arguments: lli test
#0 0x00007f4df3d5d7d6 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/usr/lib/llvm-16/bin/../lib/libLLVM-16.so.1+0xfba7d6)
#1 0x00007f4df3d5b960 llvm::sys::RunSignalHandlers() (/usr/lib/llvm-16/bin/../lib/libLLVM-16.so.1+0xfb8960)
#2 0x00007f4df3d5dfb0 (/usr/lib/llvm-16/bin/../lib/libLLVM-16.so.1+0xfbafb0)
#3 0x00007f4df2d4a420 __restore_rt (/lib/x86_64-linux-gnu/libpthread.so.0+0x14420)
#4 0x00007f4df283b00b raise /build/glibc-SzIz7B/glibc-2.31/signal/../sysdeps/unix/sysv/linux/raise.c:51:1
#5 0x00007f4df281a859 abort /build/glibc-SzIz7B/glibc-2.31/stdlib/abort.c:81:7
#6 0x00007f4df288526e __libc_message /build/glibc-SzIz7B/glibc-2.31/libio/../sysdeps/posix/libc_fatal.c:155:5
#7 0x00007f4df288d2fc /build/glibc-SzIz7B/glibc-2.31/malloc/malloc.c:5348:3
#8 0x00007f4df288efac _int_free /build/glibc-SzIz7B/glibc-2.31/malloc/malloc.c:4317:7
#9 0x00007f4df573c12b llvm::orc::JITDylib::~JITDylib() (/usr/lib/llvm-16/bin/../lib/libLLVM-16.so.1+0x299912b)
#10 0x00007f4df57476bf llvm::orc::ExecutionSession::endSession() (/usr/lib/llvm-16/bin/../lib/libLLVM-16.so.1+0x29a46bf)
#11 0x00007f4df5796fd3 llvm::orc::LLJIT::~LLJIT() (/usr/lib/llvm-16/bin/../lib/libLLVM-16.so.1+0x29f3fd3)
#12 0x00007f4df579a8c4 (/usr/lib/llvm-16/bin/../lib/libLLVM-16.so.1+0x29f78c4)
#13 0x0000558f88011ccf runOrcJIT(char const*) (/usr/lib/llvm-16/bin/lli+0x1accf)
#14 0x0000558f8800cad9 main (/usr/lib/llvm-16/bin/lli+0x15ad9)
#15 0x00007f4df281c083 __libc_start_main /build/glibc-SzIz7B/glibc-2.31/csu/../csu/libc-start.c:342:3
#16 0x0000558f88009b5e _start (/usr/lib/llvm-16/bin/lli+0x12b5e)
[1] 2892851 abort (core dumped) lli test`
### Pass code
`// RunTimeFunctionCallCounter.cpp
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/PassManager.h"
#include "llvm/Passes/PassBuilder.h"
#include "llvm/Passes/PassPlugin.h"
#include "llvm/Transforms/Utils/ModuleUtils.h"
#include <iostream>
#include <llvm-16/llvm/IR/Type.h>
#include <map>
using namespace llvm;
#define DEBUG_TYPE "runtime-function-call-counter"
namespace helper
{
Constant* CreateGlobalVariable(Module& module, StringRef globalVariableName);
bool CountFunctionCallsInModule(Module& module);
} // namespace helper
// A LLVM Pass to count the function calls at runtime
class RunTimeFunctionCallCounter : public PassInfoMixin<RunTimeFunctionCallCounter>
{
public:
PreservedAnalyses run(Module& module, ModuleAnalysisManager&)
{
bool changed = helper::CountFunctionCallsInModule(module);
return changed ? PreservedAnalyses::none() : PreservedAnalyses::all();
}
};
// Pass registration
extern "C" LLVM_ATTRIBUTE_WEAK ::PassPluginLibraryInfo llvmGetPassPluginInfo()
{
return {
LLVM_PLUGIN_API_VERSION, "Run-Time Function Call Counter", LLVM_VERSION_STRING, [](PassBuilder& passBuilder) {
passBuilder.registerPipelineParsingCallback(
[](StringRef name, ModulePassManager& passManager, ArrayRef<PassBuilder::PipelineElement>) {
if (name == "runtime-function-call-counter")
{
passManager.addPass(RunTimeFunctionCallCounter());
return true;
}
return false;
});
}};
}
Constant* helper::CreateGlobalVariable(Module& module, StringRef globalVariableName)
{
auto& context = module.getContext();
// This will insert a declaration into module
Constant* newGlobalVariable = module.getOrInsertGlobal(globalVariableName, IntegerType::getInt32Ty(context));
// This will change the declaration into definition (and initialize to 0)
GlobalVariable* initializedGlobalVariable = module.getNamedGlobal(globalVariableName);
initializedGlobalVariable->setLinkage(GlobalValue::CommonLinkage);
initializedGlobalVariable->setAlignment(MaybeAlign(4));
initializedGlobalVariable->setInitializer(ConstantInt::get(context, APInt(32, 0)));
return newGlobalVariable;
}
bool helper::CountFunctionCallsInModule(Module& module)
{
auto& context = module.getContext();
// Function name to IR variable map that holds the call counters
StringMap<Constant*> callCounterMap;
// Function name to IR variable map that holds the function names
StringMap<Constant*> functionNameMap;
// Step 1. For each function in the module, inject the code for call-counting
for (Function& function : module)
{
if (function.isDeclaration())
{
continue;
}
// Get an IR builder and set the insertion point to the top of the function
IRBuilder<> counterBuilder(&*function.getEntryBlock().getFirstInsertionPt());
// Create a global variable to count the calls to this function
std::string counterName = "counter_" + function.getName().str();
Constant* counterVariable = helper::CreateGlobalVariable(module, counterName);
callCounterMap[function.getName()] = counterVariable;
// Create a global variable to hold the name of this function
Constant* functionName = counterBuilder.CreateGlobalStringPtr(function.getName(), "name_" + function.getName());
functionNameMap[function.getName()] = functionName;
// Inject instruction to increment the call count each time this function executes
Type* t = IntegerType::getInt32Ty(context);
LoadInst* counteCurrentValue = counterBuilder.CreateLoad(t,counterVariable,"counteCurrentValue");
Value* counterNextValue = counterBuilder.CreateAdd(counterBuilder.getInt32(1), counteCurrentValue);
counterBuilder.CreateStore(counterNextValue, counterVariable);
LLVM_DEBUG(dbgs() << "Instrumented: " << function.getName() << "\n");
}
// Stop here if there is no function definition in this module
if (callCounterMap.size() == 0)
{
return false;
}
PointerType* printfArgType = PointerType::getUnqual(Type::getInt8Ty(context));
FunctionType* printfFunctionType = FunctionType::get(IntegerType::getInt32Ty(context),
printfArgType,
/*IsVarArgs=*/true);
FunctionCallee printfCallee = module.getOrInsertFunction("printf", printfFunctionType);
// Step 3. Inject a global variable that will hold the printf format string
Constant* formatString = ConstantDataArray::getString(context, "Function: %s, called %d times\n");
Constant* formatStringVariable = module.getOrInsertGlobal("", formatString->getType());
dyn_cast<GlobalVariable>(formatStringVariable)->setInitializer(formatString);
FunctionType* printfWrapperType = FunctionType::get(Type::getVoidTy(context),
{},
/*IsVarArgs=*/false);
Function* printfWrapperFunction =
dyn_cast<Function>(module.getOrInsertFunction("PrintfWrapper", printfWrapperType).getCallee());
BasicBlock* enterBlock = BasicBlock::Create(context, "enter", printfWrapperFunction);
IRBuilder<> printfWrapperBuilder(enterBlock);
Value* formatStringPtr = printfWrapperBuilder.CreatePointerCast(formatStringVariable, printfArgType);
for (auto& item : callCounterMap)
{
Constant* functionName = functionNameMap[item.first()];
auto type = IntegerType::getInt32Ty(context);
LoadInst* counterValue = printfWrapperBuilder.CreateLoad(type,item.second,"counterValue");
printfWrapperBuilder.CreateCall(printfCallee, {formatStringPtr, functionName, counterValue});
}
printfWrapperBuilder.CreateRetVoid();
// Step 5. Call `PrintfWrapper` at the very end of this module
appendToGlobalDtors(module, printfWrapperFunction, /*Priority=*/0);
return true;
}
`
### shell command
`mkdir build && cd build
cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=1 -DCMAKE_BUILD_TYPE=Debug -DCMAKE_VERBOSE_MAKEFILE=ON ..
make RunTimeFunctionCallCounter -j4
clang -S -emit-llvm Test.c -o Test.ll
opt -load-pass-plugin=/home/zhanghongyi/github/llvm-pass-examples/llvm/lib/Transforms/build/RunTimeFunctionCallCounter/RunTimeFunctionCallCounter.so -passes="runtime-function-call-counter" ./Test.ll -o test
lli test`
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJysWklz27iX_zTwBSUVBWqhDj5QW0bdtqOylXT3XFQgCVLoUAAHAB0rh_nsUwC4i5Kd-VuVikkCeBve8nsgsZQ0YYTcg8kCTFZ3OFdHLu7_piuK2X_n_J-c3QU8Ot8D5Np_8OHh-yN8JUJSzoCzAo4_mg6d4dRe1_MWOPyhBA5JMTB1NjkLlV7l-nDDOUBLGOI0JRH0oKInIu3M5rQFFo1p6Nq0DfnVmDa6Nu2EKbs2L-J5kBIYC0IgFzDkQuSZXggB8gAaZYK8AjS3k3cPa_9lDWUenKiCGAZ5AgXJuFBQcXhUKpPA9QHaALRJqDrmwTDkJ4A2afpa_hlkgv9LQgXQhkqZEwnQBmIWQcrCNI8IVEcCQ4HlEQalKYeW_YvC4Q8Y5adMczGPnCE0v53gicAniEWSnwhTWg6YphQqIpWdCgFyHei8OY7jzOJxFLvRJJpFU2iEc33g-vIs7cVOUKYMu73ZSuTVkwT-eeBSCYJPAE21XSlTAM2twTa5FFpTGpT6jqYAbQK9A5vhsB6igfaowWg6lHw4AmjhvMUBnkXTytpa4FFH4GA-dfoEfs7ZC00YTv8LsyglQhphPkUmbz51WjKhrhHjwPkU5eOgzchtMkLRGI-RAw8HQaTighyEKrhaom_e9DAdD1LK8rdBwnI7kKmjIDjSfBzDZzQeozabcYuN5waOE0CBqSRQC5_TNNL-nNIgHLz82v6aLapbNHRHAG2kMX2pozzLiGTar3NG3-yDVyMNy_WtIT0MgetPRsD1R7Ukk7YkI-xN5hAH3Gj6MUlUZK1hVhkmnmYyq5lM20y8CZoSeDhoKocTkRInH9Y7pQHll2pnXBq9DckYK5waQUaTida5lmTWkSRCcfhR1iecpjysLqw53bEHXN-tOXgdDiTGITxQpg4m4f0HvMbuaNa267zJazJzwxEKGqHKRWgv_tjuV2e9Sebuf6vbTwpYNJ_PRyioPFwnEact2ng2DeI-0dZvJMx18n8hUtriAVyfsKi8_zQZ8XgaxC0ZR20Z59M4cvtkfHj4Y7svbGevP02o2I0jtyUU6giFvXD8KZxmXjhucSpz3WTixZ7njEZhGEORs68itDqGR6zLM5MKIP9jCqcptSkPh2Hb2OM2NyfE0dzAhN-hOsHRvEW1m75Cx3PLzCIVFupQsPhQ1IUyL01pL82goWMi0B2jOtg1-2lHqXkwIdAy_h21UDAhtVqTxQhMVhB5c-RNRlUy9kIuiIEiJNKbUWONqVOs7ODCHZYShjyqcaHFSfA5Z3t6IiVgW-I0XfKcKSKGYZZ1iJUgCSBUYKrts_lvoS1KxPAIEHpvthblETOcvD9fTzUQTV98kEdrzS7NE8reW7IXmMmYi5Ne9k3RVP995FGeEnPXXH9BxV3SEo-5677hequbVtifMzI8Xllywlk9Yv7PJWUJZPhEZIZDUqSmRUeoiMSUEbhaL759Oez_2a21kiJnGnEP4mKLBxqID0K7yR3FagZHkmZEFGOzghFc6gyANeD04VIQrMiXlAc4_Y4FxUGqoaq1G0BTeCqulvBFCcqSZxLDpDX9CZ-Ms5eKaCwdcJ5C44JNn5RbVhLu4VBTALMVLDz7ii6FrcwU3_ZVJjgUh8YmpgMobWWaFgmxgoUV7fIw1Suuhw7U-D_Lg5SGhviWxfyRvlEG3OX1VfWWl_a2JKp2ozDSThBJxCuJfIbTsyRSC3fF8vaZnUjLsDONw7w2eb2_xvjhEbOERBC4q9J0puDd3JTLrYCCqFywBrnNpeiWMuOMlIXU7VHQzsJpaifVLMBsVe37RTiYLTZ7K0hCpRJYVd0zeVNE6GKAlgAh4wYHf79_3i6-7deHv9b-n7Doxaos8kADgcVZ76UJvy9E1YP6aSFcJ2QgLA1RPzPsdg_fvmyfDv5ue_i-fn7Zfn3SGwYQes7ZQLsILG0NtbHhso5YtLQkinWHl_3z9umLWW5OFADyGhlTe0TWvJ03RGkMDK2ZiNjRjKSUkR0WOu1o7roZ1vpVOjV_FdM6zpmJ7NL_Gim_FKa6XUJfCHx-JjFwl02prfkLUdYp0Y21DpGW-D0_GusKqQXQHqyd-CNJsG7JWqYpCxWOIi0bQN6N-LX73xMCSuSkleQuLFj58dUpBakYp_I6LU2nk0_Lx80AaXNrJvVWvH9egr-MCZwrrmmEnCnypkyysfSGCVFL-7QT7lW3YyJ7f6QS_qRpCimTRCiIYUTCFNswh5QpXkpYcW2qysjPtm4dGb6KraFrJwHk9am2hFumSEKErufWbAlRW6ZctD8boFYoMu9RRO9MVxebLU0RutDGlHdaHo_ZUyuqKE7pL6Lrl9PK6t2N8xuzo5uaa9Wim2o3XOwq0QFw15KoB8p-4EQ7Tjmc5qQsKKcTZ9WE3yDqpzRhJiEg7xGfA2IeAOSNuxH4HqVtNa7jt_SPrU41xWY2d3EJ_d3WcHVNFnYKdr17W0TshZ9di0NTfD9ccPtQ0KeGWe2dVR0ySVVxuH2Gr6XrnHAG1REreORpJO35qS5XRW6VNTWbJB41tl02AhG4a7OiyKJmvDfgf1eMuDm_lOOGEOV87eI9UtT2eFEkg6Mh3HABCQ6PNSfKDOc6MVL2LwktptTdF4y5gHXpoSypieshgLzq6BxNa7rmHL29zW3g1qp95bIhlas6h9TlqVvoGj_tJ5T1VKsrFaqwyBeiIGZ6QwJbvc2ZuiRWc5uftR4Zp8yc1uvHimeQx62tahOv-krgLo2XWA-pcIxngKxfqZsQtWZKnBcpt2gFzfWzDRVSbUsZduqyTrf9zNY9iItaVvtYq0WwnYFRhcquAlJFxRG5cbdS8qcClGhEUjw6aPgJ0AI2tbBJ1sgvleiC3mYRK6i0EvkHanjtoA3J-pBDJzAni34xwWRlWHfE6QmhhtPcsrOOYmNmE-vGSy6tXPya9mjGcFOiEuI27WFTwc4Y-IpaFpBrGd7Zpz7bdfPJe8Zrzr9tua3NKpRJJXKbIRSHlIXCoOROErY5SsPfthUhMQeuRLZ5GCSDfGiLxYfhTVf7B46jrT0vLDZhmQtBmDIA4Pre6HUAebrYdr3J9GqXtAr4XglQPKyC44m8vcfUjyKjTWuo1BQgb1Q4Qx_zBude2i-KC1JTr6RpRF-tYYOY6fDMUQ5AXhQk1Us1nQyNX27N_usdJzrdQOOidrTf0xprwWTJuobrT_NV0eMZPBJBdJFR9kJCxmt3asBTUwepvMDftj61k8pQ0l-1fKZhc65Uuas9UCW2vtnpIlO4LPJhJihTsS8S_cC4QHNC6dPf2P_kBu52Pd27geM1t7Jet9k1nxqerWkNaPnx9mFZtqVNferHZpv8rfyOhS8SqS2JfIA2pvdsytwElIQU5Iqb_g6ohiQeQMguKI4hLrW9iSQNcnKHZQLrSf0awplGqKoAloWGRyesoC2o_R2dnWLTulGlHFxhhc0pQ2ViO6kN7QFCze8WAJrIxncLAE2i4tOF_tC5JslH20tD0hi1uVq3KQlR1rIXlSY6s0OIpQLusttjrHVV6xEDoHlv69Oc2-svbQf_S-Ass357079b9985ja76tQ7z2ep9h7bRfyUKLwTc1BB6dWm0er_XFSq67vm7JuFWADSsUYBOG1D94GCBJQ0LkOpDYkqGvjOGbAw2ENyFp5LGWWCvwi2mXSTdWlHj6VqU_iiuKmvTWXZKGMH7aBYlsEi4S230a1657Ca2ts2K7qjsZ6kiJ9MVdQBqf924iRAvYZomPox111ABtAt4owWBqvT-T0RJooYqNyxaoiRbAozAkoScRU2QJHrh0Q2qS3vE3iwJxt1mi86GmyzVhKtNLKN5Xp5DdpHFDTGebaZ471jCFJPJ0J6Og6nTDs-pA7FFwq9EnCFhUdVGtFCJns2iPbf5c6W4-XqpbpCuBNeyyE87Qbmg6lylJ6dH5r5j4Noe1Tvb6m2tPBID3k8nzKJq1ulHRIVtsKHpfKcwjOx98VrqhH8QOFgtH_0_14f137uvz_vD8uvjbvuw1n8f_afVC3BXI1hNWnzbPqzMq0LgrlYkyJNq6Pv6efH1ZX3QN5vtg57w9QnCYfE5nOF14xXY4N9x9bKMJXDwAgfkRNUgTV9PcE-kGoZwwO1VmtqpPFNwkHIcDTIs5SAzr1aMZTdHrr1s8-uIWXLkLDnT6iu_6tM-vYa84VOWmhfA5Wd_5oV76x1v-QHArbP8G4NDyaHhRmxVevftAhxqCaymWun6s8CLF_d30b0bzd05viP3o6nnubPxdDy6O957bjRCOA7JfBIgJ4jJLCIkRKPJJAjn8-nkjt4jB7nOzHEdbzJDo6HjRV7shdgJ3flkFjlg7JATpulQG2bIRXJnPoG8n7rTsXeX4oCk0nySihAjP6EZNJ3C6k7cGwsHeSLB2EmpVLKmoqhKyf2q8Smn_YDy55EwyDNFT_RXcfwVnGGYS8VP5uXKXS7S-___d5tG7v8LAAD__5WgQcw">