Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

LLVM pass: Error when iterating over Module functions list

Tags:

llvm

I am trying in a LLVM pass to iterate over a Module functions list using the list returned by llvm::Module::getFunctionList(). I use a loop like this one:

    for (auto curFref = M->getFunctionList().begin(), 
              endFref = M->getFunctionList().end(); 
              curFref != endFref; ++curFref) {
        errs() << "found function: " << curFref->getName() << "\n";
    }

The first iteration of this loop retrieves a function, as expected, but it does not detect the end of the list and continues just to get in subsequent iterations other objects which are not functions (as reported by their getName()), such as that function parameter. After a few iterations it probably reaches some garbage (or NULL) and crash on reference to the current "function" reference. For example, for this program:

int foo(int k) {
    int i, s = 0;
    for (i = 0; i < k; ++i)
        s += i;
    return s;
}

Which becomes this IR code:

...
; Function Attrs: nounwind uwtable
define i32 @foo(i32 %k) #0 {
entry:
...

The output would look like this:

found function: foo
found function: k
found function: #0 0x00007f481f77c46e llvm::sys::PrintStackTrace(llvm::raw_ostream&) /home/me/work/llvm-3.8.0/lib/Support/Unix/Signals.inc:322:0
...

So you can see that after correctly iterating over foo it continued to objects such as the parameter k.

I tried this both in a Module pass (in the runOnModule()) as well as in a Function pass (using F.getParent() to query the containing Module), and got the same results.

The problem is also replicated on both LLVM 3.8.0 as well as LLVM 3.5.2 .

Any idea what am I missing that I fail to iterate correctly over the returned functions list?

=====

EDIT:

Note that the same behavior is shown when using alternative iteration over the Functions of a Module, such as when using M.begin()/end() for the iterator or even when using C++11 range-based for loop:for (Function &curF: M) ....

In addition, M.getFunctionList().size() cause segmentation fault while it tries to iterate over the list items. So it seems like the functions list is indeed corrupt. But that is the list I get at the very start of runOnModule() entry point. So it does not seem like something that was broken by my code.

======

EDIT 2:

I have no idea if this matters, but my LLVM pass is built externally from the LLVM source tree as a dynamically loadable library and then loaded into opt using the -load=foo.so command line option.

like image 866
ElazarR Avatar asked Sep 19 '25 15:09

ElazarR


1 Answers

I'm one of the core LLVM developers.

This is almost certainly a buggy checkout of LLVM, a miscompiled LLVM, or a problem with the fact that your pass is being built as a separate DSO (although I don't see how that could be it).

Numerous parts of LLVM use M->functions() (or M->begin() & M->end()) to iterate only functions. These parts would fail consistently if the behavior was broken. The only difference between these mechanisms and accessing the function list directly as M->getFunctionList() does is whether the list is mutable. For the use case you show, they should be precisely the same behavior.

I would suggest trying to run the LLVM test suite to make sure it works correctly. If you use the Ninja CMake generator (as I would recommend) to build LLVM:

% ninja check-llvm

If this fails, especially if it crashes in similar areas, that seems an extremely good indication that the problem is something in your copy of LLVM.

Regardless, SO isn't a great place to get further help here. The answer to the question is "that should in fact work" and I've checked the code in LLVM and I don't see any obvious explanations. So my suggestion would be to try the above, try a fresh copy of LLVM (perhaps top of tree, or the latest release). Make sure you have a sufficiently modern host toolchain for building LLVM. See this section for details: http://llvm.org/docs/GettingStarted.html#host-c-toolchain-both-compiler-and-standard-library

If all else fails, try reaching out to the developers on the mailing list: http://lists.llvm.org/mailman/listinfo/llvm-dev

Or try the IRC channel: http://llvm.org/docs/#irc

Hope this helps!

like image 131
Chandler Carruth Avatar answered Sep 23 '25 14:09

Chandler Carruth