public inbox for libffi-discuss@sourceware.org
 help / color / mirror / Atom feed
* return value buffer malloc()'ed vs alloca()'ed
@ 2013-10-08 17:14 Igor Bogomazov
  2013-10-08 17:30 ` Anthony Green
  2013-10-08 17:33 ` return value buffer malloc()'ed vs alloca()'ed Andrew Haley
  0 siblings, 2 replies; 9+ messages in thread
From: Igor Bogomazov @ 2013-10-08 17:14 UTC (permalink / raw)
  To: libffi-discuss

Hello,

I've been trying to investigate valgrind warnings for a while and found
an undocumented feature, please let me know if it is well-known.

What I did.

I modified a code given in «2.2 Simple Example» so that return value
(rc), originally declared as (int), became an (int *)malloc(sizeof(int))
so that it is resident in heap since that. Of cource, (&rc) replaced
with (rc) later in the code.

What I get.

valgrind complaints about «Invalid write of size 8» while «Address
0x55ec040 is 0 bytes inside a block of size 4 alloc'd», it is exactly
that allocated (rc) buffer.

Notes.

Allocating buffer for the return value using alloca() does the trick and
makes valgrind silent.

Further.

I looked at x86/unix64.S, it is exactly the line:
movq	%rax, (%rdi)
that causes the valgrind's warning (at .Lst_uint32)

That is my question: is it necessary to allocate a buffer for the return
value with alloca() and never with malloc()?

-- 
Sincerely yours,

Igor Bogomazov

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: return value buffer malloc()'ed vs alloca()'ed
  2013-10-08 17:14 return value buffer malloc()'ed vs alloca()'ed Igor Bogomazov
@ 2013-10-08 17:30 ` Anthony Green
  2013-10-08 17:36   ` Andrew Haley
  2013-10-08 17:33 ` return value buffer malloc()'ed vs alloca()'ed Andrew Haley
  1 sibling, 1 reply; 9+ messages in thread
From: Anthony Green @ 2013-10-08 17:30 UTC (permalink / raw)
  To: Igor Bogomazov; +Cc: libffi-discuss

Igor,

  You've hit one of the oddities of the libffi API.   The result
buffer needs to be the largest native integral type on your system.
Use a 64 bit long for rc instead of mallocing the exact return type
size.  You can pass it into ffi_call as &rc and simply cast it to an
int at the end.   I just checked the docs and it's definitely not
clear.  I'll fix this.   libffi is just a tiny bit faster when it can
make this size assumption, but I agree that it isn't pretty.

AG

On Tue, Oct 8, 2013 at 1:13 PM, Igor Bogomazov <ygrex@ygrex.ru> wrote:
> Hello,
>
> I've been trying to investigate valgrind warnings for a while and found
> an undocumented feature, please let me know if it is well-known.
>
> What I did.
>
> I modified a code given in «2.2 Simple Example» so that return value
> (rc), originally declared as (int), became an (int *)malloc(sizeof(int))
> so that it is resident in heap since that. Of cource, (&rc) replaced
> with (rc) later in the code.
>
> What I get.
>
> valgrind complaints about «Invalid write of size 8» while «Address
> 0x55ec040 is 0 bytes inside a block of size 4 alloc'd», it is exactly
> that allocated (rc) buffer.
>
> Notes.
>
> Allocating buffer for the return value using alloca() does the trick and
> makes valgrind silent.
>
> Further.
>
> I looked at x86/unix64.S, it is exactly the line:
> movq    %rax, (%rdi)
> that causes the valgrind's warning (at .Lst_uint32)
>
> That is my question: is it necessary to allocate a buffer for the return
> value with alloca() and never with malloc()?
>
> --
> Sincerely yours,
>
> Igor Bogomazov
>

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: return value buffer malloc()'ed vs alloca()'ed
  2013-10-08 17:14 return value buffer malloc()'ed vs alloca()'ed Igor Bogomazov
  2013-10-08 17:30 ` Anthony Green
