1
0
mirror of https://github.com/adtools/clib2.git synced 2026-05-02 10:16:27 +00:00

If alloca() would end up returning a NULL pointer, it now invokes the default alloca trap function, which calls abort(). You can override this, if you need to.

This commit is contained in:
obarthel
2023-09-08 16:03:47 +02:00
parent fc8051f724
commit 7ceeb4f8ed

View File

@@ -69,11 +69,36 @@ struct MemoryContextNode
/****************************************************************************/
/* The default behaviour for alloca() failing is to
* terminate the program rather than let it stumble
* into a NULL-pointer reference.
*/
static void
default_alloca_trap(void)
{
abort();
}
/****************************************************************************/
CLIB_CONSTRUCTOR(alloca_init)
{
ENTER();
__alloca_trap = default_alloca_trap;
NewList((struct List *)&alloca_memory_list);
LEAVE();
}
/****************************************************************************/
CLIB_DESTRUCTOR(alloca_exit)
{
ENTER();
/* Clean this up, too, just to be safe. */
/* This list should remain empty. */
NewList((struct List *)&alloca_memory_list);
LEAVE();
@@ -83,18 +108,18 @@ CLIB_DESTRUCTOR(alloca_exit)
/* Cleans up after all alloca() allocations that have been made so far. */
static void
alloca_cleanup(const char * file,int line)
alloca_cleanup(const char * file, int line)
{
void * stack_pointer = __get_sp();
__memory_lock();
/* Initialize this if it hasn't been taken care of yet. */
if(alloca_memory_list.mlh_Head == NULL)
if (alloca_memory_list.mlh_Head == NULL)
NewList((struct List *)&alloca_memory_list);
/* Is this worth cleaning up? */
if(NOT IsMinListEmpty(&alloca_memory_list))
if (NOT IsListEmpty((struct List *)&alloca_memory_list))
{
struct MemoryContextNode * mcn_prev;
struct MemoryContextNode * mcn;
@@ -106,21 +131,24 @@ alloca_cleanup(const char * file,int line)
we move up from the end to the top of the list, the closer we get
to the allocations made in the context of a stack frame near to
where were currently are. */
for(mcn = (struct MemoryContextNode *)alloca_memory_list.mlh_TailPred ;
mcn->mcn_MinNode.mln_Pred != NULL && mcn->mcn_StackPointer < stack_pointer ;
mcn = mcn_prev)
for (mcn = (struct MemoryContextNode *)alloca_memory_list.mlh_TailPred ;
mcn->mcn_MinNode.mln_Pred != NULL && mcn->mcn_StackPointer < stack_pointer ;
mcn = mcn_prev)
{
mcn_prev = (struct MemoryContextNode *)mcn->mcn_MinNode.mln_Pred;
Remove((struct Node *)mcn);
__free_memory(mcn->mcn_Memory,TRUE,file,line);
__free_memory(mcn,FALSE,file,line);
/* Note: force the memory to be freed because it
has gone out of scope. */
__free_memory(mcn->mcn_Memory, TRUE, file, line);
__free_memory(mcn, FALSE, file, line);
}
/* Drop the cleanup callback if there's nothing to be cleaned
up any more. */
if(IsMinListEmpty(&alloca_memory_list))
if (IsListEmpty((struct List *)&alloca_memory_list))
__alloca_cleanup = NULL;
}
@@ -130,7 +158,7 @@ alloca_cleanup(const char * file,int line)
/****************************************************************************/
__static void *
__alloca(size_t size,const char * file,int line)
__alloca(size_t size, const char * file, int line)
{
void * stack_pointer = __get_sp();
struct MemoryContextNode * mcn;
@@ -138,27 +166,23 @@ __alloca(size_t size,const char * file,int line)
__memory_lock();
/* Initialize this if it hasn't been taken care of yet. */
if(alloca_memory_list.mlh_Head == NULL)
NewList((struct List *)&alloca_memory_list);
__alloca_cleanup = alloca_cleanup;
(*__alloca_cleanup)(file,line);
(*__alloca_cleanup)(file, line);
mcn = __allocate_memory(sizeof(*mcn),FALSE,file,line);
if(mcn == NULL)
mcn = __allocate_memory(sizeof(*mcn), FALSE, file, line);
if (mcn == NULL)
{
SHOWMSG("not enough memory");
goto out;
}
/* Allocate memory which cannot be run through realloc() or free(). */
mcn->mcn_Memory = __allocate_memory(size,TRUE,file,line);
if(mcn->mcn_Memory == NULL)
mcn->mcn_Memory = __allocate_memory(size, TRUE, file, line);
if (mcn->mcn_Memory == NULL)
{
SHOWMSG("not enough memory");
__free(mcn,file,line);
__free(mcn, file, line);
goto out;
}
@@ -166,7 +190,7 @@ __alloca(size_t size,const char * file,int line)
assert( alloca_memory_list.mlh_Head != NULL );
AddTail((struct List *)&alloca_memory_list,(struct Node *)mcn);
AddTail((struct List *)&alloca_memory_list, (struct Node *)mcn);
result = mcn->mcn_Memory;
@@ -176,10 +200,14 @@ __alloca(size_t size,const char * file,int line)
/* If we are about to return NULL and a trap function is
provided, call it rather than returning NULL. */
if(result == NULL && __alloca_trap != NULL)
(*__alloca_trap)();
if (result == NULL && __alloca_trap != NULL)
{
__alloca_cleanup = NULL;
return(result);
(*__alloca_trap)();
}
return result;
}
/****************************************************************************/
@@ -191,5 +219,5 @@ alloca(size_t size)
result = __alloca(size,NULL,0);
return(result);
return result;
}