Hi Diogo,

The problem is with this line:

    auto reply = request.send().wait(clientData->waitScope_).getReply();

On this line, `wait()` will return a `capnp::Response<ReadResults>`. This
response object owns the underlying reply message. But you are immediately
calling `getReply()` on it and then throwing away the response object. Note
that struct Reader and Builder objects are essentially pointers into the
message buffer. Thus, `reply` is now pointing into a message that has been
thrown away. You need to do this instead:

    auto response = request.send().wait(clientData->waitScope_);
    auto reply = response.getReply();

This way, `response` will live until the end of the current scope, so
`reply` is not a dangling pointer.

-Kenton

On Sun, Nov 3, 2019 at 11:18 AM Diogo Leitão <[email protected]> wrote:

> The "size" it's the amount of bytes that the FUSE wants to read, and "res"
> it's the amount of bytes that were read.
> The syscall *pread* ensures that "size" is always greater or equal than
> "res". If an error occurred during the this syscall "res" will be -1, but
> in this case "memcpy" isn't called .
> FUSE also guarantees that the destination buffer as enough space to hold
> the amounted bytes that requested, that is, "size" value.
>
> I have already tested other methods related to buf field on the capnp
> struct, like *hasBuf*, and i also get segmentation fault.
>
> I forgot to say that this code works on my MacBook, but when a try it on a
> different OS (Ubuntu 18.04 or Ubuntu 16.04) it fails. I have already
> compiled it with different compilers (g++ and clang++) with old and new
> versions. But nothing seems to solve the problem.
>
>
> domingo, 3 de Novembro de 2019 às 06:10:43 UTC, Paweł Głodny R. escreveu:
>>
>> Look at the line you mentioned yourself: "std::memcpy(buf,
>> reply.getBuf().begin(), res);". You probably meant "size" instead of
>> "res".
>> What's the output of "res = reply.getResult();" exactly? Unless it's
>> not the size, you've got logic error and "memcpy" may go out-of-range
>> when copying data.
>> Does the destination buffer have enough space to hold all the copied
>> data (you might need to guarantee it explicitly - it won't resize on
>> it's own)?
>> What's the type of "reply.getBuf().begin()"? Remember that "memcpy"
>> operates on raw pointers.
>>
>> -Paweł
>>
>> On Sun, 3 Nov 2019 at 06:18, Diogo Leitão <[email protected]> wrote:
>> >
>> > Hi
>> >
>> > I'm using FUSE + Cap'n Proto to build a distributed filesystem.
>> Everything seems to be fine, but when i try get the data field, on the
>> client side, using the getBuf method, i get a segmentation fault error.
>> >
>> > This is the code that i made. What am i doing wrong?
>> >
>> >
>> > /*
>> >
>> >  * Capnp source file
>> >
>> >  */
>> >
>> > interface FilesystemOps {
>> >
>> >     ...
>> >     read @16 (request :ReadRequest) -> (reply :ReadReply);
>> >
>> >     ...
>> > }
>> >
>> >
>> > struct ReadRequest {
>> >     path @0 :Text;
>> >     size @1 :UInt64;
>> >     offset @2 :Int64;
>> > }
>> >
>> > struct ReadReply {
>> >     result @0 :Int32;
>> >     buf @1 :Data;
>> > }
>> >
>> >
>> > /*
>> >
>> >  * Client side
>> >
>> >  */
>> >
>> > int FilesystemOpsClient::rpc_read(const char *path, char *buf, size_t
>> size, off_t offset, struct fuse_file_info *fi) {
>> >     std::cout << "rpc_read begin " << size << std::endl;
>> >
>> >     int res;
>> >     auto clientData = getClient();
>> >     auto request = clientData->cap_.readRequest();
>> >     auto builder = request.getRequest();
>> >
>> >     builder.setPath(path);
>> >     builder.setSize(size);
>> >     builder.setOffset(offset);
>> >
>> >     auto reply =
>> request.send().wait(clientData->waitScope_).getReply();
>> >
>> >     res = reply.getResult();
>> >     if (res != -1) {
>> >         std::memcpy(buf, reply.getBuf().begin(), res);
>> >
>> >     }
>> >
>> >     return res;
>> > }
>> >
>> >
>> > /*
>> >
>> >  * Server side
>> >
>> >  */
>> >
>> > kj::Promise<void>
>> FilesystemOpsImpl::read(FilesystemOps::Server::ReadContext context) {
>> >     int res;
>> >     auto request = context.getParams().getRequest();
>> >     auto reply = context.getResults().getReply();
>> >
>> >     std::string path = root_path_ + request.getPath().cStr();
>> >     size_t size = request.getSize();
>> >     off_t offset = request.getOffset();
>> >
>> >     int fd = ::open(path.c_str(), O_RDONLY);
>> >     if (fd == -1) {
>> >         res = -1;
>> >     } else {
>> >         res = pread(fd, reply.initBuf(size).begin(), size, offset);
>> >         close(fd);
>> >     }
>> >
>> >     reply.setResult(res);
>> >
>> >     return kj::READY_NOW;
>> > }
>> >
>> >
>> > Appreciate your help. Thank you.
>> >
>> >
>> > --
>> > You received this message because you are subscribed to the Google
>> Groups "Cap'n Proto" group.
>> > To unsubscribe from this group and stop receiving emails from it, send
>> an email to [email protected].
>> > To view this discussion on the web visit
>> https://groups.google.com/d/msgid/capnproto/ee51e0ec-819c-4962-9245-41cafcd03862%40googlegroups.com.
>>
>>
> --
> You received this message because you are subscribed to the Google Groups
> "Cap'n Proto" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to [email protected].
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/capnproto/bd19f6da-b288-4c17-80ae-b14e2f903d1c%40googlegroups.com
> <https://groups.google.com/d/msgid/capnproto/bd19f6da-b288-4c17-80ae-b14e2f903d1c%40googlegroups.com?utm_medium=email&utm_source=footer>
> .
>

-- 
You received this message because you are subscribed to the Google Groups 
"Cap'n Proto" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/capnproto/CAJouXQ%3D1i4ei8Yat9jT9diRuw2LDx8-3X7qDBt0SNWkc6ktvKQ%40mail.gmail.com.

Reply via email to