[asterisk-dev] reasoning behind char[0]

Luigi Rizzo rizzo at iet.unipi.it
Wed Sep 30 11:31:05 CDT 2009


On Wed, Sep 30, 2009 at 11:01:05AM -0500, Kevin P. Fleming wrote:
> Boehm, Matthew wrote:
> 
> > I?ve been trying to understand some of the concepts in linkedlist.h and
> > loader.c.  My first quandry revolves around the use of ?char
> > resource[0]? in loader.c, struct ast_module.
> 
> That is done because when the 'struct ast_module' is allocated, we
> allocate more space than is actually required to hold the structure; in
> fact, we allocate enough space for the structure itself, plus the name
> of the module being loaded (following by a null byte). After the
> allocation is done, the name of the module being loaded is strcpy()-ed
> into this extra space, and the result is that 'resource' ends up being a
> properly null-terminated string. This is all done in load_dynamic_module().
> 
> > In writing my own code examples to understand, I found this along with
> > ast_module -> entry -> next to be most troublesome. Nowhere in the code,
> > do I find were ->next is set to null, thus preventing AST_LIST_TRAVERSE
> > from accessing random memory space. In my code, I always segFaulted on
> > the first iteration over the list (containing 1 entry) because the for
> > loop tried to access a ->next that didn?t exist because it wasn?t set to
> > NULL.

this problem reminds me something i was seeing with gcc 2.95

http://lists.digium.com/pipermail/asterisk-dev/2007-October/030276.html

and related to a compiler bug with struct initializers after
zero-sized arrays.

The above url includes some test code to detect the bug in gcc 2.95.
Can you try it with your compiler and see if the problem is the same ?

(i completely forgot the details, but because i know i cannot trust
my memory i make a point of always posting to some public mailing
list a full summary of things that may be of interest and I know i
will forget... )

	cheers
	luigi


> When the 'struct ast_module' is allocated in loader.c
> (load_dynamic_module()), that is done using ast_calloc(), which ensures
> that all bytes of the allocated memory are set to zero. On all platforms
> that Asterisk is expected to work on, NULL is an all-zeroes pointer
> value, so this is explicit initialization of the pointer to NULL.
> 
> > So I change the behavior of AST_LIST_INSERT_TAIL to, upon !head->first
> > to set the .next = NULL. While this worked, this caused a strange
> > behavior in the value of resource[0] being truncated or just not set
> > correctly.
> 
> I do not understand how that could occur; the 'next' pointer and the
> 'resource' character array do not occupy the same memory space.
> 
> > So I was stuck. Not setting .next to NULL allowed resource[] to maintain
> > its values but seg?d on any traversing of the list. Setting .next to
> > NULL allowed for traversing of the list but put garbled data into the
> > values of resource[].
> > 
> >  
> > 
> > My only fix was to change resource[0] to char *resource and do an
> > ast_calloc on strlen(resource_in) right before the strcpy in
> > load_dynamic_module().
> > 
> >  
> > 
> > I am now able to have .next = NULL which keeps my traversals sane and
> > preserves my values of ?resource?.
> 
> That should not have been necessary; I would suggest adding a log
> statement to load_dynamic_module(), right after the ast_calloc(),
> printing out the addresses of resource_being_loaded->resource and
> resource_being_loaded->entry->next... something like this:
> 
> ast_log(LOG_DEBUG, "resource: %p -- next: %p\n",
> resource_being_loaded->resource, &resource_being_loaded->entry->next);
> 
> -- 
> Kevin P. Fleming
> Digium, Inc. | Director of Software Technologies
> 445 Jan Davis Drive NW - Huntsville, AL 35806 - USA
> skype: kpfleming | jabber: kpfleming at digium.com
> Check us out at www.digium.com & www.asterisk.org
> 
> 
> _______________________________________________
> --Bandwidth and Colocation Provided by http://www.api-digital.com--
> 
> AstriCon 2009 - October 13 - 15 Phoenix, Arizona
> Register Now: http://www.astricon.net
> 
> asterisk-dev mailing list
> To UNSUBSCRIBE or update options visit:
>    http://lists.digium.com/mailman/listinfo/asterisk-dev



More information about the asterisk-dev mailing list