public inbox for libffi-discuss@sourceware.org
 help / color / mirror / Atom feed
* *printf functions
@ 2015-04-24 21:54 Bruce Korb
  2015-04-24 23:24 ` Richard Henderson
  0 siblings, 1 reply; 3+ messages in thread
From: Bruce Korb @ 2015-04-24 21:54 UTC (permalink / raw)
  To: libffi-discuss

Hi,

My number 1 need is for calling printf functions based upon derived information.
Since there is no widespread argument vector implementations of *printf
(the abortive "snprintfv" library excepted due to the "widespread" requirement),
I need to construct calls to the snprintf function.  I know about the vararg
caveats, but there is also the notation that "it often works anyway", so I
was hoping that it would for snprintf under Linux on an x86-64:

> $ /lib64/libc.so.6
> GNU C Library (GNU libc) stable release version 2.18 (git ), by Roland McGrath et al.
> Copyright (C) 2013 Free Software Foundation, Inc.

> $ gcc --version|head -n2
> gcc (SUSE Linux) 4.8.1 20130909 [gcc-4_8-branch revision 202388]
> Copyright (C) 2013 Free Software Foundation, Inc.

So, I constructed this call

> Breakpoint 1, print_one_event (evd=0x7ffff5ecc088) at evt/src/event-print.c:181
> 181                             ffi_call(&cif, snprintf_fn, &snprintf_res, values);
> (gdb) p cif
> $1 = {abi = FFI_UNIX64, nargs = 5, arg_types = 0x663c1f0,
>   rtype = 0x40e490 <ffi_type_uint32>, bytes = 0, flags = 9}
> (gdb) p cif.arg_types[0]
> $2 = (ffi_type *) 0x40e510 <ffi_type_pointer>
> (gdb) p cif.arg_types[1]
> $3 = (ffi_type *) 0x40e4d0 <ffi_type_uint64>
> (gdb) p cif.arg_types[2]
> $4 = (ffi_type *) 0x40e510 <ffi_type_pointer>
> (gdb) p cif.arg_types[3]
> $5 = (ffi_type *) 0x40e490 <ffi_type_uint32>
> (gdb) p cif.arg_types[4]
> $6 = (ffi_type *) 0x40e490 <ffi_type_uint32>
[...]
> (gdb) p (char *)values[0]
> $10 = 0x7fffffffc6b4 ""
> (gdb) p *(int*)values[1]
> $11 = 4044
> (gdb) p (char *)values[2]
> $12 = 0x40e360 "Allocated sblock_id=%d for band_id=%d\n"
> (gdb) p *(int*)values[3]
> $13 = 1
> (gdb) p *(int*)values[4]
> $14 = 1

so it all seems right (is it?), but clearly I would not be writing if it went well.
Is my hope to use libffi for calling snprintf a vein one?

Thank you.

> (gdb) c
> Continuing.
>
> Program received signal SIGSEGV, Segmentation fault.
> 0x00007ffff7446892 in vsnprintf () from /lib64/libc.so.6
> (gdb) bt
> #0  0x00007ffff7446892 in vsnprintf () from /lib64/libc.so.6
> #1  0x00007ffff7424ff2 in snprintf () from /lib64/libc.so.6
> #2  0x000000000040b660 in ffi_call_unix64 () at ../src/x86/unix64.S:76
> #3  0x000000000040b02f in ffi_call (cif=0x7fffffffc640,
>     fn=0x401250 <snprintf@plt>, rvalue=0x7fffffffc66c, avalue=0x663c230)
>     at ../src/x86/ffi64.c:525

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

* Re: *printf functions
  2015-04-24 21:54 *printf functions Bruce Korb
@ 2015-04-24 23:24 ` Richard Henderson
  2015-04-25 17:31   ` Bruce Korb
  0 siblings, 1 reply; 3+ messages in thread
From: Richard Henderson @ 2015-04-24 23:24 UTC (permalink / raw)
  To: Bruce Korb, libffi-discuss

On 04/24/2015 11:54 AM, Bruce Korb wrote:
> Is my hope to use libffi for calling snprintf a vein one?

As long as you used ffi_prep_cif_var instead of ffi_prep_cif it will work.  You
didn't quote enough of your source to see that part.


r~

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

* Re: *printf functions
  2015-04-24 23:24 ` Richard Henderson
