iovisor / bcc

BCC - Tools for BPF-based Linux IO analysis, networking, monitoring, and more
Apache License 2.0
20.31k stars 3.85k forks source link

LLVM hard failure on compilation error #1081

Open palmtenor opened 7 years ago

palmtenor commented 7 years ago

It seems that LLVM will hard fail and call exit() for some failures

This is bad for continuous profiling / monitoring tool that loads BPF module on-demand. Is it possible we can make it just return error or throw exception, so that the rest of the world can go on even if the BPF program compilation failed?

Example stack:

    @ 00007f1625787a89 __run_exit_handlers
    @ 00007f1625787ad4 __GI_exit
    @ 00007f162412cdcd llvm::report_fatal_error(llvm::Twine const&, bool)
                       -> /home/engshare/third-party2/glibc/2.20/src/glibc-2.20/csu/../sysdeps/x86_64/crtn.S
    @ 00007f16234a3631 llvm::RuntimeDyldImpl::resolveExternalSymbols()
                       -> /home/engshare/third-party2/glibc/2.20/src/glibc-2.20/csu/../sysdeps/x86_64/crtn.S
    @ 00007f16234a3684 llvm::RuntimeDyldImpl::resolveRelocations()
                       -> /home/engshare/third-party2/glibc/2.20/src/glibc-2.20/csu/../sysdeps/x86_64/crtn.S
    @ 00007f162348dcba llvm::MCJIT::finalizeLoadedModules()
                       -> /home/engshare/third-party2/glibc/2.20/src/glibc-2.20/csu/../sysdeps/x86_64/crtn.S
    @ 00007f162348e1fc llvm::MCJIT::finalizeObject()
                       -> /home/engshare/third-party2/glibc/2.20/src/glibc-2.20/csu/../sysdeps/x86_64/crtn.S
    @ 00007f162229dc39 ebpf::BPFModule::finalize()
                       /home/engshare/third-party2/bcc-cpp/0.1.7/src/cc/bpf_module.cc:440
    @ 00007f16222bca20 ebpf::BPF::init(std::basic_fbstring<char, std::char_traits<char>, std::allocator<char>, std::fbstring_core<char> > const&, std::vector<std::basic_fbstring<char, std::char_traits<char>, std::allocator<char>, std::fbstring_core<char> >, std::allocator<std::basic_fbstring<char, std::char_traits<char>, std::allocator<char>, std::fbstring_core<char> > > >, std::vector<ebpf::USDT, std::allocator<ebpf::USDT> >)
                       /home/engshare/third-party2/bcc-cpp/0.1.7/src/cc/BPF.cc:71
drzaeus77 commented 7 years ago

Yeah this has always bothered me...if libbcc is linked into a long-lived service then this will be a big problem. One could always run the compilation in a child process and hand the fd's back through SCM_RIGHTS.

palmtenor commented 7 years ago

Do we want to make that a general behavior for BCC (i.e., BPFModule will start compilation work in new process) or users should be doing that (i.e. users start BPF / BPFModule in new fork)?

Also would the FD_CLOEXEC flag we use across the stack be a problem if we want to do this "compile in another process" thing?

drzaeus77 commented 7 years ago

IMO depends how complicated the code ends up being, and if if there is any usability impact (performance, features). Probably deserves a prototype, but roughly it should fit into the BPFModule class somewhere, maybe with a mode similar to TableStorage (with a private impl member) that can be switched according to the user's desires.