This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] CC3235SF:从 AWS IoT MQTT 客户端启动 TLS 时崩溃

Guru**** 2558370 points
Other Parts Discussed in Thread: CC3220SF, CC3235SF

请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/wireless-connectivity/wi-fi-group/wifi/f/wi-fi-forum/1037619/cc3235sf-crash-when-starting-tls-from-aws-iot-mqtt-client

器件型号:CC3235SF
主题中讨论的其他器件:CC3220SF

尝试使用最新版本(4.30)的 AWS IoT SDK 插件以及 CC3235的 SimpleLink SDK (5.20)启动 MQTT 客户端会话时遇到硬故障。

下面是我的工作成果...  

我有两个不同的 AWS IoT 实例启动并运行... 一个是准系统实例、具有基本的"任何主题都正常"政策、而另一个是我们客户的实例。  我已经能够使用两个 AWS IoT 实例的凭据在 CC3220SF LaunchXL 板以及我们的定制 CC3235SF 目标上运行"subscribe_publish_sample" SDK 示例。  因此、我已验证我正在使用有效的凭据(Starfield 根 CA 证书、设备证书和设备私钥)、并且我已成功地将这些文件合并到烧录到目标的 SLI 映像中。

我还有一个在 CC3235上开发的主应用、演示成功运行的 SDK 示例后、我将 AWS IoT MQTT 示例代码移植到我的应用中。  具体而言,我提取了所有"AWS_IoT_*"源文件和头文件,此外还有:

  • jsmn.c
  • jsmn.h
  • network_interface.h
  • network_platform.h
  • network_sl.c
  • timer_interface.h
  • timer_platform.h
  • 定时器.c

我对该库所做的唯一重大修改是重写 aws_iot_log.h、以使用我的串行记录工具、而不是 TI Display 驱动程序。

我可以成功呼叫 aws_iot_mqtt_init()。  但是,当我呼叫时 aws_iot_mqtt_connect(),系统会挂起。  具体而言、系统从 faultISR()某个未知点进入、while(1)并始终保持在循环中。  以下是最终导致硬故障的调用树:

  • (我的MqttConnect() C++方法)
  • aws_iot_mqtt_connect()
  • _aws_iot_mqtt_internal_connect()
  • pClient->networkStack.connect()
  • iot_tls_connect()
  • SlNetSock_startSec()(首次调用绑定 TLS 上下文)
  • netIf->ifConf->sockstartSec()(指向 SlNetIfWifi_sockstartSec())

我可以单步执行sockstartSec()函数指针调用,但一旦我尝试单步执行该函数,调试器就不会再次中断,直到我暂停它,系统现在处于faultISR()中。  此外、如果我尝试在调试器中重新启动应用程序、它不会运行;必须完全重新加载目标或重启目标方才能恢复任何功能。

以下是系统准备崩溃之前的调试器状态:

我的基本问题是... 我如何确定这里实际上发生了什么错误?  我有一个线程负责所有 MQTT API 调用、我已经提供了大量的8000字节栈。  在此调用之前、系统(FreeRTOS)堆中剩余大量内存(至少32KB)。  在 MQTT 连接发生时没有发生其他重要活动。  我可以很好地运行独立示例、但当我在应用程序中进行完全相同的 API 调用时、它会爆炸。  有什么想法从哪里开始?  谢谢。

