【问题标题】:How can i catch a runtime error in ansi C90如何在 ansi C90 中捕获运行时错误
【发布时间】:2023-03-08 02:06:01
【问题描述】:

我正在使用库函数ConnectToTCPServer。当主机不可达时,该函数超时。在这种情况下,应用程序崩溃并出现以下错误: “非致命运行时错误:“MyClient.c”,第 93 行,第 15 列,线程 id 0x000017F0:库函数错误(返回值 == -11 [0xfffffff5])。超时错误”

Errorcode 11 是一个超时错误,所以这可能在我的应用程序中经常发生 - 但是应用程序崩溃了 - 我想捕捉这个错误而不是让我的应用程序崩溃。

如何在 Ansi C90 中捕获此运行时错误?

编辑: 这是当前使用的Codesn-p:

ConnectToTCPServer(&srvHandle, srvPort, srvName, HPMClientCb, answer, timeout);

int HPMClientCb(UINT handle, int xType, int errCode, void *transData){
    printf("This was never printed\n");
    return errCode;
}

永远不会调用回调函数。我的服务器没有运行,所以 ConnectToTCPServer 将超时。我怀疑回调被调用了——但它从未被调用过。

编辑2:实际上没有调用回调函数,ConnectToTCPServer的返回值包含相同的错误信息。我认为ConnectToTCPServer 抛出此错误可能是一个错误。我只需要抓住它并将其放入 C90 中即可。有什么想法吗?

编辑 3:我测试了回调函数,在我的服务器在线的罕见情况下,实际上调用了回调函数 - 这无济于事,因为发生错误时不会调用回调。

【问题讨论】:

    标签: c tcp c89 cvi


    【解决方案1】:

    查看 NI 文档,我看到:
    "库错误断点 -- 您可以设置一个选项以在 LabWindows/CVI 库函数在运行时返回错误时中断程序执行。"

    我推测他们有一个调试选项可以导致程序在运行时错误时停止,您需要在配置、编译时或运行时禁用它。

    我的第一个猜测是配置值或编译标志,但这是我找到的唯一选项,它是运行时选项:
    // If debugging is enabled, this function directs LabWindows/CVI not
    // to display a run-time error dialog box when a National Instruments
    // library function reports an error.
    DisableBreakOnLibraryErrors();

    如果有帮助请说。

    【讨论】:

    • 我生病了,目前无法测试 - 我将在两周后测试。
    • 谢谢您-这对您有所帮助...抱歉,我没有立即回复。我被关在一个房间里 8 周……根据客户的要求。
    【解决方案2】:

    在标准 C 中没有“捕获”错误(或“异常”)的一般情况。这取决于您的库来决定如何处理它。很可能它记录了它的状态,然后简单地调用 abort()。在 Unix 中,这表示SIGABRT 可以被处理,而不仅仅是 exit()ed。或者他们的库可能只是在记录,然后调用 exit()。

    您可以在 strace 之类的实用程序下运行您的应用程序,以查看正在执行的系统调用 以及正在断言的信号。

    如果您无法取得任何进展,我会与您的供应商合作。

    【讨论】:

      【解决方案3】:

      从文档看来,当发生错误时,您应该拨打您的clientCallbackFunction 电话。如果您不这样做,您应该编辑您的问题以澄清这一点。

      【讨论】:

      • 我的 clientCallbackFunction 实际上从未被调用过。
      • 我根本没有从文档中得到。在我看来,只有当服务器有 TCP_DISCONNECT 或 TCP_DATAREADY 事务时才应该调用回调函数。
      【解决方案4】:

      我不确定我是否理解你。

      我查看了库函数ConnectToTCPServer() 的文档。它返回一个整数; 0 表示成功,负数是错误码。

      编辑:这是一个 Codesn-p 当前使用:

      ConnectToTCPServer(&srvHandle, srvPort, srvName, HPMClientCb, answer, timeout);
      

      如果这确实是当前的用途,您似乎并没有试图判断 ConnectToTCPServer() 是否成功。为此,您需要

      int err_code;
      ...
      err_code = ConnectToTCPServer(&srvHandle, srvPort, srvName, HPMClientCb, answer, timeout);
      

      然后测试err_code。

      documentation for ConnectToTCPServer()表示除非有来自 TCP 服务器的消息,否则不会调用您的回调函数。没有服务器,没有消息。在这种情况下,

      1. ConnectToTCPServer() 应该返回一个负数。
      2. 你应该检查ConnectToTCPServer()的返回值。
      3. 在那里找到一个负数,你应该做一些明智的事情。

      我是否正确理解了文档?

      【讨论】:

      • 我简化了一点。将返回值存储在变量中不会改变这种情况。
      • 您的编辑 3 表示您希望在出现错误时调用回调函数。通过阅读文档,我不会想到这一点。我希望只有当 TCP 服务器有 TCP_DISCONNECT 或 TCP_DATAREADY 事务时才会调用您的回调。我不会认为错误是这些交易类型中的任何一种。
      【解决方案5】:

      通常,您应该能够简单地检查返回值。您的应用程序退出的事实意味着某些东西已经在捕获错误并断言(或类似的东西)。没有看到任何上下文(即演示您如何使用此函数的代码),很难更精确。

      【讨论】:

      • 我提供了一个极简示例 - 我相信错误已在库中捕获,然后被扔到我不知道如何处理的应用程序中。
      【解决方案6】:

      文档指出ConnectToTCPServer 将返回错误代码。只有在连接建立、断开或有数据可供读取时才会调用回调。

      您收到的消息表明该错误是非致命的,因此不应中止。如果您确定代码以后不会中止,那看起来确实是库中的错误。

      我不熟悉 CVI,但可能有一个 (compile-/runtime-) 选项可以在非致命错误时中止(用于调试目的)。如果你能在一个最小的例子中重现这个,你应该report it to NI

      【讨论】:

      • 我联系了 NI - 他们目前正在调查。
      • 通过阅读您的其他 cmets,在我看来您误解了错误处理应该如何工作。您需要保存返回值并检查它是否有错误代码。只有当函数永远不会返回它是库的错误。库返回错误代码而不调用您的回调是完全合法的。
      猜你喜欢
      • 2012-04-15
      • 2011-02-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-10
      • 2013-09-01
      相关资源
      最近更新 更多