Я пытаюсь использовать llvm pass для преобразования вызова функции pthread_create
в обычный вызов функции в родительском потоке вместо дочернего потока. Простая иллюстрация ввода и вывода показана ниже. Однако когда я пытаюсь использовать eraseFromParent для удаления оригинала pthread_create CallInst
, это всегда вызывает ошибку сегментации. После более глубокого погружения я обнаружил, что инструкция всегда возвращает false
из mayHaveSideEffect . Я действительно не знаю, почему удаление инструкции вызовет какой-либо побочный эффект.
void *foo(void *args) {
sleep(2);
}
int main() {
pthread_t tid;
pthread_create(&tid, NULL, foo, NULL);
// => foo();
pthread_join();
}
Спасибо за комментарий @ arnt. Вот именно то, что я хочу сделать. Я создаю CallInst, вызываемый функцией foo, и заменю его исходным вызовом функции pthread_create
.
for (auto &inst: main_func) { // Iterate every instructions in the main function
if (isa<CallInst>(inst)) {
CallInst *ci = dyn_cast<CallInst>(&inst);
if (ci->getCalledFunction()->getName().compare("pthread_create") == 0) {
Function *start_routine = dyn_cast<Function>(ci->getArgOperand(2));
Value *routine_args[1] = { ci->getArgOperand(3) };
ArrayRef<Value *> arr_ref(routine_args);
// Create a new CallInst and insert it before the "pthread_create" call instruction
CallInst *foo = CallInst::create(start_routine, arr_ref, "startRoutineOutput", ci);
ci->eraseFromParent(); // Segmentation fault happens here.
}
}
}