source: rtems/cpukit/score/src/heapwalk.c @ 55d7626

4.104.114.84.95
Last change on this file since 55d7626 was 55d7626, checked in by Joel Sherrill <joel.sherrill@…>, on 07/11/07 at 20:56:10

2007-07-11 Joel Sherrill <joel.sherrill@…>

  • libcsupport/src/malloc.c: Clean up Malloc debug code.
  • score/include/rtems/score/heap.h: Spacing.
  • score/inline/rtems/score/thread.inl:
  • score/src/heapfree.c. Clean up and add explicit check of the address being freed actually being in the heap.
  • score/src/heapwalk.c: Switch to printk and do not call abort.
  • Property mode set to 100644
File size: 4.5 KB
Line 
1/*
2 *  Heap Handler
3 *
4 *  COPYRIGHT (c) 1989-2007.
5 *  On-Line Applications Research Corporation (OAR).
6 *
7 *  The license and distribution terms for this file may be
8 *  found in the file LICENSE in this distribution or at
9 *  http://www.rtems.com/license/LICENSE.
10 *
11 *  $Id$
12 */
13
14#if HAVE_CONFIG_H
15#include "config.h"
16#endif
17
18#include <stdlib.h> /* abort */
19
20#include <rtems/system.h>
21#include <rtems/score/sysstate.h>
22#include <rtems/score/heap.h>
23#include <rtems/score/interr.h>
24#include <rtems/bspIo.h>
25
26/*PAGE
27 *
28 *  _Heap_Walk
29 *
30 *  This kernel routine walks the heap and verifies its correctness.
31 *
32 *  Input parameters:
33 *    the_heap  - pointer to heap header
34 *    source    - a numeric indicator of the invoker of this routine
35 *    do_dump   - when TRUE print the information
36 *
37 *  Output parameters: NONE
38 */
39
40#if !defined(RTEMS_HEAP_DEBUG)
41
42boolean _Heap_Walk(
43  Heap_Control  *the_heap,
44  int            source,
45  boolean        do_dump
46)
47{
48  return TRUE;
49}
50
51#else /* defined(RTEMS_HEAP_DEBUG) */
52
53#include <stdio.h>
54
55boolean _Heap_Walk(
56  Heap_Control  *the_heap,
57  int            source,
58  boolean        do_dump
59)
60{
61  Heap_Block *the_block = the_heap->start;
62  Heap_Block *const end = the_heap->final;
63  Heap_Block *const tail = _Heap_Tail(the_heap);
64  int error = 0;
65  int passes = 0;
66
67  do_dump = FALSE;
68  /*
69   * We don't want to allow walking the heap until we have
70   * transferred control to the user task so we watch the
71   * system state.
72   */
73
74/*
75  if ( !_System_state_Is_up( _System_state_Get() ) )
76    return TRUE;
77*/
78
79  if (source < 0)
80    source = the_heap->stats.instance;
81
82  if (do_dump == TRUE)
83    printk("\nPASS: %d start %p final %p first %p last %p begin %p end %p\n",
84      source, the_block, end,
85      _Heap_First(the_heap), _Heap_Last(the_heap),
86      the_heap->begin, the_heap->end);
87
88  /*
89   * Handle the 1st block
90   */
91
92  if (!_Heap_Is_prev_used(the_block)) {
93    printk("PASS: %d !HEAP_PREV_USED flag of 1st block isn't set\n", source);
94    error = 1;
95  }
96
97  if (the_block->prev_size != the_heap->page_size) {
98    printk("PASS: %d !prev_size of 1st block isn't page_size\n", source);
99    error = 1;
100  }
101
102  while ( the_block < end ) {
103    uint32_t const the_size = _Heap_Block_size(the_block);
104    Heap_Block *const next_block = _Heap_Block_at(the_block, the_size);
105    boolean prev_used = _Heap_Is_prev_used(the_block);
106
107    if (do_dump) {
108      printk("PASS: %d block %p size %d(%c)",
109        source, the_block, the_size, (prev_used ? 'U' : 'F'));
110      if (prev_used)
111        printk(" prev_size %d", the_block->prev_size);
112      else
113        printk(" (prev_size) %d", the_block->prev_size);
114    }
115
116    if (!_Heap_Is_block_in(the_heap, next_block)) {
117      if (do_dump) printk("\n");
118      printk("PASS: %d !block %p is out of heap\n", source, next_block);
119      error = 1;
120      break;
121    }
122
123    if (!_Heap_Is_prev_used(next_block)) {
124      if (do_dump)
125        printk( " prev %p next %p", the_block->prev, the_block->next);
126      if (_Heap_Block_size(the_block) != next_block->prev_size) {
127        if (do_dump) printk("\n");
128        printk("PASS: %d !front and back sizes don't match", source);
129        error = 1;
130      }
131      if (!prev_used) {
132        if (do_dump || error) printk("\n");
133        printk("PASS: %d !two consecutive blocks are free", source);
134        error = 1;
135      }
136
137      { /* Check if 'the_block' is in the free block list */
138        Heap_Block* block = _Heap_First(the_heap);
139        while(block != the_block && block != tail)
140          block = block->next;
141        if(block != the_block) {
142          if (do_dump || error) printk("\n");
143          printk("PASS: %d !the_block not in the free list", source);
144          error = 1;
145        }
146      }
147
148    }
149    if (do_dump || error) printk("\n");
150
151    if (the_size < the_heap->min_block_size) {
152      printk("PASS: %d !block size is too small\n", source);
153      error = 1;
154      break;
155    }
156    if (!_Heap_Is_aligned( the_size, the_heap->page_size)) {
157      printk("PASS: %d !block size is misaligned\n", source);
158      error = 1;
159    }
160
161    if (++passes > (do_dump ? 10 : 0) && error)
162      break;
163
164    the_block = next_block;
165  }
166
167  if (the_block != end) {
168    printk("PASS: %d !last block address isn't equal to 'final'\n", source);
169    error = 1;
170  }
171
172  if (_Heap_Block_size(the_block) != the_heap->page_size) {
173    printk("PASS: %d !last block's size isn't page_size\n", source);
174    error = 1;
175  }
176
177  if(do_dump && error)
178    _Internal_error_Occurred( INTERNAL_ERROR_CORE, TRUE, 0xffff0000 );
179
180  return error;
181
182}
183#endif  /* defined(RTEMS_HEAP_DEBUG) */
Note: See TracBrowser for help on using the repository browser.