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曾经有一个"全局上下文"的概念,几年前就被删除了。 执行此操作的正确方法 - 以便在不中止进程的情况下捕获和处理此错误 - 是在创建LLVMContext实例并使用特定于上下文的位码读取器函数后使用LLVMDiagnosticInfo接口:

void llvmDiagnosticHandler(LLVMDiagnosticInfoRef dir, void *p) {
fprintf(stderr, "LLVM Diagnostic: %sn", 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 函数的旧应用程序工作 - 它设置了一个上下文和一个以这种方式运行的最小错误处理程序。

最新更新