@ 2015-04-25 17:31   ` Bruce Korb
  0 siblings, 0 replies; 3+ messages in thread
From: Bruce Korb @ 2015-04-25 17:31 UTC (permalink / raw)
  To: Richard Henderson, libffi-discuss

On 04/24/15 16:24, Richard Henderson wrote:
> On 04/24/2015 11:54 AM, Bruce Korb wrote:
>> Is my hope to use libffi for calling snprintf a vein one?
>
> As long as you used ffi_prep_cif_var instead of ffi_prep_cif it will work.  You
> didn't quote enough of your source to see that part.

OK, here's the more complete debug session:

148             ffi_type ** args = assemble_ffi_args(evd, edsc, &values);
(gdb) n
153             values[0] = buf;
(gdb)
154             args[0]   = &ffi_type_pointer;
(gdb)
156             values[1] = &spc;
(gdb)
157             args[1]   = (sizeof(size_t) == sizeof(u64))
(gdb)
160             values[2] = UNCONST(ev_fmt);
(gdb)
161             args[2]   = &ffi_type_pointer;
(gdb)
163             if (ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 3, edsc->edsc_argct + 3,
(gdb)
167                     ffi_call(&cif, fn, &ret_val, values);
(gdb) p cif
$1 = {abi = FFI_UNIX64, nargs = 5, arg_types = 0x8710510,
   rtype = 0x613dd0 <ffi_type_uint32>, bytes = 0, flags = 9}
(gdb) p cif.arg_types[0]
$2 = (ffi_type *) 0x613db0 <ffi_type_pointer>
(gdb) p cif.arg_types[1]
$3 = (ffi_type *) 0x613d90 <ffi_type_uint64>
(gdb) p cif.arg_types[2]
$4 = (ffi_type *) 0x613db0 <ffi_type_pointer>
(gdb) p cif.arg_types[3]
$5 = (ffi_type *) 0x613dd0 <ffi_type_uint32>
(gdb) p cif.arg_types[4]
$6 = (ffi_type *) 0x613dd0 <ffi_type_uint32>
(gdb) p (char *)values[0]
$7 = 0x7fffffffc6b4 ""
(gdb) p *(unsigned long *)values[1]
$8 = 4044
(gdb) p (char *)values[2]
$9 = 0x40fe70 "Allocated sblock_id=%d for band_id=%d"
(gdb) p *(unsigned *)values[3]
$10 = 1
(gdb) p *(unsigned *)values[4]
$11 = 1
(gdb) p fn
$12 = (void *) 0x4012d0 <snprintf@plt>

So I put together the "var" portion of the arg list with "assemble_ffi_args()" and upon
return insert the three fixed args (destination, size and format string).
I've printed out the "cif", the arg types and the arg values and they all look correct.
I will now press "n" and "<enter>" and have a seg fault:

> (gdb) n
>
> Program received signal SIGSEGV, Segmentation fault.
> 0x00007ffff7455892 in vsnprintf () from /lib64/libc.so.6

:(  This would make for a perfect example for the use of ffi_prep_cif_var() :)

> (gdb) bt
> #0  0x00007ffff7455892 in vsnprintf () from /lib64/libc.so.6
> #1  0x00007ffff7433ff2 in snprintf () from /lib64/libc.so.6
> #2  0x00007ffff7796cd8 in ffi_call_unix64 () from /usr/lib64/libffi.so.4
> #3  0x00007ffff7796729 in ffi_call () from /usr/lib64/libffi.so.4

P.S. I also have a /usr/local/lib64/libffi.a built with "-O0 -ggdb3 -gdwarf-2",
if more debugging stuff is useful.

> Breakpoint 1, format_one_event (buf=0x7fffffffc6b4 "", spc=4044,
>     fn=0x401250 <snprintf@plt>, evd=0x7ffff5ecc088,
>     ev_fmt=0x411630 "Allocated sblock_id=%d for band_id=%d",
>     edsc=0x615a98 <event_data_for_sblock+56>) at evt/src/event-print.c:148
> 148             ffi_type ** args = assemble_ffi_args(evd, edsc, &values);
> (gdb) c
> Continuing.
>
> Breakpoint 2, ffi_call_unix64 () at ../src/x86/unix64.S:49
> 49              movq    (%rsp), %r10            /* Load return address.  */

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

end of thread, other threads:[~2015-04-25 17:31 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-04-24 21:54 *printf functions Bruce Korb
2015-04-24 23:24 ` Richard Henderson
2015-04-25 17:31   ` Bruce Korb

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