This is the mail archive of the libc-hacker@sources.redhat.com mailing list for the glibc project.
Note that libc-hacker is a closed list. You may look at the archives of this list, but subscription and posting are not open.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
Hi! memusage does not work with any threaded program. The problem is that malloc or calloc call dlsym, which in turn (through _dlerror_run) call calloc and thus end up in endless recursion. Fortunately, in _dlerror_run nothing bad happens if calloc returns NULL, because 1) dlsym (RTLD_NEXT, "") will succeed, there are at least the alloc routines in glibc and 2) no threads are running yet (because pthread_initialize_manager calls malloc) and thus the static area can be used without problems. I tried to use a static variable for the first thread instead in dlerror.c (init), but it did not help - because pthread_setspecific calls calloc as well. 2001-08-07 Jakub Jelinek <jakub@redhat.com> * malloc/memusage.c (initializing): New variable. (malloc): Set/clear it. Initialize mallocp and callocp together. (calloc): Likewise. If initializing, return NULL. --- libc/malloc/memusage.c.jj Fri Jul 6 00:55:35 2001 +++ libc/malloc/memusage.c Tue Aug 7 08:40:35 2001 @@ -82,6 +82,7 @@ static size_t buffer_size; static int fd = -1; static int not_me; +static int initializing; extern const char *__progname; struct entry @@ -264,7 +265,10 @@ malloc (size_t len) if (mallocp == NULL) { me (); + initializing = 1; mallocp = (void *(*) (size_t)) dlsym (RTLD_NEXT, "malloc"); + callocp = (void *(*) (size_t, size_t)) dlsym (RTLD_NEXT, "calloc"); + initializing = 0; } /* If this is not the correct program just use the normal function. */ @@ -385,17 +389,23 @@ calloc (size_t n, size_t len) room to the allocation to put the header in. */ if (mallocp == NULL) { + /* dlsym may call calloc, in which case we'd end up in endless + recursion. No threads should be running at this point, since + pthread_initialize_manager calls malloc. If calloc returns + NULL in _dlerror_run, a static buffer will be used which is + fine, since no threads are running yet. */ + if (initializing) + return NULL; me (); + initializing = 1; mallocp = (void *(*) (size_t)) dlsym (RTLD_NEXT, "malloc"); + callocp = (void *(*) (size_t, size_t)) dlsym (RTLD_NEXT, "calloc"); + initializing = 0; } /* If this is not the correct program just use the normal function. */ if (not_me) - { - callocp = (void *(*) (size_t, size_t)) dlsym (RTLD_NEXT, "calloc"); - - return (*callocp) (n, len); - } + return (*callocp) (n, len); /* Keep track of number of calls. */ ++calls[idx_calloc]; Jakub
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |