8wDlpd.png
8wDFp9.png
8wDEOx.png
8wDMfH.png
8wDKte.png

函数返回时检测到堆栈溢出

CrimsonED 2月前

43 0

我有一个用于读取未知大小的 TCP 数据包的函数。该函数使用 MSG_PEEK 查找接收到的 JSON 消息(循环条件中的 \\'})所需的大小,然后运行循环...

我有一个用于读取未知大小的 TCP 数据包的函数。该函数使用 MSG_PEEK 查找接收到的 JSON 消息所需的大小( \"} 循环条件),然后在不使用 MSG_PEEK 的情况下再次运行循环以清理缓冲区。出于某种原因,函数末尾的两个打印工作正常,但当我调用 fn 时,我的程序在返回后立即死机并打印 \'*** 检测到堆栈粉碎 ***:已终止\'。不应该 content_buffer 溢出,因为我正在分配 content_size + 1 并传递 content_size recv 正确的位置?

char *read_socket_raw(int socket)
{
    if (socket == -1)
    {
        fprintf(stderr, "Reading socket failed.\n");
        return NULL;
    }

    char *content_buffer = NULL;
    unsigned short content_size;

    why2_bool empty_buffer = 0; //WHETHER MSG_PEEK SHOULD BE USER OR NOT

    do
    {
        //FIND THE SENT SIZE
        content_size = 0;
        if (ioctl(socket, FIONREAD, &content_size) < 0 || content_size <= 0) continue;

        //ALLOCATE
        content_buffer = realloc(content_buffer, content_size + 1);

        read_section:

        //READ JSON MESSAGE
        if (recv(socket, content_buffer, content_size, !empty_buffer ? MSG_PEEK : 0) != content_size) //READ THE MESSAGE BY CHARACTERS
        {
            fprintf(stderr, "Socket probably read wrongly!\n");
        }

        if (empty_buffer) goto return_section; //STOP LOOPING
    } while (content_buffer == NULL || strncmp(content_buffer + (content_size - 2), "\"}", 2) != 0);

    //REMOVE JUNK FROM BUFFER (CUZ THE MSG_PEEK FLAG)
    empty_buffer = 1;
    goto read_section;

    return_section:

    content_buffer[content_size] = '\0';

    printf("'%s'\n", content_buffer);
    printf("'%p'\n\n", content_buffer);

    return content_buffer;
}
帖子版权声明 1、本帖标题:函数返回时检测到堆栈溢出
    本站网址:http://xjnalaquan.com/
2、本网站的资源部分来源于网络,如有侵权,请联系站长进行删除处理。
3、会员发帖仅代表会员个人观点,并不代表本站赞同其观点和对其真实性负责。
4、本站一律禁止以任何方式发布或转载任何违法的相关信息,访客发现请向站长举报
5、站长邮箱:yeweds@126.com 除非注明,本帖由CrimsonED在本站《sockets》版块原创发布, 转载请注明出处!
最新回复 (0)
  • 在读取之前,您不必知道有多少字节可用。特别是如果您要一直读取直到获得所需的所有数据时——您不妨执行阻塞读取。请注意,这样的读取可能会传输比请求的更少的字节,并且如果它可以在不阻塞的情况下传输至少一个字节,但不是请求的全部字节,通常会这样做。

  • 但请注意,您的方法很脆弱。TCP 没有内置消息边界,因此如果 JSON 消息的接收间隔足够近,以至于您在下一条消息进入接收队列之前没有清除一条消息,您可能会遇到麻烦。

  • 您的函数有很多令人不满意的地方,但有一点似乎完全不正确,那就是变量的类型 content_size FIONREAD ioctl 需要一个指向 的指针 int ,但您却提供了一个指向 的指针 unsigned short 。结果为未定义的行为。

    实际上,您的 unsigned short 可能小于 int ,在这种情况下 ioctl() 可能会尝试写入超出该对象的边界。这正是可能触发堆栈破坏消息并崩溃的事情,因为如果该变量的存储位于函数堆栈框架的开头(顶部),那么超出其边界确实会破坏堆栈。

    其他不喜欢的事情:

    • p3

    • p4

    • p5

  • 非常感谢,将数据类型改为 int 解决了这个问题。我会尝试修复 goto,说实话我也不喜欢它。另外,我已经有一些代码在 read_socket_raw 函数之外验证消息的结尾。关于长度,我认为这是最优雅的解决方案,因为我没有设置消息长度限制,而且我不想这样做。标记为已解决。谢谢。

返回
作者最近主题: