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