c - 读取(3) "called with bigger length than size of the destination buffer"

标签 c linux glibc

使用以下代码:

#define MIN(a,b) ({ typeof (a) _a = (a); typeof (b) _b = (b); _a < _b ? _a : _b; })
...
size_t const recvBufLength = 50*1024*1024;
char * const recvBuf = malloc(recvBufLength);
...
while ((r = read(sockfd, recvBuf, MIN(recvLength-received, recvBufLength))) > 0) {
    ...
}

我收到此错误:

/usr/include/x86_64-linux-gnu/bits/unistd.h: In function ‘main’:
/usr/include/x86_64-linux-gnu/bits/unistd.h:39:2: error: call to ‘__read_chk_warn’ declared with attribute warning: read called with bigger length than size of the destination buffer [-Werror]
  return __read_chk (__fd, __buf, __nbytes, __bos0 (__buf));
  ^
lto1: all warnings being treated as errors
lto-wrapper: gcc returned 1 exit status
/usr/bin/ld: lto-wrapper failed
collect2: error: ld returned 1 exit status

如果我去掉MIN并将读取更改为read(sockfd, recvBuf,recvBufLength),那么它就可以毫无提示地编译。

这是我的错误,还是 GCC 的错误,还是 glibc 的错误?

如果不是前者,那么我如何规避有缺陷的长度检查?


编辑:

即使将 MIN 宏扩展为简单的三元运算,仍然会出现错误。

read(sockfd, recvBuf, (recvLength-received)<recvBufLength?(recvLength-received):recvBufLength)

这一切都在 GCC 4.8.2 中,我很快就会尝试其他版本。

最佳答案

我认为这是因为 MIN 宏扩展为一个 block 而不是一个表达式(宏中有 { })。我不认为每个 C 标准都允许这样做(参见 C block becomes expression: ( {int a = 1; int b = 2; a+b;} ) equals 3 )。

也许尝试先将 MIN 的结果放入变量中

val=MIN(recvLength-received, recvBufLength));
while ((r = read(sockfd, recvBuf, val) > 0) {
    ...
    val=MIN(recvLength-received, recvBufLength));
}

有趣,我刚刚学到了一些东西!

关于c - 读取(3) "called with bigger length than size of the destination buffer",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21316988/

相关文章:

c - 提示编译器它可以使用对齐的 memcpy

c - 什么是 __open() 以及为什么 fopen() 调用它而不是打开?

c - 如何使用 cl.exe 创建 obj 文件

c - 如何将 2 的补码转换为机器自然对应的带符号对应项?

php - 使用 PHP 检查 SSL 的万无一失的方法

linux - 如何连接到 Linux 服务器并使用 shell 脚本停止/启动服务?

c - 显式 glibc 链接后为 "Segmentation fault (core dumped)"。

c - 将函数参数加载到堆栈上,然后在 C 中运行该函数

c - 如何为 CTRL+ 创建加速器?在代码中

c - 最简单的 Ubuntu GUI 应用程序