Segment error when moving codes from `main` function to another function

I follow 《 Getting Started with LLVM Core Libraries》 to write a custom LLVM IR generator, which generates a bitcode file. The bitcode file can be parsed with llvm-dis. llvm 3.4 used in the book is outdated, I used llvm 3.9.1 instead. After struggling several compilication error, the project is compiled successfully Finally. The code (omit header files for shorter code) works finally is below:

int main()
{
    LLVMContext context; 
    Module *mod = new Module("sum.ll",context);
    SmallVector<Type*,2> FuncTyArgs;
    FuncTyArgs.push_back(IntegerType::get(mod->getContext(),32));
    FuncTyArgs.push_back(IntegerType::get(mod->getContext(),32));
    FunctionType *FuncTy = FunctionType::get(IntegerType::get(mod->getContext(),32),
                                            FuncTyArgs,
                                            false);                             
    Function *funcSum = Function::Create(FuncTy,
                                        GlobalValue::ExternalLinkage,
                                        "sum",
                                        mod
                                        );
    funcSum->setCallingConv(CallingConv::C);
    Function::arg_iterator args = funcSum->arg_begin();
    Argument *arg_a = &(*args);
    args++;
    Value *int32_a = arg_a;
    int32_a->setName("a");
    Value *int32_b = &(*args);
    int32_b->setName("b");
    BasicBlock *labelEntry = BasicBlock::Create(mod->getContext(),
                                                "entry",
                                                funcSum,
                                                0);   
    AllocaInst *ptrA = new AllocaInst(IntegerType::get(mod->getContext(),32),
                                    "a.addr",labelEntry);
    ptrA->setAlignment(4);
    AllocaInst *ptrB = new AllocaInst(IntegerType::get(mod->getContext(),32),
                                    "b.addr",labelEntry);
    ptrB->setAlignment(4);

    StoreInst *st0 = new StoreInst(int32_a, ptrA, false,
                                  labelEntry);
    st0->setAlignment(4);
    StoreInst *st1 = new StoreInst(int32_b, ptrB, false,
                                labelEntry);
    st1->setAlignment(4);

    LoadInst *ld0 = new LoadInst(ptrA, "", false,
                                labelEntry);
    ld0->setAlignment(4);

    LoadInst *ld1 = new LoadInst(ptrB, "", false,
                                labelEntry);
    ld1->setAlignment(4); 

    BinaryOperator *addRes = 
        BinaryOperator::Create(Instruction::Add, ld0, ld1,
                    "add", labelEntry);
    ReturnInst::Create(mod->getContext(),addRes,labelEntry);  
    std::string error_str;
    raw_string_ostream error_stream(error_str);
    bool fail = verifyModule(*mod,&error_stream);
    if(!fail)
    {
        std::cout <<"Module is valid.\n";
    }else{
        std::cerr << "Module is invalid: " << error_str << std::endl;
        return 1;
    }
    
    std::error_code EC;
    std::unique_ptr<tool_output_file> Out(new tool_output_file("./sum.bc",
                                            EC,sys::fs::F_None));

    if (EC)
    {
        errs() << "Error open file:"<<EC.message() << "\n";
        return 1;
    }
    raw_fd_ostream file("sum.bc", EC, sys::fs::F_None);
    WriteBitcodeToFile(mod,file);
    Out->keep();
    return 0;
}

if I move code related to IR build, I can compile it successfully. But an segment fault occurs in running-time.

$ ./getsumll                                                                                               [13:32:22]
[1]    2283352 segmentation fault  ./getsumll

How strange? I don’t modify any code, just encapsulate them into a new function(It‘s also the way used in the book). the new code is below

Module* makeLLVMModule(){
    LLVMContext context;
    Module *mod = new Module("sum.ll",context);
    SmallVector<Type*,2> FuncTyArgs;
    FuncTyArgs.push_back(IntegerType::get(mod->getContext(),32));
    FuncTyArgs.push_back(IntegerType::get(mod->getContext(),32));
    FunctionType *FuncTy = FunctionType::get(IntegerType::get(mod->getContext(),32),
                                            FuncTyArgs,
                                            false);
                                            
    Function *funcSum = Function::Create(FuncTy,
                                        GlobalValue::ExternalLinkage,
                                        "sum",
                                        mod
                                        );
    funcSum->setCallingConv(CallingConv::C);
    
    Function::arg_iterator args = funcSum->arg_begin();
    Argument *arg_a = &(*args);
    args++;
    Value *int32_a = arg_a;
    int32_a->setName("a");
    Value *int32_b = &(*args);
    int32_b->setName("b");

    BasicBlock *labelEntry = BasicBlock::Create(mod->getContext(),
                                                "entry",
                                                funcSum,
                                                0);   

    AllocaInst *ptrA = new AllocaInst(IntegerType::get(mod->getContext(),32),
                                    "a.addr",labelEntry);
    ptrA->setAlignment(4);
    AllocaInst *ptrB = new AllocaInst(IntegerType::get(mod->getContext(),32),
                                    "b.addr",labelEntry);
    ptrB->setAlignment(4);

    StoreInst *st0 = new StoreInst(int32_a, ptrA, false,
                                  labelEntry);
    st0->setAlignment(4);
    StoreInst *st1 = new StoreInst(int32_b, ptrB, false,
                                labelEntry);
    st1->setAlignment(4);

    LoadInst *ld0 = new LoadInst(ptrA, "", false,
                                labelEntry);
    ld0->setAlignment(4);

    LoadInst *ld1 = new LoadInst(ptrB, "", false,
                                labelEntry);
    ld1->setAlignment(4); 

    BinaryOperator *addRes = 
        BinaryOperator::Create(Instruction::Add, ld0, ld1,
                    "add", labelEntry);
    ReturnInst::Create(mod->getContext(),addRes,labelEntry);
    return mod;
}

int main()
{
    Module *mod = makeLLVMModule();//get return value from MakeLLVMModule
    std::string error_str;
    raw_string_ostream error_stream(error_str);
    bool fail = verifyModule(*mod,&error_stream);
    if(!fail)
    {
        std::cout <<"Module is valid.\n";
    }else{
        std::cerr << "Module is invalid: " << error_str << std::endl;
        return 1;
    }
    
    std::error_code EC;
    std::unique_ptr<tool_output_file> Out(new tool_output_file("./sum.bc",
                                            EC,sys::fs::F_None));

    if (EC)
    {
        errs() << "Error open file:"<<EC.message() << "\n";
        return 1;
    }
    raw_fd_ostream file("sum.bc", EC, sys::fs::F_None);
    WriteBitcodeToFile(mod,file);
    Out->keep();
    return 0;
}

Any help will be appreciated!

You create a module with a reference to the locally allocated context which is destroyed at the end of the makeLLVMModule function call, which leads to your segmentation error when you return the module and try to use it. You can fix it by changing makeLLVMModule to accept LLVMContext &context as a parameter and passing it from your main.

You’re right. I change makeLLVMModule() to makeLLVMModule(LLVMContext &context) and pass context from main. The error is fixed. Maybe I misunderstand what the previous getGlobalContext() means, this deprecated function should return a static LLVMContext type variable. Just like this show.
make LLVMContex perform like old version
Finally, thanks very much for your help!