Return value of a FFI call to a external function is its 2`s complement

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

Return value of a FFI call to a external function is its 2`s complement

dellani
Dear uFFI experts,

I am dealing with the port of the ZeroMQ code to Pharo 6 and found
something unexpected to me, at least:

Zmq4Api>>apiZmqMsgRecv: message socket: socket withFlags: flags
    ^ self ffiCall: #(long zmq_msg_recv (ZmqApiMessage* message, ZmqApiSocket* socket, long flags ) )

Calling this returns the 2's complement of the return value
of the external function call. Is it expected that the code calling
this do the decoding of the 2'complement representation of
the return value?

Cheers,

Paulo
Reply | Threaded
Open this post in threaded view
|

Re: Return value of a FFI call to a external function is its 2`s complement

dellani
P.S.: some details of the setup follow.

pharo --version:

5.0-201707201942  Thu Jul 20 20:40:54 UTC 2017 gcc 4.6.3 [Production Spur 64-bit VM]
CoInterpreter VMMaker.oscog-eem.2254 uuid: 4f2c2cce-f4a2-469a-93f1-97ed941df0ad Jul 20 2017
StackToRegisterMappingCogit VMMaker.oscog-eem.2252 uuid: 2f3e9b0e-ecd3-4adf-b092-cce2e2587a5c Jul 20 2017
VM: 201707201942 https://github.com/OpenSmalltalk/opensmalltalk-vm.git $ Date: Thu Jul 20 12:42:21 2017 -0700 $
Plugins: 201707201942 https://github.com/OpenSmalltalk/opensmalltalk-vm.git $
Linux testing-gce-74d10329-bbfd-42e5-8995-b0e3a68c73cb 3.13.0-115-generic #162~precise1-Ubuntu SMP Fri Mar 24 16:47:06 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
plugin path: /opt/smalltalk/pharo6.1/pharo-vm/lib/pharo/5.0-201707201942 [default: /opt/smalltalk/pharo6.1/pharo-vm/lib/pharo/5.0-201707201942/]

uname -a

Linux neutrino 4.13.8-100.fc25.x86_64 #1 SMP Wed Oct 18 17:10:31 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux


On 10/30/2017 01:02 PM, Paulo R. Dellani wrote:
Dear uFFI experts,

I am dealing with the port of the ZeroMQ code to Pharo 6 and found
something unexpected to me, at least:

Zmq4Api>>apiZmqMsgRecv: message socket: socket withFlags: flags
    ^ self ffiCall: #(long zmq_msg_recv (ZmqApiMessage* message, ZmqApiSocket* socket, long flags ) )

Calling this returns the 2's complement of the return value
of the external function call. Is it expected that the code calling
this do the decoding of the 2'complement representation of
the return value?

Cheers,

Paulo

Reply | Threaded
Open this post in threaded view
|

Re: Return value of a FFI call to a external function is its 2`s complement

kilon.alios
In reply to this post by dellani

I have no idea what you mean by "2's complement" 

In any case bare in mind that UFFI has a limited range of C types that does support. Here you use 2 custom types , ZmqApiMessage and ZmqApiSocket , both are pointers because of * . Now these types are definetly not included with UFFI so if you have not done so you will have to
 
1) Define a class that inherits from FFIExternalObject and make sure your class handles the pointer properly 
2) Replace the custom type with an equivelant type that is supported by UFFI

The type of the pointer does not affect the pointer itself, usually, but rather the data it points to. So a pointer knows from it type that the data consumes a x amount of bytes and is of specific type , this can help also with indexing as C arrays are nothing more than a pointer that uses the index as an offset depending on its type of x amount of bytes. 

So its crucial that you get these right or else you going have some super weird results and even crashes. 

Because if you use improper types the pointer will give access to an area of memory bigger or smaller than the inteded type . Smaller will give you corrupted data (you will be missing bytes of data), bigger may crash because it may extend to area of memory not allowed to access. 

