LLVM "fatal errors" 真的致命吗?

Are LLVM "fatal errors" really fatal?

我想知道 LLVM 致命错误是否真的 "fatal" - 即。它们使系统的整个状态无效并且不可恢复。

例如(我使用的是llvm-c接口),以下代码的默认行为:

   LLVMMemoryBufferRef mb = LLVMCreateMemoryBufferWithMemoryRange(somedata, data_length, "test", 0);
   LLVMModuleRef module; 
   if (LLVMParseBitcode2(mb, &module) != 0) {
      fprintf(stderr, "could not parse module bitcode");
   }

如果指针 somedata 指向无效的位码,则永远不会执行 fprintf,而是整个过程中止并在 stderr 上显示其自己的致命错误消息。

但是,据说有一个接口可以捕获此类错误:LLVMFatalErrorHandler。但是,在安装错误处理程序后,进程仍然只是中止而没有调用错误处理程序。

LLVM 中的文档总体上很差,C 接口几乎没有文档。但是,如果某些位码已损坏,则以强制方式中止整个过程似乎是超级脆弱的设计!

所以,我想知道这里的 "fatal" 是否像往常一样暗示 - 如果发生这样的错误,我们可能无法恢复并继续使用该库(例如尝试一些不同的位码或修复旧的例如,一个),或者如果它不是真正的 "fatal" 错误,我们可以使用 FatalErrorHandler 或其他一些捕获和通知的方法,或采取其他补救措施,然后继续该程序。

好的,在阅读了 10 多个小时的 LLVM 源代码并寻求友好的 LLVM 开发人员的帮助之后,这里的答案是这实际上不是致命错误,毕竟!

上面在 C 接口中调用的函数已被弃用,应该被删除; LLVM 曾经有一个 "global context" 的概念,并且在几年前被删除了。正确的方法是在创建 LLVMContext 实例后使用 LLVMDiagnosticInfo 接口并使用特定于上下文的位码 reader 函数:

   void llvmDiagnosticHandler(LLVMDiagnosticInfoRef dir, void *p) {
      fprintf(stderr, "LLVM Diagnostic: %s\n", LLVMGetDiagInfoDescription(dir));
   }

   ...

   LLVMContextRef llvmCtx = LLVMContextCreate();
   LLVMContextSetDiagnosticHandler(llvmCtx, llvmDiagnosticHandler, NULL);
   LLVMMemoryBufferRef mb = LLVMCreateMemoryBufferWithMemoryRange(somedata, data_length, "test", 0);
   LLVMModuleRef module; 
   if (LLVMGetBitcodeModuleInContext2(llvmCtx, mb, &module) != 0) {
      fprintf(stderr, "could not parse module bitcode");
   }

LLVMDiagnosticInfo 还带有一个 "severity" 代码,指示错误的严重性(有时仅返回警告或性能提示)。另外,正如我所怀疑的那样,未能解析位码并不是使库或上下文状态无效的情况。

中止并显示错误消息的代码只是权宜之计,让仍然调用旧 API 函数的遗留应用程序正常工作 - 它设置了一个上下文和一个最小的错误处理程序,其行为这样。