@ 2013-10-08 17:33 ` Andrew Haley
  1 sibling, 0 replies; 9+ messages in thread
From: Andrew Haley @ 2013-10-08 17:33 UTC (permalink / raw)
  To: Igor Bogomazov; +Cc: libffi-discuss

On 10/08/2013 06:13 PM, Igor Bogomazov wrote:
> Hello,
> 
> I've been trying to investigate valgrind warnings for a while and found
> an undocumented feature, please let me know if it is well-known.
> 
> What I did.
> 
> I modified a code given in «2.2 Simple Example» so that return value
> (rc), originally declared as (int), became an (int *)malloc(sizeof(int))
> so that it is resident in heap since that. Of cource, (&rc) replaced
> with (rc) later in the code.
> 
> What I get.
> 
> valgrind complaints about «Invalid write of size 8» while «Address
> 0x55ec040 is 0 bytes inside a block of size 4 alloc'd», it is exactly
> that allocated (rc) buffer.
> 
> Notes.
> 
> Allocating buffer for the return value using alloca() does the trick and
> makes valgrind silent.
> 
> Further.
> 
> I looked at x86/unix64.S, it is exactly the line:
> movq	%rax, (%rdi)
> that causes the valgrind's warning (at .Lst_uint32)
> 
> That is my question: is it necessary to allocate a buffer for the return
> value with alloca() and never with malloc()?

As far as I can see, libffi always writes a whole word into the rvalue:

.Lst_uint8:
	movzbq	%al, %rax
	movq	%rax, (%rdi)
	ret
	.align 2
.Lst_sint8:
	movsbq	%al, %rax
	movq	%rax, (%rdi)
	ret
	.align 2
.Lst_uint16:
	movzwq	%ax, %rax
	movq	%rax, (%rdi)
	.align 2
        ...

This looks quite deliberate, but it is rather different from what the
documentation specifies:

     RVALUE is a pointer to a chunk of memory that will hold the result
     of the function call.  This must be large enough to hold the
     result and must be suitably aligned; it is the caller's
     responsibility to ensure this

So it's definitely a bug, but I don't know whether it's a bug in libffi or
in its documentation.

Andrew.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: return value buffer malloc()'ed vs alloca()'ed
  2013-10-08 17:30 ` Anthony Green
@ 2013-10-08 17:36   ` Andrew Haley
  2013-10-08 17:40     ` Anthony Green
  0 siblings, 1 reply; 9+ messages in thread
From: Andrew Haley @ 2013-10-08 17:36 UTC (permalink / raw)
  To: Anthony Green; +Cc: Igor Bogomazov, libffi-discuss

On 10/08/2013 06:30 PM, Anthony Green wrote:
> The result
> buffer needs to be the largest native integral type on your system.
> Use a 64 bit long for rc instead of mallocing the exact return type
> size.  You can pass it into ffi_call as &rc and simply cast it to an
> int at the end.   I just checked the docs and it's definitely not
> clear

Hmmmmm.  It's not so much unclear as completely wrong.

Andrew.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: return value buffer malloc()'ed vs alloca()'ed
  2013-10-08 17:36   ` Andrew Haley
@ 2013-10-08 17:40     ` Anthony Green
  2013-10-08 17:45       ` Andrew Haley
  2013-11-15 16:18       ` Broken tests in libffi testsuite Andrew Haley
  0 siblings, 2 replies; 9+ messages in thread
From: Anthony Green @ 2013-10-08 17:40 UTC (permalink / raw)
  To: Andrew Haley; +Cc: Anthony Green, Igor Bogomazov, libffi-discuss

We've had this discussion many times...

https://www.google.com/search?q=libffi+largest+integral+type&ie=utf-8&oe=utf-8&aq=t&rls=org.mozilla:en-US:official&client=firefox-a

particularly...

http://sourceware-org.1504.n7.nabble.com/closure-api-return-value-types-problem-td201402.html

I've written it off as a wart that we must live with (so, a documentation bug).  But maybe somebody can demonstrate how to change it without impacting current users.
 
AG


----- Original Message -----
From: "Andrew Haley" <aph@redhat.com>
To: "Anthony Green" <green@moxielogic.com>
Cc: "Igor Bogomazov" <ygrex@ygrex.ru>, libffi-discuss@sourceware.org
Sent: Tuesday, October 8, 2013 1:36:10 PM
Subject: Re: return value buffer malloc()'ed vs alloca()'ed