Technically speaking you can use even incorrect types if you know what you doing because UFFI pointers have great flexibility allowing you define real time the excact position of the memory and the range. 

Bare in mind that C is a high level language (and not low level as many incorrect assume) and deal with types that is NOT a low level concept (excepts types that have to do only with the size/ amount of bits) . So the type gives crucial information to C how exactly to access the memory. 
On Mon, Oct 30, 2017 at 2:03 PM Paulo R. Dellani <[hidden email]> wrote:
Dear uFFI experts,

I am dealing with the port of the ZeroMQ code to Pharo 6 and found
something unexpected to me, at least:

Zmq4Api>>apiZmqMsgRecv: message socket: socket withFlags: flags
    ^ self ffiCall: #(long zmq_msg_recv (ZmqApiMessage* message, ZmqApiSocket* socket, long flags ) )

Calling this returns the 2's complement of the return value
of the external function call. Is it expected that the code calling
this do the decoding of the 2'complement representation of
the return value?

Cheers,

Paulo
Reply | Threaded
Open this post in threaded view
|

Re: Return value of a FFI call to a external function is its 2`s complement

dellani
"Two`s complement" is one possible way to represent signed integers in binary form (1).

When the message apiZmqMsgRecv: message socket: socket withFlags: flags is sent, as
shown in my prior message, a function from libzmq, zmq_msg_recv (2) is called
and the return value should be either the number of bytes in the received message
or -1, in case of an error. Well, I was expecting to get a -1 as return value when
calling the function in non-blocking mode, but it returns 0xFFFFFFFF, which happens
to be the 2's complement representation of -1. At least the old code for libZMQ
was not expecting that.

Cheers, Paulo

(1) https://en.wikipedia.org/wiki/Two's_complement
(2) http://api.zeromq.org/4-2:zmq-msg-recv

On 10/30/2017 02:13 PM, Dimitris Chloupis wrote:

I have no idea what you mean by "2's complement" 

In any case bare in mind that UFFI has a limited range of C types that does support. Here you use 2 custom types , ZmqApiMessage and ZmqApiSocket , both are pointers because of * . Now these types are definetly not included with UFFI so if you have not done so you will have to
 
1) Define a class that inherits from FFIExternalObject and make sure your class handles the pointer properly 
2) Replace the custom type with an equivelant type that is supported by UFFI

The type of the pointer does not affect the pointer itself, usually, but rather the data it points to. So a pointer knows from it type that the data consumes a x amount of bytes and is of specific type , this can help also with indexing as C arrays are nothing more than a pointer that uses the index as an offset depending on its type of x amount of bytes. 

So its crucial that you get these right or else you going have some super weird results and even crashes. 

Because if you use improper types the pointer will give access to an area of memory bigger or smaller than the inteded type . Smaller will give you corrupted data (you will be missing bytes of data), bigger may crash because it may extend to area of memory not allowed to access. 

Technically speaking you can use even incorrect types if you know what you doing because UFFI pointers have great flexibility allowing you define real time the excact position of the memory and the range. 

Bare in mind that C is a high level language (and not low level as many incorrect assume) and deal with types that is NOT a low level concept (excepts types that have to do only with the size/ amount of bits) . So the type gives crucial information to C how exactly to access the memory. 
On Mon, Oct 30, 2017 at 2:03 PM Paulo R. Dellani <[hidden email]> wrote:
Dear uFFI experts,

I am dealing with the port of the ZeroMQ code to Pharo 6 and found
something unexpected to me, at least:

Zmq4Api>>apiZmqMsgRecv: message socket: socket withFlags: flags
    ^ self ffiCall: #(long zmq_msg_recv (ZmqApiMessage* message, ZmqApiSocket* socket, long flags ) )

Calling this returns the 2's complement of the return value
of the external function call. Is it expected that the code calling
this do the decoding of the 2'complement representation of
the return value?

