【问题标题】:Catching return codes in production environments?在生产环境中捕获返回码?
【发布时间】:2010-10-16 19:10:41
【问题描述】:

我想知道是否检查我们为生产环境编写的所有函数的返回码。 例如,我经常使用 C,你是否也捕获了标准库的返回码,不仅仅是你编写的函数,还有第 3 方 API/标准库/任何其他库。

我在生产中看到的大多数代码都没有这样做。 所以我的问题是针对那些在生产环境中工作并且已经编写生产代码大约 20 年的经验丰富的人。 您是否捕获了来自 3rd 方 API/标准库/任何其他库的返回代码,而不仅仅是您实现的函数? 只是举例说明我的意思 说你有没有捕捉到 C 标准库的 C 标准库函数(snprintf/sprintf、strncat/strcat 等等..,..)的返回码。

感谢您的所有回复。

【问题讨论】:

    标签: c error-handling return-value


    【解决方案1】:

    我认为您不应该对此采取全有或全无的方法。当您预期函数调用出现问题时(或者,当然,如果您的后续计算取决于函数返回的内容)捕获返回/错误代码。但是,如果您非常确定调用不会导致错误(或者即使在其他情况下您也没有使用返回值),do 跳过捕获返回值。

    这是需要依赖个人工程判断而非某些规定的“最佳实践”的领域之一。此外,我相信同样的想法也适用于异常处理。

    【讨论】:

    • 强烈反对。除了极少数例外,您应该始终检查返回码,即使您没有预料到会出现问题。因为有时问题会出现在你没想到的地方。调试因其他地方未检测到的故障而导致的问题可能是一场噩梦......
    • 非常危险的方法:“所有程序员都很乐观”他们总是认为错误不会发生,当它发生时......我投票赞成检查。
    【解决方案2】:

    我花了很长时间才知道这一点,但除非有少数例外,否则您应该始终检查函数的返回码。

    我见过太多调用malloc(例如)的代码,并且只是愉快地使用它返回的指针。在 99.9% 的情况下,这不是问题,但偶尔 malloc 会失败,并且当您尝试取消引用 NULL 指针时您的程序会崩溃。现在,有人可能会争辩说,如果 malloc 无论如何都返回 NULL,你想退出——这可能是真的,但你应该始终努力优雅地退出,即使出现致命错误。

    所以,是的:检查返回码。不要仅仅因为它在过去一直有效,就认为它有效。事情总是失败。通过防御性编码、检查错误、检查errno、输出strerror和优雅地失败,您将节省大量时间和痛苦。

    【讨论】:

      【解决方案3】:

      如果函数可能返回错误代码 - 始终检查并处理它,就这么简单。这条规则可以在寻找 bug 期间为您节省大量时间。

      如果函数总是返回无法指示错误的代码,并且您不需要结果(如printf)当然可以忽略它。

      【讨论】:

      • 这种方法是一个程序崩溃和一个程序尽可能优雅退出的区别,错误日志表明出了什么问题。
      • 不。并非标准函数中的所有错误都会导致崩溃,您将花费大量时间寻找问题根源。去过也做过。不喜欢。
      【解决方案4】:

      是的,除了极少数例外,您的程序应该始终检查并处理错误返回值,即使(尤其是)您不希望出现任何错误。毕竟,我们软件的环境通常不如我们希望的那么可靠。

      顺便说一句,这就是大多数现代语言都有异常的原因:除此之外,它们为您未明确处理(即捕获)的错误提供“默认错误处理程序”(中止和堆栈跟踪)。它们还允许集中错误处理,而不是检查每个函数调用的返回值。

      【讨论】:

        【解决方案5】:

        如果函数返回错误代码,您的调用代码应该决定如何处理错误。对于某些程序,忽略错误可能是可以的;例如,这往往是人们在写入标准错误时对标准 I/O 库中的错误所做的事情。 (如果消息失败了怎么办?退出?你还在这样做吗?)

        一个令人讨厌的来源是记录了返回值但总是返回相同值(通常为 0)的函数。通常,这些函数最初是在返回 void 之前用 K&R C 编写的。它们被转换为int,然后添加了一个“return(0);”来平息有关“函数不返回值”的警告,而不是像应该的那样将其转换为void。此类功能应修改为void;在此期间,可以忽略它们的错误返回值。

        我不同意另一个答案“当您预期函数调用出现问题时捕获返回/错误代码”中的观察。问题恰恰是出乎意料的事情会杀死你。即使是最稳定的操作也可能意外失败(可能 DBMS 已崩溃,因此即使您有连接,但您不再连接),您的软件必须识别并处理此类问题。

        【讨论】:

          【解决方案6】:

          snprintf 很有用,因为您可能希望分配一个更大的缓冲区然后重试,或者您可能按顺序调用它:

          // cons lists as [a,b,c, ...]
          if ( type == kin_cons_class() ) {
              size_t offs = snprintf ( buf, max, "[" );
          
              if ( offs >= max )
                  return nul_terminate ( buf, offs, max );
          
              size_t count = depth;
          
              kin_cons_ref_t empty = kin_cons_nil();
              kin_cons_ref_t cons;
          
              for ( cons = ref; cons != empty; cons = kin_cons_tail ( cons ) ) {
                  if ( count > 15 ) {
                      offs += snprintf ( buf + offs, max - offs, ", ..." );
          
                      break;
                  }
          
                  if ( cons != ref ) {
                      offs += snprintf ( buf + offs, max - offs, "," );
          
                      if ( offs >= max )
                          return nul_terminate ( buf, offs, max );
                  }
          
                  offs += string_repr ( buf + offs, max - offs, kin_cons_head ( cons ), depth, escape_strings );
          
                  if ( offs >= max )
                      return nul_terminate ( buf, offs, max );
          
                  ++count;
              }
          
              if ( offs >= max )
                  return nul_terminate ( buf, offs, max );
          
              offs += snprintf ( buf + offs, max - offs, "]" );
          
              return nul_terminate ( buf, offs, max );
          }
          

          如果您继续不进行所有offs >= max 测试,则会出现缓冲区溢出并且会出现段错误。

          printf 不会发生这种情况,因此检查退货不太常见。

          如果您需要根据函数是否有效来更改您的行为,请检查返回值。许多标准库函数可能会失败,或者稍后会导致未定义的行为,因此您需要检查这些返回。

          如果您不需要根据返回值更改行为,那么检查它是没有意义的。

          【讨论】:

            猜你喜欢
            • 2015-01-30
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2014-11-02
            • 2019-05-16
            • 1970-01-01
            • 1970-01-01
            • 2011-12-10
            相关资源
            最近更新 更多