LLVM segmentation fault / need use Instruction instead of Instruction*

Hello everyone,

I have a segmentation fault while running an LLVM pass. I need to use BBterminators array outside the iterating “for” loop for basic blocks. It seems that LLVM does not protect the addresses ( note: TerminatorInst BasicBlock::getTerminator() ) when iterating through the loop, so I need to keep in BBterminators “Instruction” type elements, not "Instruction ". How can I copy entire Instructions into BBterminators?

for (Function::iterator II = F.begin(), EE = F.end(); II != EE; ++II, ++ii)
{
… // not relevant code ;

BasicBlock* BB=(dyn_cast(II));

if (BB->getTerminator())
{
Instruction* current = BB->getTerminator();

Instruction* previous = current->getPrevNode();

if (current->getOpcode()==Instruction::Br)
{

BBterminators[ii]=current;
…// not relevant code

where Instruction** BBterminators = new Instruction*[100];

Thank you a lot !
Alex

  1. Make sure that the rest of the code isn’t inserting or remove instructions or basic blocks as you iterate. That can invalidate the iterators. Using invalidated iterators can cause a segmentation fault. 2) Make sure that you’re not writing past the end of BBterminators. My recommendation is to either allocate BBterminators with sufficient size (you can find the number of basic blocks and then use that to allocate the size) or to use a dynamically sized container (std::vector, std::set, or one of the LLVM classes that provide a more efficient implementation of these). 3) Make sure you’re not leaking memory by not freeing BBterminators. If the call to new returns a NULL pointer due to memory exhaustion, that could cause the segfault. 4) You may just have to roll up your sleeves and figure out what is causing the invalid memory reference. Tools like Address Sanitizer and SAFECode may help you narrow down the problem. Clang’s static analyzer may help, too. This above line shouldn’t require a dyn_cast. You should be able to use something like: BasicBlock * BB = *I; or BasicBlock * BB = I; If you’re going to use a cast, use cast<> instead of dyn_cast<>. If the cast fails, you’ll get an assertion if asserts are enabled. You should never get anything other than a BasicBlock when iterating through a function. – John T.

Hello John,

I was following your procedures and I isolated the problem. The problem are represented by the basic blocks with only one elements.

for (Function::iterator II = F.begin(), EE = F.end(); II != EE; ++II, ++ii)
{
BasicBlock* BB=II;

if (BB->getTerminator())
{
Instruction* current = BB->getTerminator();

Instruction* previous;

errs()<<“AAA\n”;
if(current->getPrevNode())
{
errs()<<“BBB\n”;
previous = current->getPrevNode();
ok=1;
}

if (ok)

Hello John,

I was following your procedures and I isolated the problem. The problem are represented by the basic blocks with only one element.

for (Function::iterator II = F.begin(), EE = F.end(); II != EE; ++II, ++ii)
{

BasicBlock* BB=II;

if (BB->getTerminator())
{
Instruction* current = BB->getTerminator();

Instruction* previous;

errs()<<“AAA\n”;
if(current->getPrevNode())
{
errs()<<“BBB\n”;
previous = current->getPrevNode();
ok=1;
}

if (ok){
errs()<<“CCC\n”;

It does print AAA, but then I have the segfault. So when I am evaluating the current->getPrevNode() condition, I got the segfault.
Do you know how can I solve this?

Thank you
Alex

I may be mistaken as I just took a quick look, but in ilist_node the function “getPrevNode()” actually calls a method on the previous node:

NodeTy *getPrevNode() {
NodeTy *Prev = this->getPrev();

// Check for sentinel.
if (!Prev->getNext())
return 0;

return Prev;
}

http://llvm.org/docs/doxygen/html/ilist__node_8h_source.html#l00058

Try checking if current->getPrev() is null before calling current->getPrevNode().

Stephen

Alexandru Ionut Diaconescu <alexandruionutdiaconescu@gmail.com> writes:

I was following your procedures and I isolated the problem. The problem are
represented by the basic blocks with only one element.

for (Function::iterator II = F.begin(), EE = F.end(); II != EE; ++II, ++ii)
{
BasicBlock* BB=II;

if (BB->getTerminator())
    {
        Instruction* current = BB->getTerminator();

        Instruction* previous;

        errs()<<"AAA\n";
        if(*current->getPrevNode()*)
        {
            errs()<<"BBB\n";
            previous = current->getPrevNode();
            ok=1;
        }

        if (ok){
           errs()<<"CCC\n";
              ........

It does print AAA, but then I have the segfault. So when I am evaluating
the *current->getPrevNode() *condition, I got the segfault.
Do you know how can I solve this?

The documentation for BasickBlock::getTerminator says:

  /// getTerminator() - If this is a well formed basic block, then this returns
  /// a pointer to the terminator instruction. If it is not, then you get a
  /// null pointer back.

Maybe BB is not well formed (it doesn't have proper terminator) and
BB->getTerminator returns NULL ?

Hello,

Thank you for your answer. If I want to use

then I have

error: ‘NodeTy* llvm::ilist_half_node::getPrev() [with NodeTy = llvm::Instruction]’ is protected
error: ‘llvm::ilist_half_nodellvm::Instruction’ is not an accessible base of ‘llvm::Instruction’

Do you know any other method to access the previous instruction of a terminator instruction? PS: back() is not an option.

getPrevNode ()
Get the previous node, or 0 for the list head.
I don’t see any method like hasPrevNode.
It can be a weird problem because “current->getPrevNode()” is indicating to “current” itself (the problem appears for the BB with only one element)?

I solved by checking

if(BB->size()>1)

Thank you all for the help !

Now debugging the next segfault.

Ah, sorry, I failed to pay attention to the protection level.

Your way should work, although you could also consider checking if BB->begin() points to the same thing as BB->getTerminator() - if so, the terminator instruction is the first instruction (if you want to ignore PHI nodes for this case, could compare BB->getFirstNonPHI() to BB->getTerminator().) Personal choice really, I think.

Stephen