Cheers,

Paulo

Reply | Threaded
Open this post in threaded view
|

Re: Return value of a FFI call to a external function is its 2`s complement

kilon.alios
Ah ok I know that one, just did not know it was named "two's complement" , looks to me normal error. I have seen this value many times in case of errors while debugging C code with GBP

It returns error probably because of the reason I outlined in my previous reply. 

On Mon, Oct 30, 2017 at 3:51 PM Paulo R. Dellani <[hidden email]> wrote:
"Two`s complement" is one possible way to represent signed integers in binary form (1).

When the message apiZmqMsgRecv: message socket: socket withFlags: flags is sent, as
shown in my prior message, a function from libzmq, zmq_msg_recv (2) is called
and the return value should be either the number of bytes in the received message
or -1, in case of an error. Well, I was expecting to get a -1 as return value when
calling the function in non-blocking mode, but it returns 0xFFFFFFFF, which happens
to be the 2's complement representation of -1. At least the old code for libZMQ
was not expecting that.

Cheers, Paulo

(1) https://en.wikipedia.org/wiki/Two's_complement
(2) http://api.zeromq.org/4-2:zmq-msg-recv


On 10/30/2017 02:13 PM, Dimitris Chloupis wrote:

I have no idea what you mean by "2's complement" 

In any case bare in mind that UFFI has a limited range of C types that does support. Here you use 2 custom types , ZmqApiMessage and ZmqApiSocket , both are pointers because of * . Now these types are definetly not included with UFFI so if you have not done so you will have to
 
1) Define a class that inherits from FFIExternalObject and make sure your class handles the pointer properly 
2) Replace the custom type with an equivelant type that is supported by UFFI

The type of the pointer does not affect the pointer itself, usually, but rather the data it points to. So a pointer knows from it type that the data consumes a x amount of bytes and is of specific type , this can help also with indexing as C arrays are nothing more than a pointer that uses the index as an offset depending on its type of x amount of bytes. 

So its crucial that you get these right or else you going have some super weird results and even crashes. 

Because if you use improper types the pointer will give access to an area of memory bigger or smaller than the inteded type . Smaller will give you corrupted data (you will be missing bytes of data), bigger may crash because it may extend to area of memory not allowed to access. 

Technically speaking you can use even incorrect types if you know what you doing because UFFI pointers have great flexibility allowing you define real time the excact position of the memory and the range. 

Bare in mind that C is a high level language (and not low level as many incorrect assume) and deal with types that is NOT a low level concept (excepts types that have to do only with the size/ amount of bits) . So the type gives crucial information to C how exactly to access the memory. 
On Mon, Oct 30, 2017 at 2:03 PM Paulo R. Dellani <[hidden email]> wrote:
Dear uFFI experts,

I am dealing with the port of the ZeroMQ code to Pharo 6 and found
something unexpected to me, at least:

Zmq4Api>>apiZmqMsgRecv: message socket: socket withFlags: flags
    ^ self ffiCall: #(long zmq_msg_recv (ZmqApiMessage* message, ZmqApiSocket* socket, long flags ) )

Calling this returns the 2's complement of the return value
of the external function call. Is it expected that the code calling
this do the decoding of the 2'complement representation of
the return value?

Cheers,

Paulo

Reply | Threaded
Open this post in threaded view
|

Re: Return value of a FFI call to a external function is its 2`s complement

tesonep@gmail.com
Hi, 
 the problem is that the Zq function has the following signature:

int zmq_msg_recv (zmq_msg_t *msg, void *socket, int flags);

And in your ffiCall you are putting #long. 

You should use the correct size of integers, as the binary numbers need to extend the size when they are negatives. 

0xFFFFFFFF is a valid positive for a long, but a -1 for an int. 

Cheers.

On Mon, Oct 30, 2017 at 4:26 PM, Dimitris Chloupis <[hidden email]> wrote:
Ah ok I know that one, just did not know it was named "two's complement" , looks to me normal error. I have seen this value many times in case of errors while debugging C code with GBP

It returns error probably because of the reason I outlined in my previous reply. 

On Mon, Oct 30, 2017 at 3:51 PM Paulo R. Dellani <[hidden email]> wrote:
"Two`s complement" is one possible way to represent signed integers in binary form (1).

