This is the mail archive of the
glibc-linux@ricardo.ecn.wfu.edu
mailing list for the glibc project.
More on Thread problem in XS code on Linux
- To: bug-glibc at gnu dot org, glibc-linux at ricardo dot ecn dot wfu dot edu, perl-xs at perl dot org
- Subject: More on Thread problem in XS code on Linux
- From: James Scott Boorn <jboorn at seatab dot com>
- Date: Wed, 27 Sep 2000 17:27:44 -0700
- Newsgroups: comp.lang.perl,comp.os.linux.development.apps,comp.programming.threads
- Reply-To: glibc-linux at ricardo dot ecn dot wfu dot edu
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