我正在编写一个小型库,它将FILE *指针作为输入。
如果我立即检查此FILE *指针并发现它导致段错误,处理信号,设置errno并正常退出是否更正确;或者什么也不做,并使用调用者已安装的信号处理程序,如果他有一个?
流行的智慧似乎是“图书馆永远不会导致崩溃”。但我的想法是,由于这个特定的信号肯定是来电者的错,所以我不应该试图向他隐瞒这些信息。他可能安装了自己的处理程序,以自己的方式对问题作出反应。可以使用errno检索相同的信息,但是SIGSEGV的默认处置设置是有充分理由的,并且通过强制调用者处理他的错误,或通过崩溃并保护他免受进一步损害来传递信号尊重这一理念。 。
您是否同意此分析,或者您是否看到在这种情况下处理SIGSEGV的一些令人信服的理由?
答案 0 :(得分:7)
接管处理程序不是图书馆业务,我会说除非明确要求,否则对它们有些冒犯。为了最大限度地减少崩溃,库可能会在某种程度上验证其输入。除此之外:垃圾进入 - 垃圾出来。
答案 1 :(得分:5)
流行的智慧似乎是“图书馆永远不会导致崩溃。”
我不知道你从哪里得到 - 如果他们传递了无效的指针,你应该崩溃。任何图书馆都会。
答案 2 :(得分:3)
我认为检查NULL
指针的特殊情况是合理的。但除此之外,如果他们通过垃圾,他们违反了该功能的合同,他们就会崩溃。
答案 3 :(得分:2)
这是一个主观问题,可能不适合SO,但我会提出我的观点:
以这种方式思考:如果你有一个函数,它接受一个以nul结尾的char *
字符串,并且记录如此,并且调用者传递一个没有nul终结符的字符串,你应该捕获信号和slap手腕上的来电者?或者你应该让它崩溃并让使用你的API的坏程序员修复他/她的代码?
如果您的代码采用FILE *
指针,并且您的文档显示“通过任何打开FILE *
”,并且他们传递了已关闭或无效的FILE *
对象,则他们违反了合同。检查这种情况会减慢那些正确使用你的库的人的代码,以适应没有这种情况的人,而让它崩溃会让那些阅读文档和编写好代码的人尽可能快地保存代码。
您是否期望通过无效FILE *
指针的人检查并正确处理错误?或者他们是否更有可能盲目地继续,导致之后的另一次崩溃,在这种情况下处理此崩溃可能只是掩盖了错误?
答案 4 :(得分:1)
内核不应该崩溃,但库可能应该。这并不意味着你不应该做错误检查;面对不合理的糟糕数据,一个好的程序会立即死亡。我更倾向于使用assert(f!= NULL)进行库调用保释,而不是仅使用trundle on并最终取消引用NULL指针。
答案 5 :(得分:0)
很抱歉,但是说图书馆应该崩溃的人只是懒惰(可能考虑到时间,以及开发工作)。库是函数的集合。除了软件中的其他功能之外,库代码不应该“崩溃”,而应该“崩溃”。
当然,如果通常会涉及多种语言或(例如异常)异常语言特征,那么库可能会遇到一些关于如何跨API边界传递错误的问题,但没有什么 TOO 特别关于那。实际上,这只是编写库的一部分,而不是应用程序内代码。
除非你真的无法证明开销的合理性,否则系统之间的每个接口都应该实现健全性检查,或者更好的是按合同设计,以防止出现安全问题以及错误。
有很多方法可以解决这个问题,按照优先顺序,你应该做的是:
在库中使用支持异常(或更好,按合同设计)的语言,并在合同上抛出异常或允许合同失败。
提供错误处理信号/插槽或挂钩/回调机制,并调用任何已注册的处理程序。要求在初始化库时,至少注册一个错误处理程序。
支持在每个可能失败的函数中返回一些错误代码,无论出于何种原因。但这是用C(而不是C ++)做事的旧的,相对疯狂的做法。
设置一些全局“发生错误标志”,并允许在调用之前清除该标志。这也是旧的,并且完全疯了,主要是因为它将错误状态维护负担移动到调用者,并且在涉及线程时是不安全的。