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.

[参考译文] LAUNCCHCC3220MODASF:snprintf 空指针和多线程

Guru**** 2577385 points


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

https://e2e.ti.com/support/wireless-connectivity/wi-fi-group/wifi/f/wi-fi-forum/1067005/launchcc3220modasf-snprintf-null-pointer-and-multithreading

部件号:LAUNCCHCC3220MODASF

大家好,

我使用 CCS11和 SDK 5.30。

我对 CCS11中编译器附带的 snprintf 函数有两个问题。

1.多线程

据我所知,snprintf 在最常见的实现中是线程安全的。

我检查了 snprintf 调用函数_PRINTFI,该函数也只使用区域变量。
我还在_PRINTFI 的描述中找到了以下评论。

对于  多线程应用,如果在      */上调用此函数,则为/*
/*  代表 fprintf,printf,vfprintf 或 vprintf,调用站点应该 */
/*  封装在保证单线程     */的关键部分中
/*  对文件流的访问。

因此,我假设 snprintf 的 TI 实现也是线程安全的。
我是对的?

2.空指针作为目标缓冲区

以下各行显示了一个示例代码,该代码读取,写入地址0,并使用 NULL 指针调用 snprintf 作为目标缓冲区。

 {
   #define ADR0 (*(volatile UINT32_t *)(0x0000))
   UINT32_t u32_value = ADR0;
   log_info (“读取 ADR 0:0x%x”,u32_value);

   ADR0 = 0x12345678;
   u32_value = ADR0;
   log_info (“写入0x12345678后读取 ADR 0:0x%x”,u32_value);
   ADR0 = 0x12345678;

   I32_result = snprintf((char*) NULL,(size_t)64,“TestString”);// strlen =10
   log_info (“格式0:返回%d”,i32_result);
 }

结果:

读取 ADR 0:0x20004000
写入0x12345678:0x20004000后读取 ADR 0
格式0:返回10

据我所知,snprintf 的行为与 C99一致。

但我想知道,从地址 NULL 开始的写入真的会发生(见图)。

地址 NULL 似乎是包含堆栈起始位置的映射的第一个 ROM 地址。

我假设对地址 NULL 的写入被忽略,因为内存保护处于非活动状态。

是这样计划的吗?
TIRTOS 7中的行为是否相同?

此致,
罗马

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

    你好,Roman,

    明天我将在这里跟进。

    谢谢,
    雅各布

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

    你好,Roman,

    这个问题更适合编译器团队;我 将这个问题转移给他们。 请在几天内回复。

    谢谢,
    雅各布

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    [引用 userid="135733" url="~/support/swireless-connectivity /wi-fi-group/wi-fi /f/wi-fi-forume/1067005/launchcc3220modasf-snprintf-null-null-pointer-and 多线程]I 假设 snprintf 的 TI 实现也是线程安全的。
    我是对的?

    snprintf 函数的线程安全方式与 strcpy 的线程安全相同。  它不会触及任何全局状态,除非用户将全局状态中的某个内容的地址作为参数传递。

    [引用 userid="135733" url="~/support/wireless-connectivity /wi-fi-group/wi-fi /f/wi-fi-forume/1067005/launchcc3220modasf-snprintf-null 指针和多线程"]空指针作为目标缓冲区

    函数 snprintf 假定目标缓冲区可以安全写入,除非第二个参数(要写入的字节数限制)为0。  如您所示,如果通过 NULL,则代码将尝试写入地址0。   

    [引用 userid="135733" url="~/support/wireless-connection/wi-fi-group/wi-fi -forum/1067005/launchcc3220modasf-snprintf-null-null-pointer-and-multiclthreading"]我假设对地址 NULL 的写入被忽略,因为内存保护处于非活动状态。

    这是一个特定于设备的问题,我缺乏专业知识来回答。  我会将您的问题的这一部分通知设备专家。

    谢谢,此致,

    乔治

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

    你好,Roman,

    下周我将跟进另一个问题。

    谢谢,
    雅各布

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

    你好,Roman,

    [引用 userid="135733" url="~/support/wireless-connection/wi-fi-group/wi-fi -forum/1067005/launchcc3220modasf-snprintf-null-null-pointer-and-multiclthreading"]我假设对地址 NULL 的写入被忽略,因为内存保护处于非活动状态。

    您是正确的;地址0x0没有内存保护。 但是,写入在此处不起作用,因为它是由设备保留的。 您只能写入设备的 RAM。 我不希望 TI-RTOS 7会改变这种情况,因为它是特定于设备的行为。

    谢谢,
    雅各布

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

    谢谢 Jacob,

    我认为,如果 snprintf 的缓冲区大小参数损坏到一个非常高的值,则仍有 RISC,这将导致从地址0开始的持续步行。

    例如,程序员未检查从负 int 到 size_t 的转换(当然错误)。

    由于没有 MPU 和空指针检查,因此可能需要很长的地址步行时间,这将/可能到达寄存器或内存地址;)

    此致,
    罗马

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

    你好,Roman,

    您是否能够证明这种行为? 也许您可以提供一个用例,用于演示读存储器的保留部分。 如果您成功,则可以 在此处提交一个潜在的漏洞

    谢谢,
    雅各布

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

    你好雅各,

    感谢你的介绍。 我会尝试证据,如果出现在我预期的情况下,我会跟踪您的链接。

    非常感谢,
    罗马