On 10/08/2013 06:30 PM, Anthony Green wrote:
> The result
> buffer needs to be the largest native integral type on your system.
> Use a 64 bit long for rc instead of mallocing the exact return type
> size.  You can pass it into ffi_call as &rc and simply cast it to an
> int at the end.   I just checked the docs and it's definitely not
> clear

Hmmmmm.  It's not so much unclear as completely wrong.

Andrew.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: return value buffer malloc()'ed vs alloca()'ed
  2013-10-08 17:40     ` Anthony Green
@ 2013-10-08 17:45       ` Andrew Haley
  2013-10-09  5:09         ` Igor Bogomazov
  2013-11-15 16:18       ` Broken tests in libffi testsuite Andrew Haley
  1 sibling, 1 reply; 9+ messages in thread
From: Andrew Haley @ 2013-10-08 17:45 UTC (permalink / raw)
  To: Anthony Green; +Cc: Anthony Green, Igor Bogomazov, libffi-discuss

On 10/08/2013 06:40 PM, Anthony Green wrote:
> We've had this discussion many times...
> 
> https://www.google.com/search?q=libffi+largest+integral+type&ie=utf-8&oe=utf-8&aq=t&rls=org.mozilla:en-US:official&client=firefox-a
> 
> particularly...
> 
> http://sourceware-org.1504.n7.nabble.com/closure-api-return-value-types-problem-td201402.html
> 
> I've written it off as a wart that we must live with (so, a documentation bug).  But maybe somebody can demonstrate how to change it without impacting current users.

I'd garbage-collected it from my brain.  I'm surprised no-one got
around to fixing the docs, and the "simple example" !

... but then I didn't do it either.

Andrew.


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: return value buffer malloc()'ed vs alloca()'ed
  2013-10-08 17:45       ` Andrew Haley
@ 2013-10-09  5:09         ` Igor Bogomazov
  0 siblings, 0 replies; 9+ messages in thread
From: Igor Bogomazov @ 2013-10-09  5:09 UTC (permalink / raw)
  To: Andrew Haley; +Cc: Anthony Green, Anthony Green, libffi-discuss

On Tue, 08 Oct 2013 18:45:50 +0100
Andrew Haley <aph@redhat.com> wrote:

> On 10/08/2013 06:40 PM, Anthony Green wrote:
> > We've had this discussion many times...
> > 
> > https://www.google.com/search?q=libffi+largest+integral+type&ie=utf-8&oe=utf-8&aq=t&rls=org.mozilla:en-US:official&client=firefox-a
> > 
> > particularly...
> > 
> > http://sourceware-org.1504.n7.nabble.com/closure-api-return-value-types-problem-td201402.html
> > 
> > I've written it off as a wart that we must live with (so, a
> > documentation bug).  But maybe somebody can demonstrate how to
> > change it without impacting current users.
> 
> I'd garbage-collected it from my brain.  I'm surprised no-one got
> around to fixing the docs, and the "simple example" !
> 
> ... but then I didn't do it either.
> 
> Andrew.
> 

Thank you,

I have got a clue

stack/heap allocation does not matter here

-- 
Sincerely yours,

Igor Bogomazov

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Broken tests in libffi testsuite
  2013-10-08 17:40     ` Anthony Green
  2013-10-08 17:45       ` Andrew Haley
@ 2013-11-15 16:18       ` Andrew Haley
  2013-11-16 11:24         ` Alan Modra
  1 sibling, 1 reply; 9+ messages in thread
From: Andrew Haley @ 2013-11-15 16:18 UTC (permalink / raw)
  To: Anthony Green; +Cc: Anthony Green, libffi-discuss

Following our discussion about the fact that return values are
full-word-sized, here are some tests that were using libffi
incorrectly, and thus failing on (big-endian)
powerpc64-redhat-linux-gnu.

With these changes I get a clean test run.

Andrew.


2013-11-15    Andrew Haley <aph@redhat.com>

	* testsuite/libffi.call/va_struct1.c (main): Fix broken test.
	* testsuite/libffi.call/cls_uint_va.c (cls_ret_T_fn): Likewise
	* testsuite/libffi.call/cls_struct_va1.c (test_fn): Likewise.
	* testsuite/libffi.call/va_1.c (main): Likewise.

