今天在使用libuv时出现了EFAULT错误,写此文章作为记录。
EFAULT:
引用:https://www.cnblogs.com/yxwkf/p/5399164.html
It happen if the memory address of some argument passed to sendto (or more generally to any system call) is invalid. Think of it as a sort of SIGSEGV in kernel land regarding your syscall. For instance, if you pass a null or invalid buffer pointer (for reading, writing, sending, recieving...)。说明在对套接字上调用某些函数的时候传入了空指针等非法參数,的确如此。
libuv
使用的是libuv自带的demo,tcp-echo-server
void echo_read(uv_stream_t *client, ssize_t nread, const uv_buf_t *buf) {
if (nread > 0) {
write_req_t *req = (write_req_t*) malloc(sizeof(write_req_t));
req->buf = uv_buf_init(buf->base, nread);
uv_write((uv_write_t*) req, client, &req->buf, 1, echo_write);
return;
}
if (nread < 0) {
if (nread != UV_EOF)
fprintf(stderr, "Read error %s\n", uv_err_name(nread));
uv_close((uv_handle_t*) client, on_close);
}
free(buf->base);
}
该段代码的意图是接收到客户端的消息后,再发送相同的数据给客户端。
为了验证libuv发送大量数据时,是如何运行的,我直接将代码改成了如下,然后就出现了EFAULT错误
void echo_read(uv_stream_t *client, ssize_t nread, const uv_buf_t *buf) {
if (nread > 0) {
write_req_t *req = (write_req_t*) malloc(sizeof(write_req_t));
req->buf = uv_buf_init(req->base, 10240*200);
uv_write((uv_write_t*) req, client, &req->buf, 1, echo_write);
return;
}
if (nread < 0) {
if (nread != UV_EOF)
fprintf(stderr, "Read error %s\n", uv_err_name(nread));
uv_close((uv_handle_t*) client, on_close);
}
free(buf->base);
}
EFAULT错误就是因为操作了不该操作的内存,而仔细观察uv_buf_init之后,发现该函数并没有申请空间,也就是并没有我之前想象的会有10240*200的大小,所以出现了错误