source: rtems-docs/c_user/stack_bounds_checker.rst @ 0d86b71

4.115
Last change on this file since 0d86b71 was 0d86b71, checked in by Chris Johns <chrisj@…>, on 02/18/16 at 04:29:28

Clean up.

  • Property mode set to 100644
File size: 7.0 KB
Line 
1.. COMMENT: COPYRIGHT (c) 1988-2008.
2.. COMMENT: On-Line Applications Research Corporation (OAR).
3.. COMMENT: All rights reserved.
4
5Stack Bounds Checker
6####################
7
8.. index:: stack
9
10Introduction
11============
12
13The stack bounds checker is an RTEMS support component that determines if a
14task has overrun its run-time stack.  The routines provided by the stack bounds
15checker manager are:
16
17- rtems_stack_checker_is_blown_ - Has the Current Task Blown its Stack
18
19- rtems_stack_checker_report_usage_ - Report Task Stack Usage
20
21Background
22==========
23
24Task Stack
25----------
26
27Each task in a system has a fixed size stack associated with it.  This stack is
28allocated when the task is created.  As the task executes, the stack is used to
29contain parameters, return addresses, saved registers, and local variables.
30The amount of stack space required by a task is dependent on the exact set of
31routines used.  The peak stack usage reflects the worst case of subroutine
32pushing information on the stack.  For example, if a subroutine allocates a
33local buffer of 1024 bytes, then this data must be accounted for in the stack
34of every task that invokes that routine.
35
36Recursive routines make calculating peak stack usage difficult, if not
37impossible.  Each call to the recursive routine consumes *n* bytes of stack
38space.  If the routine recursives 1000 times, then ``1000 * n`` bytes of
39stack space are required.
40
41Execution
42---------
43
44The stack bounds checker operates as a set of task extensions.  At task
45creation time, the task's stack is filled with a pattern to indicate the stack
46is unused.  As the task executes, it will overwrite this pattern in memory.  At
47each task switch, the stack bounds checker's task switch extension is executed.
48This extension checks that:
49
50- the last ``n`` bytes of the task's stack have not been overwritten.  If this
51  pattern has been damaged, it indicates that at some point since this task was
52  context switch to the CPU, it has used too much stack space.
53
54- the current stack pointer of the task is not within the address range
55  allocated for use as the task's stack.
56
57If either of these conditions is detected, then a blown stack error is reported
58using the ``printk`` routine.
59
60The number of bytes checked for an overwrite is processor family dependent.
61The minimum stack frame per subroutine call varies widely between processor
62families.  On CISC families like the Motorola MC68xxx and Intel ix86, all that
63is needed is a return address.  On more complex RISC processors, the minimum
64stack frame per subroutine call may include space to save a significant number
65of registers.
66
67Another processor dependent feature that must be taken into account by the
68stack bounds checker is the direction that the stack grows.  On some processor
69families, the stack grows up or to higher addresses as the task executes.  On
70other families, it grows down to lower addresses.  The stack bounds checker
71implementation uses the stack description definitions provided by every RTEMS
72port to get for this information.
73
74Operations
75==========
76
77Initializing the Stack Bounds Checker
78-------------------------------------
79
80The stack checker is initialized automatically when its task create extension
81runs for the first time.
82
83The application must include the stack bounds checker extension set in its set
84of Initial Extensions.  This set of extensions is defined as
85``STACK_CHECKER_EXTENSION``.  If using ``<rtems/confdefs.h>`` for Configuration
86Table generation, then all that is necessary is to define the macro
87``CONFIGURE_STACK_CHECKER_ENABLED`` before including ``<rtems/confdefs.h>`` as
88shown below:
89
90.. code:: c
91
92    #define CONFIGURE_STACK_CHECKER_ENABLED
93    ...
94    #include <rtems/confdefs.h>
95
96Checking for Blown Task Stack
97-----------------------------
98
99The application may check whether the stack pointer of currently executing task
100is within proper bounds at any time by calling the
101``rtems_stack_checker_is_blown`` method.  This method return ``FALSE`` if the
102task is operating within its stack bounds and has not damaged its pattern area.
103
104Reporting Task Stack Usage
105--------------------------
106
107The application may dynamically report the stack usage for every task in the
108system by calling the ``rtems_stack_checker_report_usage`` routine.  This
109routine prints a table with the peak usage and stack size of every task in the
110system.  The following is an example of the report generated:
111
112.. code:: c
113
114    ID      NAME       LOW        HIGH     AVAILABLE      USED
115    0x04010001  IDLE  0x003e8a60  0x003e9667       2952        200
116    0x08010002  TA1   0x003e5750  0x003e7b57       9096       1168
117    0x08010003  TA2   0x003e31c8  0x003e55cf       9096       1168
118    0x08010004  TA3   0x003e0c40  0x003e3047       9096       1104
119    0xffffffff  INTR  0x003ecfc0  0x003effbf      12160        128
120
121Notice the last line.  The task id is ``0xffffffff`` and its name is ``INTR``.
122This is not actually a task, it is the interrupt stack.
123
124When a Task Overflows the Stack
125-------------------------------
126
127When the stack bounds checker determines that a stack overflow has occurred, it
128will attempt to print a message using ``printk`` identifying the task and then
129shut the system down.  If the stack overflow has caused corruption, then it is
130possible that the message cannot be printed.
131
132The following is an example of the output generated:
133
134.. code:: c
135
136    BLOWN STACK!!! Offending task(0x3eb360): id=0x08010002; name=0x54413120
137    stack covers range 0x003e5750 - 0x003e7b57 (9224 bytes)
138    Damaged pattern begins at 0x003e5758 and is 128 bytes long
139
140The above includes the task id and a pointer to the task control block as well
141as enough information so one can look at the task's stack and see what was
142happening.
143
144Routines
145========
146
147This section details the stack bounds checker's routines.  A subsection is
148dedicated to each of routines and describes the calling sequence, related
149constants, usage, and status codes.
150
151.. COMMENT: rtems_stack_checker_is_blown
152
153.. _rtems_stack_checker_is_blown:
154
155STACK_CHECKER_IS_BLOWN - Has Current Task Blown Its Stack
156---------------------------------------------------------
157
158**CALLING SEQUENCE:**
159
160.. code:: c
161
162    bool rtems_stack_checker_is_blown( void );
163
164**STATUS CODES:**
165
166.. list-table::
167 :class: rtems-table
168
169 * - ``TRUE``
170   - Stack is operating within its stack limits
171 * - ``FALSE``
172   - Current stack pointer is outside allocated area
173
174**DESCRIPTION:**
175
176This method is used to determine if the current stack pointer of the currently
177executing task is within bounds.
178
179**NOTES:**
180
181This method checks the current stack pointer against the high and low addresses
182of the stack memory allocated when the task was created and it looks for damage
183to the high water mark pattern for the worst case usage of the task being
184called.
185
186.. _rtems_stack_checker_report_usage:
187
188STACK_CHECKER_REPORT_USAGE - Report Task Stack Usage
189----------------------------------------------------
190
191**CALLING SEQUENCE:**
192
193.. code:: c
194
195    void rtems_stack_checker_report_usage( void );
196
197**STATUS CODES:**
198
199NONE
200
201**DESCRIPTION:**
202
203This routine prints a table with the peak stack usage and stack space
204allocation of every task in the system.
205
206**NOTES:**
207
208NONE
Note: See TracBrowser for help on using the repository browser.