source: rtems-docs/c-user/stack_bounds_checker.rst @ 12dccfe

5
Last change on this file since 12dccfe was 12dccfe, checked in by Sebastian Huber <sebastian.huber@…>, on 01/09/19 at 15:14:05

Remove superfluous "All rights reserved."

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