rtems-5: Improve heap fatal error information

Update #3806.
This commit is contained in:
sebastian.huber
2019-11-05 07:29:00 +01:00
committed by Sebastian Huber
parent f9648baf65
commit 3859cd63af
9 changed files with 97 additions and 15 deletions
+63 -1
View File
@@ -134,6 +134,62 @@ typedef struct Heap_Control Heap_Control;
typedef struct Heap_Block Heap_Block;
/**
* @brief The heap error reason.
*
* @see _Heap_Protection_block_error().
*/
typedef enum {
/**
* @brief There is an unexpected value in the heap block protector area.
*/
HEAP_ERROR_BROKEN_PROTECTOR,
/**
* @brief There is an unexpected value in the free pattern of a free heap
* block.
*/
HEAP_ERROR_FREE_PATTERN,
/**
* @brief There is was an attempt to free the same block twice.
*/
HEAP_ERROR_DOUBLE_FREE,
/**
* @brief The next block of a supposed to be used block does not indicate that
* the block is used.
*/
HEAP_ERROR_BAD_USED_BLOCK,
/**
* @brief A supposed to be free block is not inside the heap memory area.
*/
HEAP_ERROR_BAD_FREE_BLOCK
} Heap_Error_reason;
/**
* @brief Context of a heap error.
*
* @see _Heap_Protection_block_error().
*/
typedef struct {
/**
* @brief The heap of the block.
*/
Heap_Control *heap;
/**
* @brief The heap block causing the error.
*/
Heap_Block *block;
/**
* @brief The heap error reason.
*/
Heap_Error_reason reason;
} Heap_Error_context;
#ifndef HEAP_PROTECTION
#define HEAP_PROTECTION_HEADER_SIZE 0
#else
@@ -153,10 +209,16 @@ typedef struct Heap_Block Heap_Block;
Heap_Block *block
);
typedef void (*_Heap_Protection_error_handler)(
Heap_Control *heap,
Heap_Block *block,
Heap_Error_reason reason
);
typedef struct {
_Heap_Protection_handler block_initialize;
_Heap_Protection_handler block_check;
_Heap_Protection_handler block_error;
_Heap_Protection_error_handler block_error;
void *handler_data;
Heap_Block *first_delayed_free_block;
Heap_Block *last_delayed_free_block;
+4 -3
View File
@@ -379,7 +379,7 @@ Heap_Block *_Heap_Block_allocate(
#ifndef HEAP_PROTECTION
#define _Heap_Protection_block_initialize( heap, block ) ((void) 0)
#define _Heap_Protection_block_check( heap, block ) ((void) 0)
#define _Heap_Protection_block_error( heap, block ) ((void) 0)
#define _Heap_Protection_block_error( heap, block, reason ) ((void) 0)
#define _Heap_Protection_free_all_delayed_blocks( heap ) ((void) 0)
#else
static inline void _Heap_Protection_block_initialize(
@@ -400,10 +400,11 @@ Heap_Block *_Heap_Block_allocate(
static inline void _Heap_Protection_block_error(
Heap_Control *heap,
Heap_Block *block
Heap_Block *block,
Heap_Error_reason reason
)
{
(*heap->Protection.block_error)( heap, block );
(*heap->Protection.block_error)( heap, block, reason );
}
static inline void _Heap_Protection_free_all_delayed_blocks( Heap_Control *heap )
+7
View File
@@ -139,6 +139,13 @@ typedef enum {
*/
RTEMS_FATAL_SOURCE_INVALID_HEAP_FREE = 12,
/**
* @brief Fatal source for heap errors.
*
* The fatal code is the address to a heap error context (Heap_Error_context).
*/
RTEMS_FATAL_SOURCE_HEAP = 13,
/**
* @brief The last available fatal source.
*
+3 -2
View File
@@ -7,7 +7,7 @@
*/
/*
* Copyright (c) 2013, 2018 embedded brains GmbH. All rights reserved.
* Copyright (c) 2013, 2019 embedded brains GmbH. All rights reserved.
*
* embedded brains GmbH
* Dornierstr. 4
@@ -39,7 +39,8 @@ static const char *const fatal_source_text[] = {
"RTEMS_FATAL_SOURCE_EXCEPTION",
"RTEMS_FATAL_SOURCE_SMP",
"RTEMS_FATAL_SOURCE_PANIC",
"RTEMS_FATAL_SOURCE_INVALID_HEAP_FREE"
"RTEMS_FATAL_SOURCE_INVALID_HEAP_FREE",
"RTEMS_FATAL_SOURCE_HEAP"
};
const char *rtems_fatal_source_text( rtems_fatal_source source )
+10 -4
View File
@@ -147,17 +147,23 @@
|| block->Protection_end.protector [0] != HEAP_END_PROTECTOR_0
|| block->Protection_end.protector [1] != HEAP_END_PROTECTOR_1
) {
_Heap_Protection_block_error( heap, block );
_Heap_Protection_block_error( heap, block, HEAP_ERROR_BROKEN_PROTECTOR );
}
}
static void _Heap_Protection_block_error_default(
Heap_Control *heap,
Heap_Block *block
Heap_Block *block,
Heap_Error_reason reason
)
{
/* FIXME */
_Terminate( INTERNAL_ERROR_CORE, 0xdeadbeef );
Heap_Error_context error_context = {
.heap = heap,
.block = block,
.reason = reason
};
_Terminate( RTEMS_FATAL_SOURCE_HEAP, (uintptr_t) &error_context );
}
#endif
+5 -1
View File
@@ -45,7 +45,11 @@
Heap_Block *next_block_to_free;
if ( !_Heap_Is_block_in_heap( heap, block_to_free ) ) {
_Heap_Protection_block_error( heap, block_to_free );
_Heap_Protection_block_error(
heap,
block_to_free,
HEAP_ERROR_BAD_FREE_BLOCK
);
}
next_block_to_free =
+3 -3
View File
@@ -69,7 +69,7 @@
for ( current = pattern_begin; current != pattern_end; ++current ) {
if ( *current != HEAP_FREE_PATTERN ) {
_Heap_Protection_block_error( heap, block );
_Heap_Protection_block_error( heap, block, HEAP_ERROR_FREE_PATTERN );
break;
}
}
@@ -89,7 +89,7 @@
} else if ( next == HEAP_PROTECTION_OBOLUS ) {
_Heap_Protection_check_free_block( heap, block );
} else {
_Heap_Protection_block_error( heap, block );
_Heap_Protection_block_error( heap, block, HEAP_ERROR_DOUBLE_FREE );
}
return do_free;
@@ -134,7 +134,7 @@ bool _Heap_Free( Heap_Control *heap, void *alloc_begin_ptr )
_Heap_Protection_block_check( heap, next_block );
if ( !_Heap_Is_prev_used( next_block ) ) {
_Heap_Protection_block_error( heap, block );
_Heap_Protection_block_error( heap, block, HEAP_ERROR_BAD_USED_BLOCK );
return false;
}
+1 -1
View File
@@ -53,7 +53,7 @@ static void test_fatal_source_text(void)
puts( text );
} while ( text != text_last );
rtems_test_assert( source - 3 == RTEMS_FATAL_SOURCE_INVALID_HEAP_FREE );
rtems_test_assert( source - 3 == RTEMS_FATAL_SOURCE_HEAP );
}
static void test_status_text(void)
@@ -59,6 +59,7 @@ RTEMS_FATAL_SOURCE_EXCEPTION
RTEMS_FATAL_SOURCE_SMP
RTEMS_FATAL_SOURCE_PANIC
RTEMS_FATAL_SOURCE_INVALID_HEAP_FREE
RTEMS_FATAL_SOURCE_HEAP
?
?
RTEMS_SUCCESSFUL