Hi, Thanks both of you for the help. I just missed that Create function had many optional arguments... sorry for that. However my problem wasn't coming from here (IRBuilder CreateCall function still return a pointer to CallInst so I just added 2 times the call?). I didn't wanted to detail the all issue previously because I knew I had a problem with my syntax. So here's my problem: I am doing this replacement operation in a FunctionPass (this is no restriction, I could do it on a ModulePass if that's a solution). On each Function given I do an iteration over the instructions and replace (if it's a call to the right function) the call. It's like this: bool FDPFunction::runOnFunction(Function &F) { bool res = false; TLI = &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(); for (inst_iterator i = inst_begin(F), e = inst_end(F); i != e; ++i) { Instruction *I = &*i; if (!I) { errs() << "error: null pointer instruction\n"; break; } else if (isMyFunctionCall(I, TLI)) { errs() << "found a call to the function to replace\n"; res = true; replacement_function(I); } else { errs() << "default: trash instruction\n"; } } return res; } The problem is that after the first replacement, the iterator becomes a null pointer. With the break instruction the program is correctly instrumented for the first call (about that: what is the use of replaceAllUsesWith function? I thought it would replace all uses of the function... but just one is done). I can then link it and execute with lli (I still get a: "*** Error in `lli': corrupted double-linked list: 0xaddress ***" but after the whole execution is done). But if I remove the break and the if condition associated, well I get a null pointer exception : Assertion `Val && "isa<> used on a null pointer"' failed I tried to clone the current instruction to not modify the iterator but the ReplaceInstWithInst will cause troubles (probably because a copied instruction has no parents): #0 0x0000000002a95b5c llvm::sys::PrintStackTrace(llvm::raw_ostream&) /home/pierre/Desktop/llvm/lib/Support/Unix/Signals.inc:400:0 #1 0x0000000002a95edf PrintStaI tried to clone the current instruction to not modify the iterator but the ReplaceInstWithInst will cause troublesckTraceSignalHandler(void*) /home/pierre/Desktop/llvm/lib/Support/Unix/Signals.inc:468:0 #2 0x0000000002a94145 llvm::sys::RunSignalHandlers() /home/pierre/Desktop/llvm/lib/Support/Signals.cpp:44:0 #3 0x0000000002a953a8 SignalHandler(int) /home/pierre/Desktop/llvm/lib/Support/Unix/Signals.inc:254:0 #4 0x00007fe358d3dd10 __restore_rt (/lib/x86_64-linux-gnu/libpthread.so.0+0x10d10) #5 0x00000000011fe489 llvm::iplist<llvm::Instruction, llvm::SymbolTableListTraits<llvm::Instruction>>::insert(llvm::ilist_iterator<llvm::Instruction>, llvm::Instruction*)/home/pierre/Desktop/llvm/include/llvm/ADT/ilist.h:415:0 #6 0x0000000002abc20d llvm::ReI tried to clone the current instruction to not modify the iterator but the ReplaceInstWithInst will cause troublesplaceInstWithInst(llvm::SymbolTableList<llvm::Instruction>&, llvm::ilist_iterator<llvm::Instruction>&, llvm::Instruction*) /home/pierre/Desktop/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp:198:0 #7 0x0000000002abc2a5 llvm::ReplaceInstWithInst(llvm::Instruction*, llvm::Instruction*) /home/pierre/Desktop/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp:210:0 Any idea on what could be the cause of the null pointer and how to avoid it? Thanks a lot for your time! Pierre On 20 June 2016 at 15:45, John Criswell <jtcriswel at gmail.com> wrote:> On 6/20/16 6:17 AM, Pierre Gagelin via llvm-dev wrote: > > Hi everyone, > > I am trying to replace the call of a certain function with a call to > another function. It would for example replace the following: > > %call = tail call noalias i8* @func(i64 10) > by > %call = tail call noalias i8* @other_func(i64 10) > > I managed to declare other_func correctly but I am having troubles to > understand how I should proceed to do the replacement. > > I tried to use ReplaceInstWithInst function as follows: > > CallInst *call_to_other_func_inst > IRBuilder.CreateCall(ptr_to_other_func, args); > ReplaceInstWithInst(call_to_func_inst, newI); > > LLVM builds correctly but the instrumentation crashes at optimization > time. I know this isn't the correct way to do it because IRBuilder > generates IR and I just want to have an instance of a CallInst. But I don't > see how it is supposed to be done? > > > Do you have assertions enabled? If so, is the crash an assertion failure > and, if so, which assertion is failing? It's nearly impossible to tell > what the problem is just by knowing that it is crashing. > > > There are methods to create CallInst in the Instruction.h file but those > needs to give an inserting point. Shoud I insert the call to other_func > before the one to func and just remove the call instruction to func? > > > Yes. You need to place the new call instruction within the same basic > block as the old call instruction. Placing it right before the old call > instruction is a good place. > > The code that Ashutosh provided is what I'd use to do what you're doing. > > Regards, > > John Criswell > > > Thanks for your help, > Pierre > > > _______________________________________________ > LLVM Developers mailing listllvm-dev at lists.llvm.orghttp://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev > > > > -- > John Criswell > Assistant Professor > Department of Computer Science, University of Rochesterhttp://www.cs.rochester.edu/u/criswell > >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20160621/9bed76a0/attachment.html>
Hi again, that's weird... I continued the implementation of the replaced function (not touched the FunctionPass, just the runtime function) and I have no more the "*** Error in `lli': corrupted double-linked list: 0xaddress ***" error message when I run the linked bitcode file... Anyway the issue of the null pointer iterator still is here but now I assume it doesn't imply the error in lli? Hope you have any lead on that point, Pierre On 21 June 2016 at 09:10, Pierre Gagelin <Pierre.Gagelin at myport.ac.uk> wrote:> Hi, > > Thanks both of you for the help. I just missed that Create function had > many optional arguments... sorry for that. However my problem wasn't coming > from here (IRBuilder CreateCall function still return a pointer to CallInst > so I just added 2 times the call?). I didn't wanted to detail the all issue > previously because I knew I had a problem with my syntax. So here's my > problem: > > I am doing this replacement operation in a FunctionPass (this is no > restriction, I could do it on a ModulePass if that's a solution). On each > Function given I do an iteration over the instructions and replace (if it's > a call to the right function) the call. It's like this: > > bool FDPFunction::runOnFunction(Function &F) { > bool res = false; > TLI = &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(); > > for (inst_iterator i = inst_begin(F), e = inst_end(F); i != e; ++i) { > Instruction *I = &*i; > > if (!I) { > errs() << "error: null pointer instruction\n"; > break; > } else if (isMyFunctionCall(I, TLI)) { > errs() << "found a call to the function to replace\n"; > res = true; > replacement_function(I); > } else { > errs() << "default: trash instruction\n"; > } > } > > return res; > } > > The problem is that after the first replacement, the iterator becomes a > null pointer. With the break instruction the program is correctly > instrumented for the first call (about that: what is the use of > replaceAllUsesWith function? I thought it would replace all uses of the > function... but just one is done). I can then link it and execute with lli > (I still get a: "*** Error in `lli': corrupted double-linked list: > 0xaddress ***" but after the whole execution is done). > > But if I remove the break and the if condition associated, well I get a > null pointer exception : Assertion `Val && "isa<> used on a null pointer"' > failed > > I tried to clone the current instruction to not modify the iterator but > the ReplaceInstWithInst will cause troubles (probably because a copied > instruction has no parents): > > #0 0x0000000002a95b5c llvm::sys::PrintStackTrace(llvm::raw_ostream&) > /home/pierre/Desktop/llvm/lib/Support/Unix/Signals.inc:400:0 > #1 0x0000000002a95edf PrintStaI tried to clone the current instruction to > not modify the iterator but the ReplaceInstWithInst will cause > troublesckTraceSignalHandler(void*) > /home/pierre/Desktop/llvm/lib/Support/Unix/Signals.inc:468:0 > #2 0x0000000002a94145 llvm::sys::RunSignalHandlers() > /home/pierre/Desktop/llvm/lib/Support/Signals.cpp:44:0 > #3 0x0000000002a953a8 SignalHandler(int) > /home/pierre/Desktop/llvm/lib/Support/Unix/Signals.inc:254:0 > #4 0x00007fe358d3dd10 __restore_rt > (/lib/x86_64-linux-gnu/libpthread.so.0+0x10d10) > #5 0x00000000011fe489 llvm::iplist<llvm::Instruction, > llvm::SymbolTableListTraits<llvm::Instruction> > >::insert(llvm::ilist_iterator<llvm::Instruction>, llvm::Instruction*) > /home/pierre/Desktop/llvm/include/llvm/ADT/ilist.h:415:0 > #6 0x0000000002abc20d llvm::ReI tried to clone the current instruction to > not modify the iterator but the ReplaceInstWithInst will cause > troublesplaceInstWithInst(llvm::SymbolTableList<llvm::Instruction>&, > llvm::ilist_iterator<llvm::Instruction>&, llvm::Instruction*) > /home/pierre/Desktop/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp:198:0 > #7 0x0000000002abc2a5 llvm::ReplaceInstWithInst(llvm::Instruction*, > llvm::Instruction*) > /home/pierre/Desktop/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp:210:0 > > Any idea on what could be the cause of the null pointer and how to avoid > it? > > Thanks a lot for your time! > Pierre > > > On 20 June 2016 at 15:45, John Criswell <jtcriswel at gmail.com> wrote: > >> On 6/20/16 6:17 AM, Pierre Gagelin via llvm-dev wrote: >> >> Hi everyone, >> >> I am trying to replace the call of a certain function with a call to >> another function. It would for example replace the following: >> >> %call = tail call noalias i8* @func(i64 10) >> by >> %call = tail call noalias i8* @other_func(i64 10) >> >> I managed to declare other_func correctly but I am having troubles to >> understand how I should proceed to do the replacement. >> >> I tried to use ReplaceInstWithInst function as follows: >> >> CallInst *call_to_other_func_inst >> IRBuilder.CreateCall(ptr_to_other_func, args); >> ReplaceInstWithInst(call_to_func_inst, newI); >> >> LLVM builds correctly but the instrumentation crashes at optimization >> time. I know this isn't the correct way to do it because IRBuilder >> generates IR and I just want to have an instance of a CallInst. But I don't >> see how it is supposed to be done? >> >> >> Do you have assertions enabled? If so, is the crash an assertion failure >> and, if so, which assertion is failing? It's nearly impossible to tell >> what the problem is just by knowing that it is crashing. >> >> >> There are methods to create CallInst in the Instruction.h file but those >> needs to give an inserting point. Shoud I insert the call to other_func >> before the one to func and just remove the call instruction to func? >> >> >> Yes. You need to place the new call instruction within the same basic >> block as the old call instruction. Placing it right before the old call >> instruction is a good place. >> >> The code that Ashutosh provided is what I'd use to do what you're doing. >> >> Regards, >> >> John Criswell >> >> >> Thanks for your help, >> Pierre >> >> >> _______________________________________________ >> LLVM Developers mailing listllvm-dev at lists.llvm.orghttp://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev >> >> >> >> -- >> John Criswell >> Assistant Professor >> Department of Computer Science, University of Rochesterhttp://www.cs.rochester.edu/u/criswell >> >> >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20160621/a14bb39f/attachment-0001.html>
On 6/21/16 3:10 AM, Pierre Gagelin wrote:> Hi, > > Thanks both of you for the help. I just missed that Create function > had many optional arguments... sorry for that. However my problem > wasn't coming from here (IRBuilder CreateCall function still return a > pointer to CallInst so I just added 2 times the call?). I didn't > wanted to detail the all issue previously because I knew I had a > problem with my syntax. So here's my problem: > > I am doing this replacement operation in a FunctionPass (this is no > restriction, I could do it on a ModulePass if that's a solution). On > each Function given I do an iteration over the instructions and > replace (if it's a call to the right function) the call. It's like this: > > bool FDPFunction::runOnFunction(Function &F) { > bool res = false; > TLI = &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(); > > for (inst_iterator i = inst_begin(F), e = inst_end(F); i != e; ++i) { > Instruction *I = &*i; > > if (!I) { > errs() << "error: null pointer instruction\n"; > break; > } else if (isMyFunctionCall(I, TLI)) { > errs() << "found a call to the function to replace\n"; > res = true; > replacement_function(I); > } else { > errs() << "default: trash instruction\n"; > } > } > > return res; > } > > The problem is that after the first replacement, the iterator becomes > a null pointer.You might be invalidating the iterator after inserting the first CallInst. There are multiple ways to solve this problem: 1. Make your pass derive from the InstVistor class and implement a visitCallInst() method. I believe the iterators in the InstVistor class do not get invalidated when new instructions are added. 2. Iterate over all the instructions first and record the ones to replace in a container (e.g., a std::vector<>). A second loop iterates over the container and replaces all the CallInsts stored therein. 3. Look up the iterator invalidation rules for the instruction iterator and use the iterator in a way that does not invalidate the iterator. Regards, John Criswell> With the break instruction the program is correctly instrumented for > the first call (about that: what is the use of replaceAllUsesWith > function? I thought it would replace all uses of the function... but > just one is done). I can then link it and execute with lli (I still > get a: "*** Error in `lli': corrupted double-linked list: 0xaddress > ***" but after the whole execution is done). > > But if I remove the break and the if condition associated, well I get > a null pointer exception : Assertion `Val && "isa<> used on a null > pointer"' failed > > I tried to clone the current instruction to not modify the iterator > but the ReplaceInstWithInst will cause troubles (probably because a > copied instruction has no parents): > > #0 0x0000000002a95b5c llvm::sys::PrintStackTrace(llvm::raw_ostream&) > /home/pierre/Desktop/llvm/lib/Support/Unix/Signals.inc:400:0 > #1 0x0000000002a95edf PrintStaI tried to clone the current instruction > to not modify the iterator but the ReplaceInstWithInst will cause > troublesckTraceSignalHandler(void*) > /home/pierre/Desktop/llvm/lib/Support/Unix/Signals.inc:468:0 > #2 0x0000000002a94145 llvm::sys::RunSignalHandlers() > /home/pierre/Desktop/llvm/lib/Support/Signals.cpp:44:0 > #3 0x0000000002a953a8 SignalHandler(int) > /home/pierre/Desktop/llvm/lib/Support/Unix/Signals.inc:254:0 > #4 0x00007fe358d3dd10 __restore_rt > (/lib/x86_64-linux-gnu/libpthread.so.0+0x10d10) > #5 0x00000000011fe489 llvm::iplist<llvm::Instruction, > llvm::SymbolTableListTraits<llvm::Instruction> > >::insert(llvm::ilist_iterator<llvm::Instruction>, llvm::Instruction*) > /home/pierre/Desktop/llvm/include/llvm/ADT/ilist.h:415:0 > #6 0x0000000002abc20d llvm::ReI tried to clone the current instruction > to not modify the iterator but the ReplaceInstWithInst will cause > troublesplaceInstWithInst(llvm::SymbolTableList<llvm::Instruction>&, > llvm::ilist_iterator<llvm::Instruction>&, llvm::Instruction*) > /home/pierre/Desktop/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp:198:0 > #7 0x0000000002abc2a5 llvm::ReplaceInstWithInst(llvm::Instruction*, > llvm::Instruction*) > /home/pierre/Desktop/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp:210:0 > > Any idea on what could be the cause of the null pointer and how to > avoid it? > > Thanks a lot for your time! > Pierre > > > On 20 June 2016 at 15:45, John Criswell <jtcriswel at gmail.com > <mailto:jtcriswel at gmail.com>> wrote: > > On 6/20/16 6:17 AM, Pierre Gagelin via llvm-dev wrote: >> Hi everyone, >> >> I am trying to replace the call of a certain function with a call >> to another function. It would for example replace the following: >> >> %call = tail call noalias i8* @func(i64 10) >> by >> %call = tail call noalias i8* @other_func(i64 10) >> >> I managed to declare other_func correctly but I am having >> troubles to understand how I should proceed to do the replacement. >> >> I tried to use ReplaceInstWithInst function as follows: >> >> CallInst *call_to_other_func_inst >> IRBuilder.CreateCall(ptr_to_other_func, args); >> ReplaceInstWithInst(call_to_func_inst, newI); >> >> LLVM builds correctly but the instrumentation crashes at >> optimization time. I know this isn't the correct way to do it >> because IRBuilder generates IR and I just want to have an >> instance of a CallInst. But I don't see how it is supposed to be >> done? > > Do you have assertions enabled? If so, is the crash an assertion > failure and, if so, which assertion is failing? It's nearly > impossible to tell what the problem is just by knowing that it is > crashing. > >> >> There are methods to create CallInst in the Instruction.h file >> but those needs to give an inserting point. Shoud I insert the >> call to other_func before the one to func and just remove the >> call instruction to func? > > Yes. You need to place the new call instruction within the same > basic block as the old call instruction. Placing it right before > the old call instruction is a good place. > > The code that Ashutosh provided is what I'd use to do what you're > doing. > > Regards, > > John Criswell > >> >> Thanks for your help, >> Pierre >> >> >> _______________________________________________ >> LLVM Developers mailing list >> llvm-dev at lists.llvm.org <mailto:llvm-dev at lists.llvm.org> >> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev > > > -- > John Criswell > Assistant Professor > Department of Computer Science, University of Rochester > http://www.cs.rochester.edu/u/criswell > >-- John Criswell Assistant Professor Department of Computer Science, University of Rochester http://www.cs.rochester.edu/u/criswell -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20160621/e3ed6c3e/attachment.html>
You might be invalidating the iterator after inserting the first CallInst. There are multiple ways to solve this problem:> > > 1. Make your pass derive from the InstVistor class and implement a > visitCallInst() method. I believe the iterators in the InstVistor class do > not get invalidated when new instructions are added. > 2. Iterate over all the instructions first and record the ones to > replace in a container (e.g., a std::vector<>). A second loop iterates > over the container and replaces all the CallInsts stored therein. > 3. Look up the iterator invalidation rules for the instruction > iterator and use the iterator in a way that does not invalidate the > iterator. > > Good call, method 2. is working fine. I remember seeing such pattern inBoudsChecking code. I guess I am not the first having troubles with this. I took a quick look at the iterator problem - For the cloned instruction, the problem is it has no parents and I guess it implies it has no link with previous or next instructions. So some nullpointers will appear when inserting the instruction because it will try to build the double linked list of instructions (I think that's the algorithmic structure employed). - For the regular iterator the problem might be just the same. As it is a double linked list, when you replace the current instruction with another the current instruction probably is erased. I already made the changes so I won't try to generate the error again but I thinks that makes sense.> > > > Regards, > > John Criswell > > Thanks a lot! About the lli error it appears to have an undefinedbehavior. Some times it runs correctly, most of the times it freezes and sometimes I get the lli error. Anyway, the fact the error says that the double-linked list is corrupted make sense with my thoughts about the iterator issue. Pierre -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20160622/cfac8775/attachment.html>