戴维·R.

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

    您能否在  SlNetIfWifi_sockstartSec 中设置断点并检查它是否到达该断点或它是否恰好失败(函数会多次调用 sl_SetSockOpt、然后调用 sl_StartTLS -以便您可以在分步操作不起作用时在该设置断点)。

    除了调试这个、我目前没有任何建议。 它看起来像是内存损坏(即使堆栈大小和堆按照您的说明看起来正常,您也可以在调用 tools/ROV classic->Task/detailed 之前检查堆栈使用情况和峰值)。 一个选项是从 AWS 开始、然后在其上面添加代码 、这可能更容易(特别是如果您可以通过平级方式添加代码来尝试和捕捉故障点)。

    BR、

    Kobi

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    [引用 userid="132163" URL"~/support/wireless-connectivity/wi-fi-group/wifi/f/wi-fi-forum/1037619/cc3235sf-crash-when-starting-tls-from-aws-iot-mqtt-client/3837562 #3837562"]您能否在  SlNetIfWifi_sockstartSec 中设置断点[/quot]

    有趣的事实:我不能。  具体来说,如果我尝试在中设置任何断点 SlNetIfWifi_sockstartSec(),它将立即被禁用。  我假设这是因为调试器没有与该源代码位置相对应的调试信息。  我不知道这段代码是不是在没有"-g"标志的情况下编译到其库中、还是在那里发生了什么。

    在中双击一行时,我会看到以下内容 SlNetIfWifi_sockstartSec()

    这就是断点窗口的外观:

    奇怪的是、请注意、编辑器窗口中的文件图标是一个通用图标、而不是".c"源文件图标、这表明 IDE 不认为它是相关的源文件。  (在哪里可以向项目添加其他源代码搜索路径?)

    我正在尝试在函数指针调用之前验证堆栈使用情况、但 ROV Classic 不想为我提出。  我得到 此对话框:

    单击 OK (确定)会显示 RTSC 配置对话框:

    我选择了"Arm"和"GNU v9.2.1"、并添加了当前版本的 XDCtools、但我不知道要在底部的两个项目中放入什么。  如果我单击"Apply and Close"(应用并关闭)、然后再次尝试运行 ROV Classic、我将收到相同的消息。

    但是、如果我运行"运行时对象视图"(非经典)、就会立即启动。  如果我单击 FreeRTOS、然后查看任务实例、我会看到以下内容:

    因此、所有任务在所有任务堆栈上都具有较高的页边距、看起来都很正常。

    您建议从 AWS IoT MQTT 示例作为基准开始、然后逐位输入我的代码、这实际上是不可行的。  到目前为止、我已经为这个应用开发了很多代码、为了分段对其进行解压、然后重新连接单个代码段、这将是一个非常大的时间投资。  我将尝试找到一些调试方法。  当然、如果我找到此问题的解决方案、我将在此处发布更新。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您能在 .map 文件中找到 SlNetIfWifi_sockstartSec 的地址吗?

    能否在 SL_StartTLS 和/或 SL_SetSockOpt 中设置断点?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    是的、SlNetIfWifi_sockstartSec()出现在映射文件中、这就是我能够确认函数指针的值 netIf->ifConf->sockstartSec正确的方式。  不可以、我无法在这些函数的源文件中设置断点、因为调试器似乎不会将其中任何一个识别为相关的源文件。

    如果我执行反汇编“步入”(Ctrl-Shift-F5),我可以进入的程序集SlNetIfWifi_sockstartSec(),但 IDE 直接告诉我没有可用于此函数的源代码:

    因此、对于 giggles、我单步执行的汇编 SlNetIfWifi_sockstartSec() 、直到我转到第一sl_SetSockOpt()个调用、我进入了:

    然后,我一直向下单步执行(Ctrl-Shift-F6)直到它到达对 SlDrvCmdOp()的调用,然后我尝试单步执行:

    此时、调试器无法返回。  我在调试器中单击了“暂停”,发现我被挂断,vListInsert()正在从vTaskPlaceOnEventList()以下位置进行呼叫:

    由于某种原因,这是与之前不同的终端状态,其中程序在faultIsr()中结束。  如果我在到达后按“Continue (继续)” netIf->ifConf->sockstartSec(),而不是单步执行反汇编,则目标将到达faultIsr()。  因此、根据目标的调试/单步执行方式、似乎存在一些不一致的行为。  在上面的捕获中,请注意for()循环通过遍历到前进,pxIterator->nextpxIterator->next它等于pxIterator,从而创建无限循环。  不确定这意味着什么类型的故障。

    您可能能够帮助解决的最大问题是:为什么 SlNetIfWifi_sockstartSec() 没有针对或的源代码调试 sl_SetSockOpt()?  这些库是否未使用-g选项进行编译?  在过去、当我跟踪到调试器知道应该有源代码但无法找到的函数时、它将在编辑器窗口中显示类似于"无法找到源文件的内容.c"的内容。 它将提供一个按钮、您可以单击该按钮、在该按钮中输入该源文件的搜索路径、项目将记住该源文件。  但与此处的情况不同、调试器只显示"no source available (无可用源代码)"。

    想法?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我认为它们确实使用-g 进行编译、至少是 CCS 编译(我可以在那里设置断点)。  您使用哪种工具链?

    您还可以 通过地址设置断点。

    如果您进入函数 并需要 找到源代码-它位于下面 /source/ti/drivers/net/wifi.  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我使用的是 Code Composer 10.4和 GCC 9.2.1。  您是否建议改用 TI 编译器?

    此外、您还没有阅读我说过的一些内容。

    [引用 userid="47307" URL"~/support/wireless-connectivity/wi-fi-group/wifi/f/wi-fi-forum/1037619/cc3235sf-crash-when-starting-tls-from-aws-iot-mqtt-client/3837910 #3837910"]在过去、当我跟踪到调试器知道应该有源代码但无法找到的函数时、我该如何向项目添加其他源代码搜索路径?
    kt c 说:
    它将在编辑器窗口中显示"找不到源文件 se.C"之类的内容。它将提供一个按钮、您可以单击该按钮、您可以在其中输入该源文件的搜索路径、项目将记住该路径。  但与此处的情况不同、调试器只显示"no source available (无可用源代码)"。

    我要告诉您的是、IDE/调试器说 这些函数没有可用的源代码。  IDE 不知道源文件 slnertifwifi .c 的位置、因为即使我打开该文件并尝试在相关函数中放置断点、IDE 也会立即禁用断点、因为它无法将该源位置与当前加载的任何机器代码相关联。  IDE 不能找到源文件并不重要、实际上 IDE 不知道编译的目标代码中特定的源代码行对应的位置。

    我将尝试使用 TI (clang)编译器来查看它是否提供任何不同的结果。  我希望您的 C++支持功能强大。  我可能需要向库软件包中添加大量#if conditionals。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您还可以为 gcc 重新编译库。

    只需转至文件夹(C:\ti\simplelink_cc32xx_sdk_5_20_00_06\sources\ti\drivers\net\wifi for simplelink.a 或 C:\ti\simplelink_cc32xx_sdk_5_20_00_06\sources\ti\drivers\net\wifi \slnewi\c32xx_cc32xx_cc32xx_sdk_5_5_5_5_20_00_06\gc10406\cmblog_mblu_mware\g3\cmbluF)、并使用"WiFi 命令在窗口中将"WiFi 命令默认值和 c100_mc1040_mc\g_mblu_mc1040_mc\g_mc\g

    您可能需要在命令行中更改 CCS 和 XDS 版本、以满足您的确切安装要求(以及中的编译器路径 /import.mak)。   

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    好的、我使用-g 选项重新编译了库... 老实说、我认为一些库不是使用-g 选项构建的、而其他库是... 这似乎是任意的。

    我能够跟踪 SlNetIfWifi_sockstartSec ()以查看发生的情况。  正如我所能察觉  到的那样,该函数会被传递一个 SlNetSock_SecAttribNode_t 结构的链接列表,该函数会迭代所有这些结构并调用 sl_SetSockOpt (),以设置所提供套接字的每个指定属性。  我多次单步执行循环,然后它到达 faultIsr()。  但为什么呢?

    事实证明、链接的列表已错误终止。  这是列表在传递到  SlNetIfWifi _sockstartSec 之前的状态:

    请注意下一个指针的最后一个指针(0x7361652D)的值。  这显然是一个垃圾值、不是 RAM 的有效指针。  (如果是 ASCII 格式、则为"SAE-"、如果这意味着任何东西。)

    我目前正在跟踪前面的代码、以了解如何构建该列表以及该非法值是如何在其中找到的。  当我弄清这一点时、我将发布更多内容。

    戴维·R.

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    有趣。  可能是存储器(例如地址0x20033A54中的下一个点) 在代码中的某个位置损坏(如果 每次覆盖确切位置-您可以使用 HW 观察点查找导致该位置的代码)。  

    但它也可能是 列表处理中的错误(尽管我希望参考代码中也会发生此错误)。  

    您应该按照列表创建操作 、直到使用它(该列表构建在 SlNetSock_secAttribSet 中、该列表在 StartTLS 之前调用)。  

    我将检查"-g"内容 (我认为它在所有预构建库中都已启用)。 您是否重建了 simplelink.a? (因为所提供的 makefile 文件的默认值似乎没有"-g")。  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    因此,我跟踪了它,这是我的实现中的一个错误calloc();内存没有按calloc()预期设置为0。  现在、我在尝试连接时收到一条合理的错误消息。  如果在 Get Go 的子库中启用了调试功能、我可能会更快速地解决这个问题。

    调试(-g)肯定不会在每个库中启用、只启用某些库。  下面是我对正在发生的情况的最佳分析:

    未启用调试的配置(-g、或 IAR 的--debug)为:

    • ti/drivers/net/wifi(GCC 和 TI_clang、RTOS +北向)
    • ti/drivers/net/wifi/slnetif (GCC 和 TI_clang)
    • ti/net/atcmd(GCC 和 TI_clang)
    • ti/net/ota(GCC 和 TI_clang)

    所有driverlib实例都具有调试功能,就像调试ti/net/utils一样。  如果 TI 能在月底之前在5.3中解决这个问题、我将不胜感激。  感谢您帮助调试工作。

    戴维·R.