Behaviour change for double-free'ing a pointer

Ralf Corsepius ralf.corsepius at rtems.org
Fri Dec 21 06:40:11 UTC 2007


On Thu, 2007-12-20 at 17:24 -0800, Kenneth J. Peters wrote:
> >On Thu, Dec 20, 2007 at 01:05:03PM -0600, Joel Sherrill wrote:
> >>  Aaron J. Grier wrote:
> >>
> >>  FWIW [double-free] isn't an RTEMS internal error.  It is a case where
> >>  the user called free with a bad pointer.
> >>
> >>  + Not in the heap
> >>  + already freed
> >>  + not the starting address of a block
> >>
> >>  In all cases, RTEMS does not cause a fatal error when the user makes
> >>  an API call with bad arguments.  If we think "free of bad pointer" is
> >>  a common enough case that it should be a place where a user can plug
> >>  in a handler, then that's OK.
> >>
> >>  >I believe it should be possible and optional for RTEMS to halt at
> >>  >run-time.
> >>
> >>  In this case only or do you have a set of these in mind?
> >
> >I think the existing RTEMS_DEBUG and consistency checks covers the other
> >cases.
> >
> >since I am RAM constrained, having hooks to catch bad malloc/free usage,
> >heap corruption, and stack overflows have been helpful to me in the
> >past.  I'd hate to see them be removed because "failed API calls should
> >not halt the machine."  there are cases where both behaviors are
> >helpful.
> >
> 
> Couldn't a hook be created for the user to provide the "assert" 
> function/macro that RTEMS calls internally

assert's behavior is clearly defined by POSIX:

<cite>
The <assert.h> header shall define the assert() macro. It refers to the
macro NDEBUG which is not defined in the header. If NDEBUG is defined as
a macro name before the inclusion of this header, the assert() macro
shall be defined simply as:

#define assert(ignore)((void) 0)


Otherwise, the macro behaves as described in assert().

The assert() macro shall be redefined according to the current state of
NDEBUG each time <assert.h> is included.

The assert() macro shall be implemented as a macro, not as a function.
If the macro definition is suppressed in order to access an actual
function, the behavior is undefined.
</cite>

>  (ideally with an 
> RTEMS-provided default if the user does not provide one)?
c.f. above.

=> RTEMS must provide the infrastructure to assure the behavior
described above.

It currently defaults to 
#define assert(e)       ((e) ? (void)0 : __assert(__FILE__, __LINE__, #e))

i.e. the default is to map assert() to 
void __assert(const char *, int, const char *);



>  I have seen 
> other systems (for example, the Quantum Platform) where that is the 
> case. Then in theory the user could either compile out all assert 
> calls for efficiency (if you keep the conditional compilation),
This is what is the supposed to be the standardized behavior and is the
purpose of -DNDEBUG.

To put it even stronger: Whatever RTEMS_DEBUG does or want to do, it is
not connected to assert and -DNDEBUG.

>  or 
> provide their own halting assert, or provide a non-halting assert if 
> they had something special to do instead. Don't forget that some 
> systems may not have a "printk" that does anything (poor bastards...)
Given how RTEMS assert() implementation, these systems will have to
provide a custom __assert().

Ralf





More information about the users mailing list