Changeset d8ec87b4 in rtems


Ignore:
Timestamp:
Apr 2, 2007, 2:33:59 PM (13 years ago)
Author:
Joel Sherrill <joel.sherrill@…>
Branches:
4.10, 4.11, 4.8, 4.9, master
Children:
d4f8287
Parents:
26292d3
Message:

2007-04-02 Joel Sherrill <joel@…>

  • libmisc/stackchk/check.c: Add code to check validity of frame pointer in addition to the pattern area being overwritten. Also do some cleanup.
Location:
cpukit
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • cpukit/ChangeLog

    r26292d3 rd8ec87b4  
     12007-04-02      Joel Sherrill <joel@OARcorp.com>
     2
     3        * libmisc/stackchk/check.c: Add code to check validity of frame pointer
     4        in addition to the pattern area being overwritten. Also do some
     5        cleanup.
     6
    172007-03-31      Ralf Corsépius <ralf.corsepius@rtems.org>
    28
  • cpukit/libmisc/stackchk/check.c

    r26292d3 rd8ec87b4  
    77 *         extension routines for that direction.
    88 *
    9  *  COPYRIGHT (c) 1989-2006.
     9 *  COPYRIGHT (c) 1989-2007.
    1010 *  On-Line Applications Research Corporation (OAR).
    1111 *
     
    3838
    3939#include <assert.h>
    40 #include <stdio.h>
    4140#include <string.h>
    4241#include <stdlib.h>
    4342
     43#include <rtems/bspIo.h>
    4444#include <rtems/stackchk.h>
    4545#include "internal.h"
    46 
    47 /*
    48  *  This variable contains the name of the task which "blew" the stack.
    49  *  It is NULL if the system is all right.
    50  */
    51 
    52 Thread_Control *Stack_check_Blown_task;
    5346
    5447/*
     
    7770
    7871/*
     72 * Helper function to report if the actual stack pointer is in range.
     73 *
     74 * NOTE: This uses a GCC specific method.
     75 */
     76
     77static inline boolean Stack_check_Frame_pointer_in_range(
     78  Stack_Control *the_stack
     79)
     80{
     81  void *sp = __builtin_frame_address(0);
     82
     83  #if defined(__GNUC__)
     84    if ( sp < the_stack->area ) {
     85      printk( "Stack Pointer Too Low!\n" );
     86      return FALSE;
     87    }
     88    if ( sp > (the_stack->area + the_stack->size) ) {
     89      printk( "Stack Pointer Too High!\n" );
     90      return FALSE;
     91    }
     92  #endif
     93  return TRUE;
     94}
     95
     96/*
    7997 *  Where the pattern goes in the stack area is dependent upon
    8098 *  whether the stack grow to the high or low area of the memory.
    8199 *
    82100 */
    83 
    84101#if ( CPU_STACK_GROWS_UP == TRUE )
    85102
     
    96113#else
    97114
     115
    98116#define Stack_check_Get_pattern_area( _the_stack ) \
    99117  ((Stack_check_Control *) ((char *)(_the_stack)->area + HEAP_OVERHEAD))
     
    142160void rtems_stack_checker_initialize( void )
    143161{
    144 #if 0
    145   rtems_status_code    status;
    146   Objects_Id           id_ignored;
    147 #endif
    148162  uint32_t            *p;
    149 #if 0
    150   uint32_t             i;
    151   uint32_t             api_index;
    152   Thread_Control      *the_thread;
    153   Objects_Information *information;
    154 #endif
    155163
    156164  if (stack_check_initialized)
    157       return;
     165    return;
    158166
    159167  /*
     
    172180  };
    173181
    174 #if 0
    175   status = rtems_extension_create(
    176     rtems_build_name( 'S', 'T', 'C', 'K' ),
    177     &Stack_check_Extension_table,
    178     &id_ignored
    179   );
    180   assert ( status == RTEMS_SUCCESSFUL );
    181 #endif
    182 
    183   Stack_check_Blown_task = 0;
    184 
    185182  /*
    186183   * If installed by a task, that task will not get setup properly
     
    189186   * So pretend here that we actually ran create and begin extensions.
    190187   */
    191 
    192   /* XXX
    193    *
    194    *  Technically this has not been done for any task created before this
    195    *  happened.  So just run through them and fix the situation.
    196    */
    197 #if 0
    198   if (_Thread_Executing) {
    199       rtems_stack_checker_create_extension(
    200         _Thread_Executing,
    201         _Thread_Executing
    202       );
    203   }
    204 #endif
    205 
    206 #if 0
    207   for ( api_index = 1;
    208         api_index <= OBJECTS_APIS_LAST ;
    209         api_index++ ) {
    210     if ( !_Objects_Information_table[ api_index ] )
    211       continue;
    212     information = _Objects_Information_table[ api_index ][ 1 ];
    213     if ( information ) {
    214       for ( i=1 ; i <= information->maximum ; i++ ) {
    215         the_thread = (Thread_Control *)information->local_table[ i ];
    216         rtems_stack_checker_create_extension( the_thread, the_thread );
    217       }
    218     }
    219   }
    220 #endif
    221188
    222189  /*
     
    296263 *  so that interrupt handlers can use this too.
    297264 *
    298  *  Caller must have set the Stack_check_Blown_task.
    299  *
    300265 *  NOTE: The system is in a questionable state... we may not get
    301266 *        the following message out.
    302267 */
    303268
    304 void Stack_check_report_blown_task(void)
    305 {
    306     Stack_Control *stack;
    307     Thread_Control *running;
    308 
    309     running = Stack_check_Blown_task;
    310     stack = &running->Start.Initial_stack;
    311 
    312     fprintf(
    313         stderr,
     269void Stack_check_report_blown_task(
     270  Thread_Control *running,
     271  boolean         pattern_ok
     272)
     273{
     274    Stack_Control *stack = &running->Start.Initial_stack;
     275
     276    printk(
    314277        "BLOWN STACK!!! Offending task(%p): id=0x%08" PRIx32
    315278             "; name=0x%08" PRIx32,
     
    318281        (uint32_t) running->Object.name
    319282    );
    320     fflush(stderr);
    321283
    322284    if (rtems_configuration_get_user_multiprocessing_table())
    323         fprintf(
    324           stderr,
    325           "; node=%" PRId32 "\n",
     285        printk(
     286          "; node=%d\n",
    326287          rtems_configuration_get_user_multiprocessing_table()->node
    327288       );
    328289    else
    329         fprintf(stderr, "\n");
    330     fflush(stderr);
    331 
    332     fprintf(
    333         stderr,
    334         "  stack covers range %p - %p" PRIx32 " (%" PRId32 " bytes)\n",
     290        printk( "\n");
     291
     292    printk(
     293        "  stack covers range %p - %p (%d bytes)\n",
    335294        stack->area,
    336295        stack->area + stack->size - 1,
    337296        stack->size);
    338     fflush(stderr);
    339 
    340     fprintf(
    341         stderr,
    342         "  Damaged pattern begins at 0x%08lx and is %ld bytes long\n",
    343         (unsigned long) Stack_check_Get_pattern_area(stack),
    344         (long) PATTERN_SIZE_BYTES);
    345     fflush(stderr);
    346 
    347     rtems_fatal_error_occurred( (uint32_t  ) "STACK BLOWN" );
     297
     298    if ( !pattern_ok ) {
     299      printk(
     300          "  Damaged pattern begins at 0x%08lx and is %ld bytes long\n",
     301          (unsigned long) Stack_check_Get_pattern_area(stack),
     302          (long) PATTERN_SIZE_BYTES);
     303    }
     304
     305    rtems_fatal_error_occurred( (uint32_t) "STACK BLOWN" );
    348306}
    349307
     
    358316)
    359317{
    360   void *pattern;
    361   if ( running->Object.id == 0 )        /* skip system tasks */
    362     return;
    363   pattern = (void *)
    364     Stack_check_Get_pattern_area(&running->Start.Initial_stack)->pattern;
    365 
    366   if (0 != memcmp( pattern,
    367             (void *) Stack_check_Pattern.pattern, PATTERN_SIZE_BYTES)) {
    368       Stack_check_Blown_task = running;
    369       Stack_check_report_blown_task();
     318  Stack_Control *the_stack = &running->Start.Initial_stack;
     319  void          *pattern;
     320  boolean        sp_ok;
     321  boolean        pattern_ok = TRUE;
     322
     323  pattern = (void *) Stack_check_Get_pattern_area(the_stack)->pattern;
     324
     325
     326  /*
     327   *  Check for an out of bounds stack pointer and then an overwrite
     328   */
     329
     330  sp_ok = Stack_check_Frame_pointer_in_range( the_stack );
     331  pattern_ok = (!memcmp( pattern,
     332            (void *) Stack_check_Pattern.pattern, PATTERN_SIZE_BYTES));
     333
     334  if ( !sp_ok || !pattern_ok ) {
     335    Stack_check_report_blown_task( running, pattern_ok );
    370336  }
    371337}
     
    463429      name = (char *) the_thread->Object.name;
    464430    } else {
    465       u32_name = (uint32_t )the_thread->Object.name;
     431      u32_name = (uint32_t) the_thread->Object.name;
    466432      name[ 0 ] = (u32_name >> 24) & 0xff;
    467433      name[ 1 ] = (u32_name >> 16) & 0xff;
     
    479445  }
    480446
    481   fprintf(stdout, "0x%08" PRIx32 "  %4s  %p - %p"
    482              "   %8" PRId32 "   %8" PRId32 "\n",
     447  printk("0x%08" PRIx32 "  %4s  %p - %p   %8" PRId32 "   %8" PRId32 "\n",
    483448          the_thread ? the_thread->Object.id : ~0,
    484449          name,
     
    515480void rtems_stack_checker_report_usage( void )
    516481{
    517   uint32_t             i;
    518   uint32_t             api_index;
    519   Thread_Control      *the_thread;
    520   uint32_t             hit_running = 0;
    521   Objects_Information *information;
    522 
    523482  if (stack_check_initialized == 0)
    524483      return;
    525484
    526   fprintf(stdout,"Stack usage by thread\n");
    527   fprintf(stdout,
     485  printk("Stack usage by thread\n");
     486  printk(
    528487    "    ID      NAME       LOW        HIGH     AVAILABLE      USED\n"
    529488  );
    530489
    531   for ( api_index = 1 ;
    532         api_index <= OBJECTS_APIS_LAST ;
    533         api_index++ ) {
    534     if ( !_Objects_Information_table[ api_index ] )
    535       continue;
    536     information = _Objects_Information_table[ api_index ][ 1 ];
    537     if ( information ) {
    538       for ( i=1 ; i <= information->maximum ; i++ ) {
    539         the_thread = (Thread_Control *)information->local_table[ i ];
    540         Stack_check_Dump_threads_usage( the_thread );
    541         if ( the_thread == _Thread_Executing )
    542           hit_running = 1;
    543       }
    544     }
    545   }
    546 
    547   if ( !hit_running )
    548     Stack_check_Dump_threads_usage( _Thread_Executing );
     490  /* iterate over all threads and dump the usage */
     491  rtems_iterate_over_all_threads( Stack_check_Dump_threads_usage );
    549492
    550493  /* dump interrupt stack info if any */
Note: See TracChangeset for help on using the changeset viewer.