When the message apiZmqMsgRecv: message socket: socket withFlags: flags is sent, as
shown in my prior message, a function from libzmq, zmq_msg_recv (2) is called
and the return value should be either the number of bytes in the received message
or -1, in case of an error. Well, I was expecting to get a -1 as return value when
calling the function in non-blocking mode, but it returns 0xFFFFFFFF, which happens
to be the 2's complement representation of -1. At least the old code for libZMQ
was not expecting that.

Cheers, Paulo

(1) https://en.wikipedia.org/wiki/Two's_complement
(2) http://api.zeromq.org/4-2:zmq-msg-recv


On 10/30/2017 02:13 PM, Dimitris Chloupis wrote:

I have no idea what you mean by "2's complement" 

In any case bare in mind that UFFI has a limited range of C types that does support. Here you use 2 custom types , ZmqApiMessage and ZmqApiSocket , both are pointers because of * . Now these types are definetly not included with UFFI so if you have not done so you will have to
 
1) Define a class that inherits from FFIExternalObject and make sure your class handles the pointer properly 
2) Replace the custom type with an equivelant type that is supported by UFFI

The type of the pointer does not affect the pointer itself, usually, but rather the data it points to. So a pointer knows from it type that the data consumes a x amount of bytes and is of specific type , this can help also with indexing as C arrays are nothing more than a pointer that uses the index as an offset depending on its type of x amount of bytes. 

So its crucial that you get these right or else you going have some super weird results and even crashes. 

Because if you use improper types the pointer will give access to an area of memory bigger or smaller than the inteded type . Smaller will give you corrupted data (you will be missing bytes of data), bigger may crash because it may extend to area of memory not allowed to access. 

Technically speaking you can use even incorrect types if you know what you doing because UFFI pointers have great flexibility allowing you define real time the excact position of the memory and the range. 

Bare in mind that C is a high level language (and not low level as many incorrect assume) and deal with types that is NOT a low level concept (excepts types that have to do only with the size/ amount of bits) . So the type gives crucial information to C how exactly to access the memory. 
On Mon, Oct 30, 2017 at 2:03 PM Paulo R. Dellani <[hidden email]> wrote:
Dear uFFI experts,

I am dealing with the port of the ZeroMQ code to Pharo 6 and found
something unexpected to me, at least:

Zmq4Api>>apiZmqMsgRecv: message socket: socket withFlags: flags
    ^ self ffiCall: #(long zmq_msg_recv (ZmqApiMessage* message, ZmqApiSocket* socket, long flags ) )

Calling this returns the 2's complement of the return value
of the external function call. Is it expected that the code calling
this do the decoding of the 2'complement representation of
the return value?

Cheers,

Paulo




--
Pablo Tesone.
[hidden email]
Reply | Threaded
Open this post in threaded view
|

Re: Return value of a FFI call to a external function is its 2`s complement

dellani
Hi Pablo,

correcting the type declaration in the ffiCall solved the problem, thanks!

Cheers,

Paulo

On 10/30/2017 05:24 PM, [hidden email] wrote:
Hi, 
 the problem is that the Zq function has the following signature:

int zmq_msg_recv (zmq_msg_t *msg, void *socket, int flags);

And in your ffiCall you are putting #long. 

You should use the correct size of integers, as the binary numbers need to extend the size when they are negatives. 

0xFFFFFFFF is a valid positive for a long, but a -1 for an int. 

Cheers.


--
Pablo Tesone.
[hidden email]