delorie.com/archives/browse.cgi   search  
Mail Archives: cygwin/2005/09/08/05:05:52

Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm
List-Subscribe: <mailto:cygwin-subscribe AT cygwin DOT com>
List-Archive: <http://sourceware.org/ml/cygwin/>
List-Post: <mailto:cygwin AT cygwin DOT com>
List-Help: <mailto:cygwin-help AT cygwin DOT com>, <http://sourceware.org/ml/#faqs>
Sender: cygwin-owner AT cygwin DOT com
Mail-Followup-To: cygwin AT cygwin DOT com
Delivered-To: mailing list cygwin AT cygwin DOT com
Message-ID: <431FFEDC.9030908@carmen.se>
Date: Thu, 08 Sep 2005 11:05:32 +0200
From: Michael Spicar <Michael DOT Spicar AT carmen DOT se>
User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.7.10) Gecko/20050719 Red Hat/1.7.10-1.1.3.1
MIME-Version: 1.0
To: cygwin AT cygwin DOT com
Subject: Callbacks from shared libraries compiled with cygwin
X-Carmen_GOT-MailScanner-Information: Please contact IT/IS for more information
X-Carmen_GOT-MailScanner: Found to be clean
X-MailScanner-From: michael DOT spicar AT carmen DOT se

Hi!

I use cygwin 1.5.17/(0.129/4/2) on a vmware installation on a linux 
computer.

I have a small test application that consist of a main program and a 
shared library (dll) that is loaded by the main program with dlopen at 
RUNTIME. All is compiled with gcc and plain C-code.

I have a global variable or a global function that are implemented in 
the main program. If I call the variable or the function from within the 
   shared library will the program crash. I get this output:

Exception: STATUS_ACCESS_VIOLATION at eip=F03E0000
eax=003E305D ebx=00000004 ecx=6110AF48 edx=0000001F esi=61128080 
edi=610066BC
ebp=0022EF28 esp=0022EF1C 
program=C:\cygwin\home\rave\multiple\i386_cygin\main.e
xe, pid 1524, thread main
cs=001B ds=0023 es=0023 fs=003B gs=0000 ss=0023
Stack trace:
Frame     Function  Args
0022EF28  F03E0000  (003E305D, 00000063, 0022EFA8, 0040126D)
0022EF38  003E1050  (18682000, 004020B0, 00000009, 0040109C)
0022EFA8  0040126D  (00000001, 618251D0, 004600A8, 0022F000)
0022EFE8  61006A1D  (0022F000, 0022F020, 0022F368, 0022F880)
0022FF88  61006E41  (00000000, 00000000, 00000000, 00000000)

As I understand the man-page for 'ld' it should be possible to have
callbacks/references from a shared library back to the main program 
without specifying export/import-symbol-lists. This, however, 
contradicts a little with the information given on the cygwin page:
http://www.cygwin.com/cygwin-ug-net/dll.html.

So I have two questions:
1) Is it possible at all to have callbacks like this?
2) If yes, must I have the import/export-lists?

The supplied example just models the behaviour of the real, much bigger 
application, so the answers are important for me.

Best regards

Michael Spicar
michael DOT spicar AT carmensystems DOT com

-------------

The main program is compiled with:

gcc -Wl,-E -o main main.cc
(or alternatively)
gcc -Wl,--export-all-symbols main main.cc

and the shared library is compiled with:

cc -o libtaurus.so -shared -Wl,-Bsymbolic -Wl,-noinhibit-exec 
-Wl,--enable-auto-import -I. taurus.c cancer.c


main.c
-------
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
#include "globaldecls.h"
#include "eclipses.h"

#define DYNLIBS 1

const char libname[] = __FILE__;

int global = 0;

int eclipses(char *caller, char *grandfather) {
   printf("This is a eclipses in main caused by %s due to %s \n",
	 caller, grandfather);
   return 0;
}

main(int argc, char **argv)
{
   void *handle[DYNLIBS];
   int (*fptr[DYNLIBS])(int *);
   int *trythis;

   if ((handle[0] = dlopen("./taurus.so.1", RTLD_LAZY)) == NULL) {
     (void) printf("dlopen: %s\n", dlerror());
      exit(1);
    }

   if ((fptr[0] = (int (*)(int *)) dlsym(handle[0], "alfa")) == NULL) {
     (void) printf("0:alfa : dlsym: %s\n", dlerror());
     exit(1);
   }

   fptr[0](trythis);
   printf("global is now %d \n", global);

   if ((trythis = (int *) dlsym(handle[0], "sigma")) == NULL) {
     (void) printf("0:sigma : dlsym: %s\n", dlerror());
     exit(1);
   }

   if (handle[0] && dlclose(handle[0])) {
     (void) printf("0: dlclose failed %s\n", dlerror());
   }
}


taurus.c
--------
#include <stdio.h>
#include "cancer.h"
#include "globaldecls.h"

const char libname[] = __FILE__;

int sigma = 77;

int alfa(int *tau)
{
   global = 10;
   printf("This is alfa in Taurus \n");
   printf("Sending on %d MHz \n", *tau);
   printf("Now calling beta \n");
   beta();
   printf("Now calling gamma \n");
   gamma("taurus");
}

int beta()
{
   printf("This is beta in Taurus \n");
}

cancer.c
--------
#include <stdio.h>
#include "cancer.h"
#include "eclipses.h"
extern const char libname[];

int gamma(char *caller)
{
   printf("Calling gamma in %s\n", libname);
   printf("This is gamma in Cancer (yes, you get cancer from gamma rays) 
\n");
   printf("gamma is called from %s \n", caller);

   printf("Gamma will now cause eclipses \n");
   eclipses("gamma", caller);
}

eclipses.h
----------
extern int eclipses(char *, char *);

globaldecls.h
-------------
extern int global;

cancer.h
--------
extern int gamma(char *);

--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Problem reports:       http://cygwin.com/problems.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019