* 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).