bug-gnu-utils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Bug in Heapmanagement of gettext-0.11.2 for systems without allloca-Supp


From: Andreas Fischer
Subject: Bug in Heapmanagement of gettext-0.11.2 for systems without allloca-Support
Date: Tue, 9 Jul 2002 17:28:37 +0200

This is a detailed description of the Bug in the Heap-Management of:
This only affects system without support for alloca()! 

I compiled gettext-0.11.2 for our system, which has an RTOS with limited
Task-Stacks, so I configured the gettext-Library to avoid alloca()
functions. 
config.h: 
        #undef HAVE_ALLOCA   0 
      #undef HAVE_ALLOCA_H 0

My configuration compiled and worked, but analyzing the heap after some
calls to gettext(), showed up an increasing amount of heapblocks.
With my configuration alloca() is replaced by calls to malloc() and
free().
Normally the calls to alloca() and freea() are balanced, but in the
module dcigettext.c a list of blocks is needed, which are linked
together with the macro ADD_BLOCK(list, addr)
and freed afterwards with FREE_BLOCKS(list).

The problem arises because ADD_BLOCK requests another Heap-Block to link
the data-blocks, but FREE_BLOCK() frees just the linking blocks, an not
the corresponding data.

This is my corrected version: (ADD_BLOCK() is unchanged and stated for
reference only! 
FREE_BLOCKS() now frees both blocks. 

------   Begin of Snippet from dcigettext.c ----
# define ADD_BLOCK(list, addr)
\
  do {
\
    struct block_list *newp = (struct block_list *) malloc (sizeof
(*newp)); \
    /* If we cannot get a free block we cannot add the new element to
\
       the list.  */
\
    if (newp != NULL) {
\
      newp->address = (addr);
\
      newp->next = (list);
\
      (list) = newp;
\
    }
\
  } while (0)

# define FREE_BLOCKS(list)
\
  do {
\
    while (list != NULL) {
\
      struct block_list *old = list;
\
      list = list->next;
\
      free (old->address); /* <--- Introduced to fix the bug!  */
\  
      free (old);
\
    }
\
  } while (0)
------   End of Snippet from dcigettext.c ----


Another bug is a lacking call to the macro ADD_BLOCK() in the function
DCIGETTEXT()
Comes into effect only if alloca() is not supported (#undef
HAVE_ALLOCA), and 
tfind () is available (#define HAVE_TSEARCH 1). 

------   Begin of Snippet from dcigettext.c ----
#if defined HAVE_TSEARCH || defined _LIBC
  msgid_len = strlen (msgid1) + 1;

  /* Try to find the translation among those which we found at
     some time.  */
  search = (struct known_translation_t *)
           alloca (offsetof (struct known_translation_t, msgid) +
msgid_len + BLOCKLISTSIZE);
  ADD_BLOCK (block_list, search);  /* <--- Introduced to allow freeing
of block with                    
                                            FREE_BLOCKS()on function
return! */

  memcpy (search->msgid, msgid1, msgid_len);
  search->domainname = (char *) domainname;
  search->category = category;
------   End of Snippet from dcigettext.c ----

--
Andreas Fischer
ASENTICS GmbH
Birlenbacher Str. 19-21
57078 Siegen, Germany




reply via email to

[Prev in Thread] Current Thread [Next in Thread]