Ich versuche in einem LLVM-Durchgang, über eine Modulfunktionsliste mit der von llvm::Module::getFunctionList()
zurückgegebenen Liste zu iterieren. Ich benutze eine Schleife wie diese:LLVM-Pass: Fehler beim Iterieren der Modulfunktionsliste
for (auto curFref = M->getFunctionList().begin(),
endFref = M->getFunctionList().end();
curFref != endFref; ++curFref) {
errs() << "found function: " << curFref->getName() << "\n";
}
Die erste Iteration dieser Schleife eine Funktion ruft, wie erwartet, aber nicht das Ende der Liste erkennen und weiterhin nur in nachfolgenden Iterationen andere Objekte zu erhalten, die nicht funktioniert (wie von ihren getName()
gemeldet), wie dieser Funktionsparameter. Nach ein paar Iterationen erreicht es wahrscheinlich etwas Müll (oder NULL) und stürzt bei einem Verweis auf die aktuelle "Funktions" -Referenz ab. Zum Beispiel für dieses Programm:
int foo(int k) {
int i, s = 0;
for (i = 0; i < k; ++i)
s += i;
return s;
}
Welche dieser IR-Code wird:
...
; Function Attrs: nounwind uwtable
define i32 @foo(i32 %k) #0 {
entry:
...
Die Ausgabe würde wie folgt aussehen:
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 können Sie sehen, dass nach richtig Iterieren über foo
ging es weiter zu Objekten wie dem Parameter k
.
Ich versuchte dies sowohl in einem Modul-Durchlauf (in der runOnModule()
) als auch in einem Function-Durchlauf (mit F.getParent(), um das beinhaltende Modul abzufragen) und erhielt die gleichen Ergebnisse.
Das Problem wird auch auf LLVM 3.8.0 sowie LLVM 3.5.2 repliziert.
Eine Idee, was fehlt mir, dass ich nicht ordnungsgemäß über die zurückgegebene Funktionen Liste iterieren?
=====
EDIT:
Beachten Sie, dass das gleiche Verhalten bei der Verwendung von alternativer Iteration über die Funktionen eines Moduls angezeigt wird, wie wenn M.begin()/end()
für den Iterator oder auch bei Verwendung von C++ 11 bereichsbasierte for
loop: for (Function &curF: M) ...
.
Darüber hinaus verursachen M.getFunctionList().size()
Segmentierungsfehler, während es versucht, über die Listenelemente zu iterieren. Es scheint also so, als ob die Liste der Funktionen tatsächlich korrupt ist. Aber das ist die Liste, die ich am Anfang von runOnModule()
Einstiegspunkt bekomme. Es scheint also nicht etwas zu sein, das durch meinen Code gebrochen wurde.
======
EDIT 2:
Ich habe keine Ahnung, ob diese Dinge, aber mein LLVM Pass extern von dem LLVM Quellbaum als dynamisch ladbare Bibliothek gebaut wird und dann geladen opt
mit der Befehlszeilenoption -load=foo.so
.
Die Antwort von @Chandler Carruth löste das Problem. Im Kern seiner Antwort empfahl er, LLVM mit Ninja/cmake zu erstellen, als ich LLVM mit make/configure erstellte. Der Wiederaufbau mit Ninja/cmake hat dieses Problem beseitigt. Während die Versionshinweise zu LLVM 3.8.0 darauf hindeuten, dass das Erstellen mit make/configure weiterhin unterstützt wird, deutet dieses Problem darauf hin, dass es irgendwie kaputt ist. – ElazarR