public inbox for libffi-discuss@sourceware.org
 help / color / mirror / Atom feed
From: "Stefan Sonnenberg-Carstens" <stefan.sonnenberg@pythonmeister.com>
To: "wp1068189-ssc" <stefan.sonnenberg@pythonmeister.com>
Cc: "Anthony Green" <green@moxielogic.com>, libffi-discuss@sourceware.org
Subject: Re: Passing function pointer to fcall
Date: Sun, 27 Nov 2011 14:12:00 -0000	[thread overview]
Message-ID: <d045c192962182d757e1c08290de93a5-EhVcX1lJRApWRxoDCzpQCEFddQZLVF5dQUBFCzBYWENGU1kWXlpwH1RcWzBeQkcAW1paQVpd-webmailer1@server06.webmailer.hosteurope.de> (raw)
In-Reply-To: <1668487104.152326.1322379214061.JavaMail.open-xchange@ox.hosteurope.de>

So, I extended the program some more:

#include <stdio.h>
#include <ffi.h>
#include <stdlib.h>
#include <windows.h>

int add(int a,int b, char *fmt,void *fn) {
    // int (*func)(char *,int) = (int (*)(char
*,int))GetProcAddress(GetModuleHandle("msvcrt.dll"),fn);
    int (*func)(char *,int) = (int (*)(char *,int))fn;
    return func(fmt,a+b);
}

int main(void)
    {

    ffi_cif cif;
    ffi_abi abi;
    ffi_status status;
    int nargs = 4;
    ffi_type *rtype = &ffi_type_sint32;
    ffi_type *atypes[4];
    void *avalues[4];
    int result;

    int a,b;
    a = 3;
    b = 4;

    char *fmt = "The answer is %i\n";
    char *fn  = "printf";

    atypes[0] = &ffi_type_sint32;
    atypes[1] = &ffi_type_sint32;
    atypes[2] = &ffi_type_pointer;
    atypes[3] = &ffi_type_pointer;

    avalues[0] = malloc(atypes[0]->size);
    avalues[1] = malloc(atypes[1]->size);

    *(int *) avalues[0] = a;
    *(int *) avalues[1] = b;
    avalues[2] = (char *) &fmt;
    avalues[3] = &printf;

    printf("direct call: %i",add(3,4,"erg: %i\n",&printf));

    status = ffi_prep_cif(&cif, FFI_DEFAULT_ABI, nargs, rtype, atypes);

    if(status != FFI_OK)
        printf("ffi_prep_cif failed (%i)\n",status);

    // crash occurs somewhere near here ...
    ffi_call(&cif,FFI_FN(add),&result,avalues);

    printf("%i\n",result);

    return 0 ;

    }


As you can see, I call my add function twice, once directly
and once via ffi_call.
Both times I pass a reference to printf.
As the direct method works, I guess the principal code is OK.

Now, when I run the program it shows:

$ dyn_callback.exe
erg: 7
direct call: 7

Then it crashes and creates this callstack:

dyn_callback.exe caused an Access Violation at location 614c25ff Reading
from location 614c25ff.

Registers:
eax=614c25ff ebx=0040138c ecx=00000000 edx=00000003 esi=45206472 edi=6085db86
eip=614c25ff esp=0022fe34 ebp=0022fe60 iopl=0         nv up ei pl nz na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202

Call stack:
AddrPC     AddrReturn AddrFrame  AddrStack  Params
614C25FF   004013AF   0022FE30   0022FE34   00403064   00000007   77C35C94
  77C12580
614C25FF
004013AF   6B746957   0022FE60   0022FE34   00000003   00000004   00403064
  614C25FF
004013AF  dyn_callback.exe:004013AF  add  dyn_callback.c:10

	...
	    int (*func)(char *,int) = (int (*)(char *,int))fn;
	    return func(fmt,a+b);
>	}

	int main(void)
	...

6B746957   6B7465AF   0022FE78   0022FE34   6B746298   0022FEB4   00000010
  00000001
6B746957  libffi-6.dll:6B746957  ffi_call_win32
6B7465AF   004014FB   0022FEC8   0022FE34   0022FF20   0040138C   0022FEFC
  0022FF00
6B7465AF  libffi-6.dll:6B7465AFC:\MinGW\msys\1.0\local\bin\libffi-6.dll:
No symbol found
  ffi_call
004014FB   004010B9   0022FF58   0022FE34   00000001   005B2C98   005B2ED0
  00405004
004014FB  dyn_callback.exe:004014FB  main  dyn_callback.c:53

	...
	    ffi_call(&cif,FFI_FN(add),&result,avalues);

>	    printf("%i\n",result);

	    return 0 ;
	...

004010B9   00401284   0022FFA0   0022FE34   00000001   A47CBD08   7C90DCBA
  7C817064
004010B9  dyn_callback.exe:004010B9  __mingw_CRTStartup  crt1.c:244

00401284   7C817067   0022FFC0   0022FE34   6085DB86   45206472   7FFDA000
  C0000005
00401284  dyn_callback.exe:00401284  WinMainCRTStartup  crt1.c:274

7C817067   00000000   0022FFF0   0022FE34   0040126C   00000000   00000000
  00000000
7C817067  kernel32.dll:7C817067
C:\WINDOWS\system32\kernel32.dll: No symbols
  RegisterWaitForInputIdle
DEBUG_EVENT:
	dwDebugEventCode = EXIT_PROCESS_DEBUG_EVENT
	dwProcessId = CCC
	dwThreadId = A30
	dwExitCode = C0000005

I installed libffi 3.0.11 beforhand, but sadly it produces no debugging
symbols.

  reply	other threads:[~2011-11-27 14:12 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-11-27  0:06 wp1068189-ssc
2011-11-27  4:05 ` Anthony Green
2011-11-27  7:33   ` wp1068189-ssc
2011-11-27 14:12     ` Stefan Sonnenberg-Carstens [this message]
2011-12-07 12:01       ` Anthony Green
2011-12-07 13:19         ` wp1068189-ssc

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=d045c192962182d757e1c08290de93a5-EhVcX1lJRApWRxoDCzpQCEFddQZLVF5dQUBFCzBYWENGU1kWXlpwH1RcWzBeQkcAW1paQVpd-webmailer1@server06.webmailer.hosteurope.de \
    --to=stefan.sonnenberg@pythonmeister.com \
    --cc=green@moxielogic.com \
    --cc=libffi-discuss@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).