LLVM的“致命错误”真的致命吗?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LLVM的“致命错误”真的致命吗?相关的知识,希望对你有一定的参考价值。

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

例如(我正在使用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接口几乎没有文档。但是,如果某些位码损坏,以强制方式终止整个过程似乎是超脆弱的设计!

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

答案

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

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

   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函数的旧版应用程序可以正常工作-它设置了上下文和以这种方式运行的最小错误处理程序。

以上是关于LLVM的“致命错误”真的致命吗?的主要内容,如果未能解决你的问题,请参考以下文章

kCLErrorNetwork 是核心位置的“致命”错误吗?

ubuntu 上的 npm 致命错误,知道吗?

Java致命错误,不知道啥意思

我收到错误:致命错误:索引超出范围

UIview中的两个表视图致命错误

安装 WP 后出现致命错误,是 wp-settings.php 的问题吗?