【问题标题】:valgrind invalid read sizevalgrind 无效的读取大小
【发布时间】:2016-01-15 19:55:32
【问题描述】:

在下面的 valgrind 输出中,能否解释一下在 valgrind 库中引用 strlen 的顶行的含义。这是否意味着 valgrind itslef 有 bug?

==26147== Invalid read of size 1
==26147==    at 0x4C2E0E2: strlen (in/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==26147==    by 0x40263A: urldecode (server.c:1131)
==26147==    by 0x401853: main (server.c:199)
==26147==  Address 0xffefffaa0 is on thread 1's stack
==26147==  136 bytes below stack pointer

char* urldecode(const char* s)
{
    // check whether s is NULL
    if (s == NULL)
    {
        return NULL;
    }

    // allocate enough (zeroed) memory for an undecoded copy of s
    char* t = calloc(strlen(s) + 1, 1);  <--- line 1131

【问题讨论】:

  • 你最好看看server.c:1131
  • 小心指责你的工具有问题。它通常(但不总是)是您自己的代码。
  • 重现问题的邮政编码。
  • 这看起来像是一个没有正确终止的 C 字符串。 strlen 假设它传递的字符串以空字符结尾。如果 char 数组中没有空字符,strlen 就会越界——这不是它自己的错。
  • valgrind 提供了自己的 strlen() 版本,遮蔽了 libc 中的版本。没关系。大小为 1 的无效读取可能意味着使用无效但非 NULL 的指针调用 urldecode(),该指针恰好指向 0x00。

标签: c ubuntu


【解决方案1】:

这是一个堆栈跟踪。它说:

  • strlen() 试图读取它不应该读取的 1 个字节的内存 (可能它已经超过了您动态分配的缓冲区 1 个字节)
  • 该 strlen() 调用是从 server.c 第 1131 行调用的,即 urldecode() 函数。
  • 从 server.c 第 199 行调用了 urldecode() 函数

这意味着您的代码中存在错误。 您会在堆栈跟踪中找到最顶层的元素,即您的代码,这可能是 server.c 中的第 1131 行。

从第 1131 行开始,您开始弄清楚为什么将无效字符串传递给 strlen()。也许这是一个未初始化或未正确 nul 终止的字符串。

最终,您可能需要追踪创建字符串的位置,您为 urldecode() 函数发布的新代码看起来不错,因此您可能需要返回 server.c 第 199 行,看看如何您传递给 urldecode() 的字符串已生成。

【讨论】:

    猜你喜欢
    • 2017-04-09
    • 2012-07-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多