diff --git a/testsuite/libffi.call/cls_struct_va1.c b/testsuite/libffi.call/cls_struct_va1.c
index 175ed96..6d1fdae 100644
--- a/testsuite/libffi.call/cls_struct_va1.c
+++ b/testsuite/libffi.call/cls_struct_va1.c
@@ -35,7 +35,7 @@ test_fn (ffi_cif* cif __UNUSED__, void* resp,
   printf ("%d %d %d %d %d %d %d %d %d %d\n", n, s1.a, s1.b,
          l1.a, l1.b, l1.c, l1.d, l1.e,
          s2.a, s2.b);
-  * (int*) resp = 42;
+  * (ffi_arg*) resp = 42;
 }

 int
diff --git a/testsuite/libffi.call/cls_uint_va.c b/testsuite/libffi.call/cls_uint_va.c
index 150fddd..548d8c6 100644
--- a/testsuite/libffi.call/cls_uint_va.c
+++ b/testsuite/libffi.call/cls_uint_va.c
@@ -10,12 +10,13 @@

 typedef unsigned int T;

-static void cls_ret_T_fn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+static void cls_ret_T_fn(ffi_cif* cif __UNUSED__, void *resp, void** args,
                         void* userdata __UNUSED__)
  {
-   *(T *)resp = *(T *)args[0];
+   *(ffi_arg*)resp = *(T *)args[0];

-   printf("%d: %d %d\n", *(T *)resp, *(T *)args[0], *(T *)args[1]);
+
+   printf("%d: %d %d\n", (int)*(ffi_arg *)resp, *(T *)args[0], *(T *)args[1]);
  }

 typedef T (*cls_ret_T)(T, ...);
diff --git a/testsuite/libffi.call/va_1.c b/testsuite/libffi.call/va_1.c
index cf4dd85..7f96809 100644
--- a/testsuite/libffi.call/va_1.c
+++ b/testsuite/libffi.call/va_1.c
@@ -94,7 +94,7 @@ main (void)
   struct large_tag l1;

   int n;
-  int res;
+  ffi_arg res;

   unsigned char uc;
   signed char sc;
diff --git a/testsuite/libffi.call/va_struct1.c b/testsuite/libffi.call/va_struct1.c
index 11d1f10..e645206 100644
--- a/testsuite/libffi.call/va_struct1.c
+++ b/testsuite/libffi.call/va_struct1.c
@@ -61,7 +61,7 @@ main (void)
   struct large_tag l1;

   int n;
-  int res;
+  ffi_arg res;

   s_type.size = 0;
   s_type.alignment = 0;

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Broken tests in libffi testsuite
  2013-11-15 16:18       ` Broken tests in libffi testsuite Andrew Haley
@ 2013-11-16 11:24         ` Alan Modra
  0 siblings, 0 replies; 9+ messages in thread
From: Alan Modra @ 2013-11-16 11:24 UTC (permalink / raw)
  To: Andrew Haley; +Cc: Anthony Green, Anthony Green, libffi-discuss

On Fri, Nov 15, 2013 at 04:18:22PM +0000, Andrew Haley wrote:
> 2013-11-15    Andrew Haley <aph@redhat.com>
> 
> 	* testsuite/libffi.call/va_struct1.c (main): Fix broken test.
> 	* testsuite/libffi.call/cls_uint_va.c (cls_ret_T_fn): Likewise
> 	* testsuite/libffi.call/cls_struct_va1.c (test_fn): Likewise.
> 	* testsuite/libffi.call/va_1.c (main): Likewise.

This is https://sourceware.org/ml/libffi-discuss/2013/msg00199.html
and in the next message I update examples in doc/libffi.texi that
make the same errors.

-- 
Alan Modra
Australia Development Lab, IBM

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2013-11-16 11:24 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-10-08 17:14 return value buffer malloc()'ed vs alloca()'ed Igor Bogomazov
2013-10-08 17:30 ` Anthony Green
2013-10-08 17:36   ` Andrew Haley
2013-10-08 17:40     ` Anthony Green
2013-10-08 17:45       ` Andrew Haley
2013-10-09  5:09         ` Igor Bogomazov
2013-11-15 16:18       ` Broken tests in libffi testsuite Andrew Haley
2013-11-16 11:24         ` Alan Modra
2013-10-08 17:33 ` return value buffer malloc()'ed vs alloca()'ed Andrew Haley

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).