This is the mail archive of the glibc-linux@ricardo.ecn.wfu.edu mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

More on Thread problem in XS code on Linux


I noticed that when I run the straight c version (m.c below) that at
malloc.c:2679 (from glibc-2.1.3-21.src.rpm from RedHat) that
__malloc_hook has a nonnull value.  But the in the .so version loaded by
perl (TT.xs below compiled to .so) __malloc_hook is null.  What do I
need to do to get __malloc_hook defined in the .so version?

Thank You,
James


James Scott Boorn wrote:

> > > > I suspect I am not linking properly.  The symptom is that malloc/free
> > > > does not seem to behave in a thread safe manner.  In a XS module the
> > > > code uses the pthread library to create a couple of threads, in the
> > > > threads lots of mallocs and frees are performed.  The code will fail
> > > > from Segmentation fault.  The sample code attached behaves the same on
> > > > two
> > > > differt machines.  The first is a dual cpu x86 box running RedHat 6.0
> > > > Linux with a hand build kernel 2.2.16, perl rpm is perl-5.00503-11, and
> > > > glibc rpm is glibc-2.1.3-21.  The second machine is a dual cpu x86 box
> > > > running RedHat 6.1 Linux, stock kernel 2.2.12-20smp, perl
> > > > perl-5.00503-11, and glibc-2.1.2-11.
> > > >
> > > > To compile edit makefile and type make.  Run test with 'perl test.pl'.
> > > >
> > > > Thanks,
> > > > James Boorn
>Here is build output:
> 
> perl /usr/lib/perl5/5.00503/ExtUtils/xsubpp -typemap
> /usr/lib/perl5/5.00503/ExtUtils/typemap TT.xs > TT.c
> Please specify prototyping behavior for TT.xs (see perlxs manual)
> cc -D_POSIX_REENTRANT_FUNCTIONS -DREENTRANT -g -Wall
> -I/usr/lib/perl5/5.00503/i386-linux/CORE -c TT.c
> TT.c: In function `boot_TT':
> TT.c:81: warning: unused variable `items'
> cc -Wl,-G -o TT.so TT.o -lpthread
> 
> I tried changing  -lpthread to -pthread, no difference.  Also note the c
> program below does the same thing, but works fine.  So I think it has
> something to do with the fact that the perl module is dynamically
> loaded, but I don't know how to figure out what is different at runtime
> to fix it.
> 
> This c program works (compile with 'cc -D_POSIX_REENTRANT_FUNCTIONS
> -DREENTRANT -g -o m m.c -lpthread')
> 
> #include <stdio.h>
> #include <pthread.h>
> 
> #define TESTSTRING "This is a test.  I am ok."
> 
> void foo(void *arg) {
>     char *bar;
>     int i, j, x;
> 
>     for (i = 0; i < 1000000; ++i) {
>         bar = (char*)malloc(26 * sizeof(char));
>         strcpy(bar, TESTSTRING);
>         for (x = 0, j = 0; j < 1000; ++j) {
>             x += j;
>         }
>         if (strcmp(bar, TESTSTRING)) {
>             printf("bar is %s, i = %d\n", bar, i);
>         }
>         free(bar);
>     }
> }
> 
> int main(int argc, char **argv) {
>     pthread_t *threads;
>     int i, tc = 2;
> 
>     if (argc > 1) {
>         tc = atoi(argv[1]);
>         if (tc < 1) return -1;
>     }
>     printf ("tc is %d\n", tc);
>     threads = (pthread_t*)malloc(tc * sizeof(pthread_t));
>     for (i = 0; i < tc; ++i) {
>         pthread_create(&threads[i], NULL, (void*)foo, NULL);
>     }
> 
>     for (i = 0; i < tc; ++i) {
>         pthread_join(threads[i], NULL);
>     }
> 
>     return 0;
> }
> 
> This perl code does not work (3 source file TT.xs TT.pm test.pl, after
> compiling TT.xs run 'perl test.pl')
> 
> /**** TT.xs compile with:
> perl /usr/lib/perl5/5.00503/ExtUtils/xsubpp -typemap
> /usr/lib/perl5/5.00503/ExtUtils/typemap TT.xs > TT.c
> gcc -D_POSIX_REENTRANT_FUNCTIONS -DREENTRANT -g -Wall
> -I/usr/lib/perl5/5.00503/i386-linux/CORE -c TT.c
> gcc -Wl,-G -o TT.so TT.o -lpthread
> ****/
> #include <stdio.h>
> #include <pthread.h>
> 
> typedef unsigned char bool;
> #include "EXTERN.h"
> #include "perl.h"
> #include "XSUB.h"
> 
> #ifdef __cplusplus
> extern "C" {
> #endif
> 
> #define TESTSTRING "This is a test.  I am ok."
> 
> void foo(void *arg) {
>     char *bar;
>     int i, j, x;
> 
>     for (i = 0; i < 1000000; ++i) {
>         bar = (char*)malloc(26 * sizeof(char));
>         strcpy(bar, TESTSTRING);
>         for (x = 0, j = 0; j < 1000; ++j) {
>             x += j;
>         }
>         if (strcmp(bar, TESTSTRING)) {
>             printf("bar is %s, i = %d\n", bar, i);
>         }
>         free(bar);
>     }
> }
> 
> int tt_run() {
>     pthread_t *threads;
>     int i, tc = 2;
> 
>     printf ("tc is %d\n", tc);
>     threads = (pthread_t*)malloc(tc * sizeof(pthread_t));
>     for (i = 0; i < tc; ++i) {
>         pthread_create(&threads[i], NULL, (void*)foo, NULL);
>     }
> 
>     for (i = 0; i < tc; ++i) {
>         pthread_join(threads[i], NULL);
>     }
> 
>     return 0;
> }
> 
> #ifdef __cplusplus
> }
> #endif
> 
> MODULE = TT     PACKAGE = TT    PREFIX = TT_
> 
> void
> TT_doit ()
>     CODE:
>         tt_run();
> 
> ##TT.pm
> package TT;
> 
> use Exporter;
> use DynaLoader;
> 
> BEGIN {
>     $VERSION = '0.01';
>     @ISA = qw(Exporter DynaLoader);
>     bootstrap TT $VERSION;
> }
> 
> 1;
> 
> ##test.pl
> use TT;
> 
> TT::doit();

here is the makefile
PERLEXUTILS=/usr/lib/perl5/5.00503/ExtUtils
PERLINC=/usr/lib/perl5/5.00503/i386-linux/CORE

all: TT.so m

m: m.c
	cc -D_POSIX_REENTRANT_FUNCTIONS -DREENTRANT -g -Wall -o m m.c -lpthread

TT.so: TT.o
	cc -Wl,-G -o TT.so TT.o -lpthread

TT.o: TT.c
	cc -D_POSIX_REENTRANT_FUNCTIONS -DREENTRANT -g -Wall -I$(PERLINC) -c
TT.c

TT.c: TT.xs
	perl $(PERLEXUTILS)/xsubpp -typemap $(PERLEXUTILS)/typemap TT.xs > TT.c

clean:
	rm -f TT.so TT.o TT.c core m

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]