Date: Mon, 14 Nov 2005 15:45:55 +0100 From: Anton Berezin <tobez@tobez.org> To: Heiko Weber <heiko@wecos.de> Cc: mat@freebsd.org, freebsd-perl@freebsd.org Subject: Re: shared memory, perl, FreebSD 6 Message-ID: <20051114144555.GG68946@heechee.tobez.org> In-Reply-To: <200511141329.13933.heiko@wecos.de> References: <200511130055.20371.heiko@wecos.de> <20051114085811.GB68946@heechee.tobez.org> <200511141329.13933.heiko@wecos.de>
next in thread | previous in thread | raw e-mail | index | archive | help
On Mon, Nov 14, 2005 at 01:29:13PM +0100, Heiko Weber wrote: > Am Montag, 14. November 2005 09:58 schrieb Anton Berezin: > > On Sun, Nov 13, 2005 at 12:55:20AM +0100, Heiko Weber wrote: > > > I have problem using shared memory with perl. I tried p5-IPC-ShareLite: > > > > > > Segmentation fault (core dumped) > > > *** Error code 139 [Mathieu, are you paying attention? :-) ] Ok. The following patch should fix the problem with p5-IPC-ShareLite. You should cd /usr/ports/devel/p5-IPC-ShareLite ; make clean. Then copy the patch to files/patch-sharelite.c. Then rebuild. --- sharelite.c.orig Mon Nov 14 15:37:08 2005 +++ sharelite.c Mon Nov 14 15:37:41 2005 @@ -1,3 +1,7 @@ +#include "EXTERN.h" +#include "perl.h" +#include "XSUB.h" + #include <stdio.h> #include <stdlib.h> #include <sys/types.h> @@ -151,7 +155,7 @@ Node *_add_segment(Share *share) { Node *node; int flags; - if ((node = (Node *) malloc(sizeof(Node))) == NULL) + if ((node = (Node *) safemalloc(sizeof(Node))) == NULL) return NULL; node->next = NULL; @@ -196,7 +200,7 @@ int _detach_segments(Node *node) { while(node != NULL) { next_node = node->next; if (shmdt((char *) node->shmaddr) < 0) return -1; - free(node); + safefree(node); node = next_node; } return 0; @@ -329,7 +333,7 @@ int read_share(Share *share, char **data node = share->head; left = length = node->shmaddr->length; - if ((pos = *data = (char *) malloc( length )) == NULL) + if ((pos = *data = (char *) safemalloc( length )) == NULL) return -1; while(left) { @@ -379,7 +383,7 @@ again: segment_size = SHM_SEGMENT_SIZE; } - if ((node = (Node *) malloc(sizeof(Node))) == NULL) + if ((node = (Node *) safemalloc(sizeof(Node))) == NULL) return NULL; if ((node->shmid = shmget(key, segment_size, flags)) < 0) return NULL; @@ -387,7 +391,7 @@ again: return NULL; node->next = NULL; - if ((share = (Share *) malloc(sizeof(Share))) == NULL) + if ((share = (Share *) safemalloc(sizeof(Share))) == NULL) return NULL; share->key = key; share->next_key = key + 1; @@ -460,7 +464,7 @@ int destroy_share (Share *share, int rmi return -1; } - free(share); + safefree(share); return 0; } The problem is that by default perl is built with its own version of malloc. (The other solution would be to rebuild your perl with -DWITHOUT_PERL_MALLOC, but that is not a particularly good solution in general, since Perl malloc is heavily optimized to multiple reallocations, while FreeBSD system malloc is not). Normally, this is not a problem for Perl XS modules. Normally, it is not even a problem for Perl XS modules that are using 3rd-party C or C++ libraries. It is only a problem when the XS part (or one of the libraries/objects it is using) uses system malloc and then passes those pointers back to perl. The whole thing becomes acutely unhappy when it tries to free() stuff which was allocated using a different malloc library. Hence the coredump. I have not looked at the other module you had a problem with, but I won't be surprized to find a similar bug. Hope this helps, Cheers, \Anton. -- An undefined problem has an infinite number of solutions. -- Robert A. Humphrey
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20051114144555.GG68946>