sprintf() 的错误:"__builtin___sprintf_chk"可能会在目标末尾写入终

  • 本文关键字:sprintf quot 目标 builtin 错误 chk c
  • 更新时间 :
  • 英文 :


我正在尝试按照本指南为 RX 制作工具链。本指南使用以下工具:

GCC-4.6.4
binutils-2.23.52
gdb-7.6
newlib-2.0.0

当我运行第一个make时,我遇到此错误:

../../binutils-2.23.52/binutils/prdbg.c:500:20:错误:"__builtin___sprintf_chk"可能会在目标末尾写入终止 NUL[-Werror=format-overflow=]
sprintf (buf, "%ld", (long( VMA(;

然后我打开代码并导航到这部分,它应该有一个错误:

static void
print_vma (bfd_vma vma, char *buf, bfd_boolean unsignedp, bfd_boolean hexp)
{
if (sizeof (vma) <= sizeof (unsigned long))
{
if (hexp)
sprintf (buf, "0x%lx", (unsigned long) vma);
else if (unsignedp)
sprintf (buf, "%lu", (unsigned long) vma);
else
sprintf (buf, "%ld", (long) vma); // <-- this line
}
// ... // some code below

我搜索并找到了这些问题:问题 1 和问题 2。我知道这种溢出错误是因为缓冲区不够大,无法包含所有数据。但此链接指出longunsigned long具有相同的存储大小(8 字节(。

我尝试用unsigned long替换long,它通过了,这个文件上没有更多的错误(所以我认为下面的代码没有相关错误(,但我认为这不是一个好方法。

所以,我真的不明白为什么long会导致错误,而unsigned long不会。还是我误解了什么?谢谢你的帮助。


ps:实际上在此错误之前,我首先遇到了以下2个错误(在其他文件中(:

  • 跌倒
  • 负换档

但是它们与此错误无关(我修复了它们(,所以我跳过了。

无符号长整型的存储大小可能是 8 个字节,但字符串中的十进制表示形式可能更长!

例如,2^32适合 4 个字节,但字符串表示"4294967296"需要 11 个字节(注意隐式零字节作为字符串终止符(!因此,您需要为sprintf()目标提供大于 8 字节的缓冲区。

一般来说,十进制字符串表示形式需要ceil(log_10(max_value_of_datatype)) + 1 (zero byte)个字节(减号可能需要一个额外的字节,具体取决于符号(。

对于 64 位无符号值,这会导致ceil(log_10(2^64)) + 1 = 21 bytes

64 位有符号的结果相同:ceil(log_10(2^63)) + 1 + 1 (for minus sign) = 21 bytes

对于 32 位无符号值,这会导致ceil(log_10(2^32)) + 1) = 11 bytes,对于 32 位有符号值,必要的空格是ceil(log_10(2^31)) + 2) = 12 bytes

最新更新