diff options
Diffstat (limited to '')
-rw-r--r-- | c/src/lib/libmisc/stackchk/Makefile.in | 72 | ||||
-rw-r--r-- | c/src/lib/libmisc/stackchk/README | 56 | ||||
-rw-r--r-- | c/src/lib/libmisc/stackchk/check.c | 535 | ||||
-rw-r--r-- | c/src/lib/libmisc/stackchk/internal.h | 96 | ||||
-rw-r--r-- | c/src/lib/libmisc/stackchk/stackchk.h | 83 |
5 files changed, 0 insertions, 842 deletions
diff --git a/c/src/lib/libmisc/stackchk/Makefile.in b/c/src/lib/libmisc/stackchk/Makefile.in deleted file mode 100644 index 80d72807d9..0000000000 --- a/c/src/lib/libmisc/stackchk/Makefile.in +++ /dev/null @@ -1,72 +0,0 @@ -# -# $Id$ -# - -@SET_MAKE@ -srcdir = @srcdir@ -top_srcdir = @top_srcdir@ -top_builddir = .. -subdir = stackchk - -RTEMS_ROOT = @RTEMS_ROOT@ -PROJECT_ROOT = @PROJECT_ROOT@ - -VPATH = @srcdir@ - -LIB = ${ARCH}/libstackchk-tmp.a - -# C source names, if any, go here -- minus the .c -C_PIECES = check -C_FILES = $(C_PIECES:%=%.c) -C_O_FILES = $(C_PIECES:%=${ARCH}/%.o) - -H_FILES = internal.h -INSTALLED_H_FILES = $(srcdir)/stackchk.h - -SRCS = $(C_FILES) $(H_FILES) $(INSTALLED_H_FILES) -OBJS = $(C_O_FILES) - -include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg -include $(RTEMS_ROOT)/make/lib.cfg - -INSTALL_CHANGE = @INSTALL_CHANGE@ -mkinstalldirs = $(SHELL) $(top_srcdir)/@RTEMS_TOPdir@/mkinstalldirs - -INSTALLDIRS = $(PROJECT_INCLUDE)/rtems - -$(INSTALLDIRS): - @$(mkinstalldirs) $(INSTALLDIRS) - -# -# (OPTIONAL) Add local stuff here using += -# - -DEFINES += -CPPFLAGS += -CFLAGS += - -LD_PATHS += -LD_LIBS += -LDFLAGS += - -# -# Add your list of files to delete here. The config files -# already know how to delete some stuff, so you may want -# to just run 'make clean' first to see what gets missed. -# 'make clobber' already includes 'make clean' -# - -CLEAN_ADDITIONS += -CLOBBER_ADDITIONS += - -${LIB}: ${SRCS} preinstall ${OBJS} - $(make-library) - -all: ${ARCH} $(SRCS) $(LIB) - -preinstall: - @$(INSTALL_CHANGE) -m 644 $(INSTALLED_H_FILES) $(PROJECT_INCLUDE)/rtems - -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - cd $(top_builddir) \ - && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status diff --git a/c/src/lib/libmisc/stackchk/README b/c/src/lib/libmisc/stackchk/README deleted file mode 100644 index 0f6e2f2b10..0000000000 --- a/c/src/lib/libmisc/stackchk/README +++ /dev/null @@ -1,56 +0,0 @@ -# -# $Id$ -# - -Introduction -============ - -This directory contains a stack bounds checker. It provides two -primary features: - - + check for stack overflow at each context switch - + provides an educated guess at each task's stack usage - -Enabling -======== - -Add the stack checker extension to the initial user extension set. -If using confdefs.h to build your configuration table, this is -as simple as adding -DSTACK_CHECK_ON to the gcc command line which -compiles the file defining the configuration table. In the RTEMS -test suites and samples, this is always init.c - -Background -========== - -The stack overflow check at context switch works by looking for -a 16 byte pattern at the logical end of the stack to be corrupted. -The "guesser" assumes that the entire stack was prefilled with a known -pattern and assumes that the pattern is still in place if the memory -has not been used as a stack. - -Both of these can be fooled by pushing large holes onto the stack -and not writing to them... or (much more unlikely) writing the -magic patterns into memory. - -This code has not been extensively tested. It is provided as a tool -for RTEMS users to catch the most common mistake in multitasking -systems ... too little stack space. Suggestions and comments are appreciated. - -NOTES: - -1. Stack usage information is questionable on CPUs which push - large holes on stack. - -2. The stack checker has a tendency to generate a fault when - trying to print the helpful diagnostic message. If it comes - out, congratulations. If not, then the variable Stack_check_Blown_task - contains a pointer to the TCB of the offending task. This - is usually enough to go on. - -FUTURE: - -1. Determine how/if gcc will generate stack probe calls and support that. - -2. Get accurate stack usage numbers on i960.. it pushes very large - holes on the stack. diff --git a/c/src/lib/libmisc/stackchk/check.c b/c/src/lib/libmisc/stackchk/check.c deleted file mode 100644 index ac688c2a2e..0000000000 --- a/c/src/lib/libmisc/stackchk/check.c +++ /dev/null @@ -1,535 +0,0 @@ -/* - * Stack Overflow Check User Extension Set - * - * NOTE: This extension set automatically determines at - * initialization time whether the stack for this - * CPU grows up or down and installs the correct - * extension routines for that direction. - * - * COPYRIGHT (c) 1989-1998. - * On-Line Applications Research Corporation (OAR). - * Copyright assigned to U.S. Government, 1994. - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.OARcorp.com/rtems/license.html. - * - * $Id$ - * - */ - -#include <rtems.h> - -/* - * HACK - * the stack dump information should be printed by a "fatal" extension. - * Fatal extensions only get called via rtems_fatal_error_occurred() - * and not when rtems_shutdown_executive() is called. - * I hope/think this is changing so that fatal extensions are renamed - * to "shutdown" extensions. - * When that happens, this #define should be deleted and all the code - * it marks. - */ -#define DONT_USE_FATAL_EXTENSION - - -extern rtems_configuration_table BSP_Configuration; - -#include <assert.h> -#include <stdio.h> -#include <string.h> -#include <stdlib.h> - -#include <rtems/stackchk.h> -#include "internal.h" - -/* - * This variable contains the name of the task which "blew" the stack. - * It is NULL if the system is all right. - */ - -Thread_Control *Stack_check_Blown_task; - -/* - * The extension table for the stack checker. - */ - -rtems_extensions_table Stack_check_Extension_table = { - Stack_check_Create_extension, /* rtems_task_create */ - 0, /* rtems_task_start */ - 0, /* rtems_task_restart */ - 0, /* rtems_task_delete */ - Stack_check_Switch_extension, /* task_switch */ - Stack_check_Begin_extension, /* task_begin */ - 0, /* task_exitted */ -#ifdef DONT_USE_FATAL_EXTENSION - 0, /* fatal */ -#else - Stack_check_Fatal_extension, /* fatal */ -#endif -}; - -/* - * The "magic pattern" used to mark the end of the stack. - */ - -Stack_check_Control Stack_check_Pattern; - -/* - * Where the pattern goes in the stack area is dependent upon - * whether the stack grow to the high or low area of the memory. - * - */ - -#if ( CPU_STACK_GROWS_UP == TRUE ) - -#define Stack_check_Get_pattern_area( _the_stack ) \ - ((Stack_check_Control *) ((char *)(_the_stack)->area + \ - (_the_stack)->size - sizeof( Stack_check_Control ) )) - -#define Stack_check_Calculate_used( _low, _size, _high_water ) \ - ((char *)(_high_water) - (char *)(_low)) - -#define Stack_check_usable_stack_start(_the_stack) \ - ((_the_stack)->area) - -#else - -#define Stack_check_Get_pattern_area( _the_stack ) \ - ((Stack_check_Control *) ((char *)(_the_stack)->area + HEAP_OVERHEAD)) - -#define Stack_check_Calculate_used( _low, _size, _high_water) \ - ( ((char *)(_low) + (_size)) - (char *)(_high_water) ) - -#define Stack_check_usable_stack_start(_the_stack) \ - ((char *)(_the_stack)->area + sizeof(Stack_check_Control)) - -#endif - -#define Stack_check_usable_stack_size(_the_stack) \ - ((_the_stack)->size - sizeof(Stack_check_Control)) - - -/* - * Do we have an interrupt stack? - * XXX it would sure be nice if the interrupt stack were also - * stored in a "stack" structure! - */ - - -Stack_Control stack_check_interrupt_stack; - -/* - * Prototypes necessary for forward references - */ - -void Stack_check_Dump_usage( void ); - -/* - * Fill an entire stack area with BYTE_PATTERN. - * This will be used by a Fatal extension to check for - * amount of actual stack used - */ - -void -stack_check_dope_stack(Stack_Control *stack) -{ - memset(stack->area, BYTE_PATTERN, stack->size); -} - - -/*PAGE - * - * Stack_check_Initialize - */ - -unsigned32 stack_check_initialized = 0; - -void Stack_check_Initialize( void ) -{ -#if 0 - rtems_status_code status; - Objects_Id id_ignored; -#endif - unsigned32 *p; -#if 0 - unsigned32 i; - unsigned32 class_index; - Thread_Control *the_thread; - Objects_Information *information; -#endif - - if (stack_check_initialized) - return; - - /* - * Dope the pattern and fill areas - */ - - for ( p = Stack_check_Pattern.pattern; - p < &Stack_check_Pattern.pattern[PATTERN_SIZE_WORDS]; - p += 4 - ) - { - p[0] = 0xFEEDF00D; /* FEED FOOD to BAD DOG */ - p[1] = 0x0BAD0D06; - p[2] = 0xDEADF00D; /* DEAD FOOD GOOD DOG */ - p[3] = 0x600D0D06; - }; - -#if 0 - status = rtems_extension_create( - rtems_build_name( 'S', 'T', 'C', 'K' ), - &Stack_check_Extension_table, - &id_ignored - ); - assert ( status == RTEMS_SUCCESSFUL ); -#endif - - Stack_check_Blown_task = 0; - - /* - * If installed by a task, that task will not get setup properly - * since it missed out on the create hook. This will cause a - * failure on first switch out of that task. - * So pretend here that we actually ran create and begin extensions. - */ - - /* XXX - * - * Technically this has not been done for any task created before this - * happened. So just run through them and fix the situation. - */ -#if 0 - if (_Thread_Executing) - { - Stack_check_Create_extension(_Thread_Executing, _Thread_Executing); - } -#endif - -#if 0 - for ( class_index = OBJECTS_CLASSES_FIRST ; - class_index <= OBJECTS_CLASSES_LAST ; - class_index++ ) { - information = _Objects_Information_table[ class_index ]; - if ( information && information->is_thread ) { - for ( i=1 ; i <= information->maximum ; i++ ) { - the_thread = (Thread_Control *)information->local_table[ i ]; - Stack_check_Create_extension( the_thread, the_thread ); - } - } - } -#endif - - /* - * If appropriate, setup the interrupt stack for high water testing - * also. - */ - if (_CPU_Interrupt_stack_low && _CPU_Interrupt_stack_high) - { - stack_check_interrupt_stack.area = _CPU_Interrupt_stack_low; - stack_check_interrupt_stack.size = (char *) _CPU_Interrupt_stack_high - - (char *) _CPU_Interrupt_stack_low; - - stack_check_dope_stack(&stack_check_interrupt_stack); - } - -#ifdef DONT_USE_FATAL_EXTENSION -#ifdef RTEMS_DEBUG - /* - * this would normally be called by a fatal extension - * handler, but we don't run fatal extensions unless - * we fatal error. - */ - atexit(Stack_check_Dump_usage); -#endif -#endif - - stack_check_initialized = 1; -} - -/*PAGE - * - * Stack_check_Create_extension - */ - -boolean Stack_check_Create_extension( - Thread_Control *running, - Thread_Control *the_thread -) -{ - if (!stack_check_initialized) - Stack_check_Initialize(); - - if (the_thread /* XXX && (the_thread != _Thread_Executing) */ ) - stack_check_dope_stack(&the_thread->Start.Initial_stack); - - return TRUE; -} - -/*PAGE - * - * Stack_check_Begin_extension - */ - -void Stack_check_Begin_extension( - Thread_Control *the_thread -) -{ - Stack_check_Control *the_pattern; - - if (!stack_check_initialized) - Stack_check_Initialize(); - - if ( the_thread->Object.id == 0 ) /* skip system tasks */ - return; - - the_pattern = Stack_check_Get_pattern_area(&the_thread->Start.Initial_stack); - - *the_pattern = Stack_check_Pattern; -} - -/*PAGE - * - * Stack_check_report_blown_task - * Report a blown stack. Needs to be a separate routine - * so that interrupt handlers can use this too. - * - * Caller must have set the Stack_check_Blown_task. - * - * NOTE: The system is in a questionable state... we may not get - * the following message out. - */ - -void Stack_check_report_blown_task(void) -{ - Stack_Control *stack; - Thread_Control *running; - - running = Stack_check_Blown_task; - stack = &running->Start.Initial_stack; - - fprintf( - stderr, - "BLOWN STACK!!! Offending task(%p): id=0x%08x; name=0x%08x", - running, - running->Object.id, - *(unsigned32 *)running->Object.name - ); - fflush(stderr); - - if (BSP_Configuration.User_multiprocessing_table) - fprintf( - stderr, - "; node=%d\n", - BSP_Configuration.User_multiprocessing_table->node - ); - else - fprintf(stderr, "\n"); - fflush(stderr); - - fprintf( - stderr, - " stack covers range 0x%08x - 0x%08x (%d bytes)\n", - (unsigned32) stack->area, - (unsigned32) stack->area + stack->size - 1, - (unsigned32) stack->size); - fflush(stderr); - - fprintf( - stderr, - " Damaged pattern begins at 0x%08x and is %d bytes long\n", - (unsigned32) Stack_check_Get_pattern_area(stack), PATTERN_SIZE_BYTES); - fflush(stderr); - - rtems_fatal_error_occurred( (unsigned32) "STACK BLOWN" ); -} - -/*PAGE - * - * Stack_check_Switch_extension - */ - -void Stack_check_Switch_extension( - Thread_Control *running, - Thread_Control *heir -) -{ - if ( running->Object.id == 0 ) /* skip system tasks */ - return; - - if (0 != memcmp( (void *) Stack_check_Get_pattern_area( &running->Start.Initial_stack)->pattern, - (void *) Stack_check_Pattern.pattern, - PATTERN_SIZE_BYTES)) - { - Stack_check_Blown_task = running; - Stack_check_report_blown_task(); - } -} - -void *Stack_check_find_high_water_mark( - const void *s, - size_t n -) -{ - const unsigned32 *base, *ebase; - unsigned32 length; - - base = s; - length = n/4; - -#if ( CPU_STACK_GROWS_UP == TRUE ) - /* - * start at higher memory and find first word that does not - * match pattern - */ - - base += length - 1; - for (ebase = s; base > ebase; base--) - if (*base != U32_PATTERN) - return (void *) base; -#else - /* - * start at lower memory and find first word that does not - * match pattern - */ - - base += PATTERN_SIZE_WORDS; - for (ebase = base + length; base < ebase; base++) - if (*base != U32_PATTERN) - return (void *) base; -#endif - - return (void *)0; -} - -/*PAGE - * - * Stack_check_Dump_threads_usage - * Try to print out how much stack was actually used by the task. - * - */ - -void Stack_check_Dump_threads_usage( - Thread_Control *the_thread -) -{ - unsigned32 size, used; - void *low; - void *high_water_mark; - Stack_Control *stack; - unsigned32 u32_name; - char name[5]; - - - if ( !the_thread ) - return; - - /* - * XXX HACK to get to interrupt stack - */ - - if (the_thread == (Thread_Control *) -1) - { - if (stack_check_interrupt_stack.area) - { - stack = &stack_check_interrupt_stack; - the_thread = 0; - } - else - return; - } - else - stack = &the_thread->Start.Initial_stack; - - low = Stack_check_usable_stack_start(stack); - size = Stack_check_usable_stack_size(stack); - - high_water_mark = Stack_check_find_high_water_mark(low, size); - - if ( high_water_mark ) - used = Stack_check_Calculate_used( low, size, high_water_mark ); - else - used = 0; - - if ( the_thread ) - u32_name = *(unsigned32 *)the_thread->Object.name; - else - u32_name = rtems_build_name('I', 'N', 'T', 'R'); - - name[ 0 ] = (u32_name >> 24) & 0xff; - name[ 1 ] = (u32_name >> 16) & 0xff; - name[ 2 ] = (u32_name >> 8) & 0xff; - name[ 3 ] = (u32_name >> 0) & 0xff; - name[ 4 ] = '\0'; - - printf( "0x%08x %4s 0x%08x 0x%08x %8d %8d\n", - the_thread ? the_thread->Object.id : ~0, - name, - (unsigned32) stack->area, - (unsigned32) stack->area + (unsigned32) stack->size - 1, - size, - used - ); -} - -/*PAGE - * - * Stack_check_Fatal_extension - */ - -void Stack_check_Fatal_extension( - Internal_errors_Source source, - boolean is_internal, - unsigned32 status -) -{ -#ifndef DONT_USE_FATAL_EXTENSION - if (status == 0) - Stack_check_Dump_usage(); -#endif -} - - -/*PAGE - * - * Stack_check_Dump_usage - */ - -void Stack_check_Dump_usage( void ) -{ - unsigned32 i; - unsigned32 class_index; - Thread_Control *the_thread; - unsigned32 hit_running = 0; - Objects_Information *information; - - if (stack_check_initialized == 0) - return; - - printf("Stack usage by thread\n"); - printf( - " ID NAME LOW HIGH AVAILABLE USED\n" - ); - - for ( class_index = OBJECTS_CLASSES_FIRST ; - class_index <= OBJECTS_CLASSES_LAST ; - class_index++ ) { - information = _Objects_Information_table[ class_index ]; - if ( information && information->is_thread ) { - for ( i=1 ; i <= information->maximum ; i++ ) { - the_thread = (Thread_Control *)information->local_table[ i ]; - Stack_check_Dump_threads_usage( the_thread ); - if ( the_thread == _Thread_Executing ) - hit_running = 1; - } - } - } - - if ( !hit_running ) - Stack_check_Dump_threads_usage( _Thread_Executing ); - - /* dump interrupt stack info if any */ - Stack_check_Dump_threads_usage((Thread_Control *) -1); -} - diff --git a/c/src/lib/libmisc/stackchk/internal.h b/c/src/lib/libmisc/stackchk/internal.h deleted file mode 100644 index 96d0c3f10a..0000000000 --- a/c/src/lib/libmisc/stackchk/internal.h +++ /dev/null @@ -1,96 +0,0 @@ -/* internal.h - * - * This include file contains internal information - * for the RTEMS stack checker. - * - * COPYRIGHT (c) 1989-1998. - * On-Line Applications Research Corporation (OAR). - * Copyright assigned to U.S. Government, 1994. - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.OARcorp.com/rtems/license.html. - * - * $Id$ - */ - -#ifndef __INTERNAL_STACK_CHECK_h -#define __INTERNAL_STACK_CHECK_h - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * This structure is used to fill in and compare the "end of stack" - * marker pattern. - * pattern area must be a multiple of 4 words. - */ - -#ifdef CPU_STACK_CHECK_SIZE -#define PATTERN_SIZE_WORDS (((CPU_STACK_CHECK_SIZE / 4) + 3) & ~0x3) -#else -#define PATTERN_SIZE_WORDS 4 -#endif - -#define PATTERN_SIZE_BYTES (PATTERN_SIZE_WORDS * 4) - -typedef struct { - unsigned32 pattern[ PATTERN_SIZE_WORDS ]; -} Stack_check_Control; - -/* - * The pattern used to fill the entire stack. - */ - -#define BYTE_PATTERN 0xA5 -#define U32_PATTERN 0xA5A5A5A5 - -/* - * Stack_check_Create_extension - */ - -boolean Stack_check_Create_extension( - Thread_Control *running, - Thread_Control *the_thread -); - -/* - * Stack_check_Begin_extension - */ - -void Stack_check_Begin_extension( - Thread_Control *the_thread -); - -/* - * Stack_check_Switch_extension - */ - -void Stack_check_Switch_extension( - Thread_Control *running, - Thread_Control *heir -); - -/* - * Stack_check_Fatal_extension - */ - -void Stack_check_Fatal_extension( - Internal_errors_Source source, - boolean is_internal, - unsigned32 status -); - -/* - * Stack_check_Dump_usage - */ - -void Stack_check_Dump_usage( void ); - -#ifdef __cplusplus -} -#endif - -#endif -/* end of include file */ diff --git a/c/src/lib/libmisc/stackchk/stackchk.h b/c/src/lib/libmisc/stackchk/stackchk.h deleted file mode 100644 index 1b40da5e0c..0000000000 --- a/c/src/lib/libmisc/stackchk/stackchk.h +++ /dev/null @@ -1,83 +0,0 @@ -/* stackchk.h - * - * This include file contains information necessary to utilize - * and install the stack checker mechanism. - * - * COPYRIGHT (c) 1989-1998. - * On-Line Applications Research Corporation (OAR). - * Copyright assigned to U.S. Government, 1994. - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.OARcorp.com/rtems/license.html. - * - * $Id$ - */ - -#ifndef __STACK_CHECK_h -#define __STACK_CHECK_h - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * Stack_check_Initialize - */ - -void Stack_check_Initialize( void ); - -/* - * Stack_check_Dump_usage - */ - -void Stack_check_Dump_usage( void ); - -/* - * Stack_check_Create_extension - */ - -boolean Stack_check_Create_extension( - Thread_Control *running, - Thread_Control *the_thread -); - -/* - * Stack_check_Begin_extension - */ - -void Stack_check_Begin_extension( - Thread_Control *the_thread -); - -/* - * Stack_check_Switch_extension - */ - -void Stack_check_Switch_extension( - Thread_Control *running, - Thread_Control *heir -); - -/* - * Extension set definition - */ - -#define STACK_CHECKER_EXTENSION \ -{ \ - Stack_check_Create_extension, /* rtems_task_create */ \ - 0, /* rtems_task_start */ \ - 0, /* rtems_task_restart */ \ - 0, /* rtems_task_delete */ \ - Stack_check_Switch_extension, /* task_switch */ \ - Stack_check_Begin_extension, /* task_begin */ \ - 0, /* task_exitted */ \ - 0 /* Stack_check_Fatal_extension */, /* fatal */ \ -} - -#ifdef __cplusplus -} -#endif - -#endif -/* end of include file */ |