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

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

   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上显示其自己的致命错误消息。

但是,应该有一个捕获此类错误的接口(interface):LLVMFatalErrorHandler。但是,安装错误处理程序后,该过程仍会中止而不会调用该错误处理程序。

LLVM中的文档总体而言非常差,而C接口(interface)几乎完全没有文档。但是,如果某些位码损坏,以强制性的方式终止整个过程似乎是超脆弱的设计!

因此,我想知道“致命”是否像往常一样意味着-如果发生此类错误,我们可能无法恢复并继续使用该库(例如,尝试某些不同的位码或修复旧的位码),或者如果这不是真正的“致命”错误,我们可以使用FatalErrorHandler或其他某种方式进行捕获和通知,或者采取其他补救措施,然后继续执行该程序。

最佳答案

好吧,在通读LLVM源码10多个小时并获得友好的LLVM开发人员的帮助后,这里的答案是,毕竟这实际上并不是致命的错误!

上面在C接口(interface)中调用的功能已被弃用,应该删除。 LLVM曾经有一个“全局上下文”的概念,并且在几年前已被删除。正确的方法是-在创建LLVMDiagnosticInfo实例并使用特定于上下文的位码读取器功能之后,使用LLVMContext接口(interface),以便可以捕获和处理该错误而不会中止该过程-

   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还带有“严重性”代码,用于指示错误的严重性(有时仅返回警告或性能提示)。另外,正如我所怀疑的,不是没有解析位代码会使库或上下文状态失效的情况。

因粗鲁的错误消息而中止的代码只是一个权宜之计,它可以使仍称为旧API函数的旧版应用程序正常工作-它设置了上下文和以这种方式运行的最小错误处理程序。

10-06 13:37