source: rtems-docs/c_user/stack_bounds_checker.rst @ 01a36ee

4.115
Last change on this file since 01a36ee was 489740f, checked in by Chris Johns <chrisj@…>, on 05/20/16 at 02:47:09

Set SPDX License Identifier in each source file.

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