source: rtems-docs/c-user/fatal_error.rst @ dee158c

5
Last change on this file since dee158c was dee158c, checked in by Sebastian Huber <sebastian.huber@…>, on 10/31/19 at 12:29:41

c-user: Document RTEMS_FATAL_SOURCE_HEAP

Close #3806.

  • Property mode set to 100644
File size: 21.8 KB
Line 
1.. SPDX-License-Identifier: CC-BY-SA-4.0
2
3.. Copyright (C) 1988, 2008 On-Line Applications Research Corporation (OAR)
4
5.. index:: fatal errors
6
7.. _fatal_error_manager:
8
9Fatal Error Manager
10*******************
11
12Introduction
13============
14
15The fatal error manager processes all fatal or irrecoverable errors and other
16sources of system termination (for example after :c:func:`exit()`).  Fatal
17errors are identified by the (fatal source, error code) pair.  The directives
18provided by the fatal error manager are:
19
20- rtems_fatal_ - Invoke the fatal error handler
21
22- rtems_panic_ - Print a message and invoke the fatal error handler
23
24- rtems_shutdown_executive_ - Shutdown RTEMS
25
26- rtems_exception_frame_print_ - Print the CPU exception frame
27
28- rtems_fatal_source_text_ - Return the fatal source text
29
30- rtems_internal_error_text_ - Return the error code text
31
32- rtems_fatal_error_occurred_ - Invoke the fatal error handler (deprecated)
33
34Background
35==========
36
37.. index:: fatal error detection
38.. index:: fatal error processing
39.. index:: fatal error user extension
40
41Overview
42--------
43
44The fatal error manager is called upon detection of an irrecoverable error
45condition by either RTEMS or the application software.  Fatal errors are also
46used in case it is difficult or impossible to return an error condition by
47other means, e.g. a return value of a directive call.  Fatal errors can be
48detected from various sources, for example
49
50- the executive (RTEMS),
51- support libraries,
52- user system code, and
53- user application code.
54
55RTEMS automatically invokes the fatal error manager upon detection of an error
56it considers to be fatal.  Similarly, the user should invoke the fatal error
57manager upon detection of a fatal error.
58
59Each static or dynamic user extension set may include a fatal error handler.
60The fatal error handler in the static extension set can be used to provide
61access to debuggers and monitors which may be present on the target hardware.
62If any user-supplied fatal error handlers are installed, the fatal error
63manager will invoke them.  Usually, the board support package provides a fatal
64error extension which resets the board.  If no user handlers are configured or
65if all the user handler return control to the fatal error manager, then the
66RTEMS default fatal error handler is invoked.  If the default fatal error
67handler is invoked, then the system state is marked as failed.
68
69Although the precise behavior of the default fatal error handler is processor
70specific, in general, it will disable all maskable interrupts, place the error
71code in a known processor dependent place (generally either on the stack or in
72a register), and halt the processor.  The precise actions of the RTEMS fatal
73error are discussed in the Default Fatal Error Processing chapter of the
74Applications Supplement document for a specific target processor.
75
76Fatal Sources
77-------------
78
79The following fatal sources are defined for RTEMS via the
80:c:type:`rtems_fatal_source` enumeration.  Each symbolic name has the
81corresponding numeric fatal source in parenthesis.
82
83INTERNAL_ERROR_CORE (0)
84    Errors of the core operating system.  See :ref:`internal_errors`.
85
86INTERNAL_ERROR_RTEMS_API (1)
87    Errors of the Classic API.
88
89INTERNAL_ERROR_POSIX_API (2)
90    Errors of the POSIX API.
91
92RTEMS_FATAL_SOURCE_BDBUF (3)
93    Fatal source for the block device cache.  See
94    :c:type:`rtems_bdbuf_fatal_code`.
95
96RTEMS_FATAL_SOURCE_APPLICATION (4)
97    Fatal source for application-specific errors.  The fatal code is
98    application-specific.
99
100RTEMS_FATAL_SOURCE_EXIT (5)
101    Fatal source of :c:func:`exit()`.  The fatal code is the :c:func:`exit()`
102    status code.
103
104RTEMS_FATAL_SOURCE_BSP (6)
105    Fatal source for BSP errors.  The fatal codes are defined in
106    :file:`<bsp/fatal.h>`.  Examples are interrupt and exception
107    initialization.  See :c:type:`bsp_fatal_code` and :c:func:`bsp_fatal()`.
108
109RTEMS_FATAL_SOURCE_ASSERT (7)
110    Fatal source of :c:macro:`assert()`.  The fatal code is the pointer value
111    of the assert context.  See :c:type:`rtems_assert_context`.
112
113RTEMS_FATAL_SOURCE_STACK_CHECKER (8)
114    Fatal source of the stack checker.  The fatal code is the object name of
115    the executing task.
116
117RTEMS_FATAL_SOURCE_EXCEPTION (9)
118    Fatal source of the exceptions.  The fatal code is the pointer value of the
119    exception frame pointer.  See :c:type:`rtems_exception_frame` and
120    :ref:`rtems_exception_frame_print`.
121
122RTEMS_FATAL_SOURCE_SMP (10)
123    Fatal source of SMP domain.  See :c:type:`SMP_Fatal_code`.
124
125RTEMS_FATAL_SOURCE_PANIC (11)
126    Fatal source of :c:func:`rtems_panic`, see :ref:`rtems_panic`.
127
128RTEMS_FATAL_SOURCE_INVALID_HEAP_FREE (12)
129    Fatal source for invalid C program heap frees via :c:func:`free`.  The
130    fatal code is the bad pointer.
131
132RTEMS_FATAL_SOURCE_HEAP (13)
133    Fatal source for heap errors.  The fatal code is the address to a heap error
134    context.  See :c:type:`Heap_Error_context`.
135
136.. _internal_errors:
137
138Internal Error Codes
139--------------------
140
141The following error codes are defined for the :c:data:`INTERNAL_ERROR_CORE`
142fatal source.  Each symbolic name has the corresponding numeric error code in
143parenthesis.
144
145INTERNAL_ERROR_TOO_LITTLE_WORKSPACE (2)
146    There is not enough memory for the workspace.  This fatal error may occur
147    during system initialization.  It is an application configuration error.
148
149INTERNAL_ERROR_WORKSPACE_ALLOCATION (3)
150    An allocation from the workspace failed.  This fatal error may occur during
151    system initialization.  It is an application configuration error.
152
153INTERNAL_ERROR_INTERRUPT_STACK_TOO_SMALL (4)
154    The configured interrupt stack size is too small.  This fatal error may
155    occur during system initialization.  It is an application configuration
156    error.
157
158INTERNAL_ERROR_THREAD_EXITTED (5)
159    A non-POSIX thread entry function returned.  This is an API usage error.
160
161    An example code to provoke this fatal error is:
162
163    .. code-block:: c
164
165        rtems_task task( rtems_task_argument arg )
166        {
167          /* Classic API tasks must not return */
168        }
169
170        void create_bad_task( void )
171        {
172          rtems_status_code sc;
173          rtems_id          task_id;
174
175          sc = rtems_task_create(
176            rtems_build_name('T', 'A', 'S', 'K'),
177            1,
178            RTEMS_MINIMUM_STACK_SIZE,
179            RTEMS_DEFAULT_MODES,
180            RTEMS_DEFAULT_ATTRIBUTES,
181            &task_id
182          );
183          assert( sc == RTEMS_SUCCESSFUL );
184
185          sc = rtems_task_start( task_id, task, 0 );
186          assert( sc == RTEMS_SUCCESSFUL );
187        }
188
189INTERNAL_ERROR_INCONSISTENT_MP_INFORMATION (6)
190    This fatal error can only occur on MPCI configurations.  The MPCI nodes or
191    global objects configuration is inconsistent.  This fatal error may occur
192    during system initialization.  It is an application configuration error.
193
194INTERNAL_ERROR_INVALID_NODE (7)
195    This fatal error can only occur on MPCI configurations.  The own MPCI node
196    number is invalid.  This fatal error may occur during system
197    initialization.  It is an application configuration error.
198
199INTERNAL_ERROR_NO_MPCI (8)
200    This fatal error can only occur on MPCI configurations.  There is no MPCI
201    configuration table.  This fatal error may occur during system
202    initialization.  It is an application configuration error.
203
204INTERNAL_ERROR_BAD_PACKET (9)
205    This fatal error can only occur on MPCI configurations.  The MPCI server
206    thread received a bad packet.
207
208INTERNAL_ERROR_OUT_OF_PACKETS (10)
209    This fatal error can only occur on MPCI configurations.  The MPCI packet
210    pool is empty.  It is an application configuration error.
211
212INTERNAL_ERROR_OUT_OF_GLOBAL_OBJECTS (11)
213    This fatal error can only occur on MPCI configurations.  The MPCI global
214    objects pool is empty.  It is an application configuration error.
215
216INTERNAL_ERROR_OUT_OF_PROXIES (12)
217    This fatal error can only occur on MPCI configurations.  The MPCI thread
218    proxy pool is empty.  It is an application configuration error.
219
220INTERNAL_ERROR_INVALID_GLOBAL_ID (13)
221    This fatal error can only occur on MPCI configurations.  The system cannot
222    find the global object for a specific object identifier.  In case this
223    happens, then this is probably an operating system bug.
224
225INTERNAL_ERROR_BAD_STACK_HOOK (14)
226    The stack allocator hook or stack free hook is NULL.  This fatal error may
227    occur during system initialization.  It is an application configuration
228    error.
229
230INTERNAL_ERROR_UNLIMITED_AND_MAXIMUM_IS_0 (19)
231    An object class is configured to use the unlimited objects option, however,
232    the count of objects for each extension is zero.  This fatal error may
233    occur during system initialization.  It is an application configuration
234    error.
235
236INTERNAL_ERROR_NO_MEMORY_FOR_HEAP (23)
237    There is not enough memory for the C program heap.  This fatal error may
238    occur during system initialization.  It is an application configuration
239    error.
240
241INTERNAL_ERROR_CPU_ISR_INSTALL_VECTOR (24)
242    The use of :c:func:`_CPU_ISR_install_vector()` is illegal on this system.
243
244INTERNAL_ERROR_RESOURCE_IN_USE (25)
245    This fatal error can only occur on debug configurations.  It happens in
246    case a thread which owns mutexes is deleted.  Mutexes owned by a deleted
247    thread are in an inconsistent state.
248
249INTERNAL_ERROR_RTEMS_INIT_TASK_ENTRY_IS_NULL (26)
250    An RTEMS initialization task entry function is NULL.  This fatal error may
251    occur during system initialization.  It is an application configuration
252    error.
253
254INTERNAL_ERROR_THREAD_QUEUE_DEADLOCK (28)
255    A deadlock was detected during a thread queue enqueue operation.
256
257INTERNAL_ERROR_THREAD_QUEUE_ENQUEUE_STICKY_FROM_BAD_STATE (29)
258    This fatal error can only happen in SMP configurations.  It is not allowed
259    to obtain MrsP semaphores in a context with thread dispatching disabled,
260    for example interrupt context.
261
262    An example code to provoke this fatal error is:
263
264    .. code-block:: c
265
266        rtems_timer_service_routine bad( rtems_id timer_id, void *arg )
267        {
268          rtems_id *sem_id;
269
270          sem_id = arg;
271
272          rtems_semaphore_obtain( *sem_id, RTEMS_WAIT, RTEMS_NO_TIMEOUT );
273          assert( 0 );
274        }
275
276        rtems_task fire_bad_timer( rtems_task_argument arg )
277        {
278          rtems_status_code sc;
279          rtems_id          sem_id;
280          rtems_id          timer_id;
281
282          sc = rtems_semaphore_create(
283            rtems_build_name('M', 'R', 'S', 'P'),
284            1,
285            RTEMS_MULTIPROCESSOR_RESOURCE_SHARING
286              | RTEMS_BINARY_SEMAPHORE,
287            1,
288            &sem_id
289          );
290          assert( sc == RTEMS_SUCCESSFUL );
291
292          sc = rtems_timer_create(
293            rtems_build_name( 'E', 'V', 'I', 'L' ),
294            &timer_id
295          );
296          assert( sc == RTEMS_SUCCESSFUL );
297
298          sc = rtems_semaphore_obtain( sem_id, RTEMS_WAIT, RTEMS_NO_TIMEOUT );
299          assert( sc == RTEMS_SUCCESSFUL );
300
301          sc = rtems_timer_fire_after( timer_id, 1, bad, &sem_id );
302          assert( sc == RTEMS_SUCCESSFUL );
303
304          rtems_task_wake_after( 2 );
305          assert( 0 );
306        }
307
308INTERNAL_ERROR_BAD_THREAD_DISPATCH_DISABLE_LEVEL (30)
309    It is illegal to call blocking operating system services with thread
310    dispatching disabled, for example in interrupt context.
311
312    An example code to provoke this fatal error is:
313
314    .. code-block:: c
315
316        void bad( rtems_id id, void *arg )
317        {
318          rtems_task_wake_after( RTEMS_YIELD_PROCESSOR );
319          assert( 0 );
320        }
321
322        void fire_bad_timer( void )
323        {
324          rtems_status_code sc;
325          rtems_id          id;
326
327          sc = rtems_timer_create(
328            rtems_build_name( 'E', 'V', 'I', 'L' ),
329            &id
330          );
331          assert( sc == RTEMS_SUCCESSFUL );
332
333          sc = rtems_timer_fire_after( id, 1, bad, NULL );
334          assert( sc == RTEMS_SUCCESSFUL );
335
336          rtems_task_wake_after( 2 );
337          assert( 0 );
338        }
339
340INTERNAL_ERROR_BAD_THREAD_DISPATCH_ENVIRONMENT (31)
341    In SMP configurations, it is a fatal error to call blocking operating
342    system with interrupts disabled, since this prevents delivery of
343    inter-processor interrupts.  This could lead to executing threads which are
344    not allowed to execute resulting in undefined system behaviour.
345
346    Some CPU ports, for example the ARM Cortex-M port, have a similar problem,
347    since the interrupt state is not a part of the thread context.
348
349    This fatal error is detected in the operating system core function
350    :c:func:`_Thread_Do_dispatch()` responsible to carry out a thread dispatch.
351
352    An example code to provoke this fatal error is:
353
354    .. code-block:: c
355
356        void bad( void )
357        {
358          rtems_interrupt_level level;
359
360          rtems_interrupt_local_disable( level );
361          rtems_task_suspend( RTEMS_SELF );
362          rtems_interrupt_local_enable( level  );
363        }
364
365INTERNAL_ERROR_RTEMS_INIT_TASK_CREATE_FAILED (32)
366    Creation of an RTEMS initialization task failed.  This fatal error may
367    occur during system initialization.  It is an application configuration
368    error.
369
370INTERNAL_ERROR_POSIX_INIT_THREAD_CREATE_FAILED (33)
371    Creation of a POSIX initialization thread failed.  This fatal error may
372    occur during system initialization.  It is an application configuration
373    error.
374
375INTERNAL_ERROR_LIBIO_USER_ENV_KEY_CREATE_FAILED (34)
376    Creation of the IO library user environment POSIX key failed.  This fatal
377    error may occur during system initialization.  It is an application
378    configuration error.
379
380INTERNAL_ERROR_LIBIO_SEM_CREATE_FAILED (35)
381    Creation of the IO library semaphore failed.  This fatal error may occur
382    during system initialization.  It is an application configuration error.
383
384INTERNAL_ERROR_LIBIO_STDOUT_FD_OPEN_FAILED (36)
385    Open of the standard output file descriptor failed or resulted in an
386    unexpected file descriptor number.  This fatal error may occur during
387    system initialization.  It is an application configuration error.
388
389INTERNAL_ERROR_LIBIO_STDERR_FD_OPEN_FAILED (37)
390    Open of the standard error file descriptor failed or resulted in an
391    unexpected file descriptor number.  This fatal error may occur during
392    system initialization.  It is an application configuration error.
393
394INTERNAL_ERROR_ILLEGAL_USE_OF_FLOATING_POINT_UNIT (38)
395    The floating point unit was used illegally, for example in interrupt
396    context on some architectures.
397
398INTERNAL_ERROR_ARC4RANDOM_GETENTROPY_FAIL (39)
399    A :c:func:`getentropy` system call failed in one of the `ARC4RANDOM(3)
400    <https://man.openbsd.org/arc4random.3>`_ functions.  This fatal error can
401    only be fixed with a different implementation of :c:func:`getentropy`.
402
403INTERNAL_ERROR_NO_MEMORY_FOR_PER_CPU_DATA (40)
404    This fatal error may happen during workspace initialization.  There is not
405    enough memory available to populate the per-CPU data areas, see
406    `<rtems/score/percpudata.h> <https://git.rtems.org/rtems/tree/cpukit/include/rtems/score/percpudata.h>`_.
407
408Operations
409==========
410
411.. index:: _Terminate
412
413.. _Terminate:
414
415Announcing a Fatal Error
416------------------------
417
418The :c:func:`_Terminate()` internal error handler is invoked when the
419application or the executive itself determines that a fatal error has occurred
420or a final system state is reached (for example after :c:func:`rtems_fatal()`
421or :c:func:`exit()`).
422
423The first action of the internal error handler is to call the fatal extension of
424the user extensions.  For the initial extensions the following conditions are
425required
426
427- a valid stack pointer and enough stack space,
428
429- a valid code memory, and
430
431- valid read-only data.
432
433For the initial extensions the read-write data (including .bss segment) is not
434required on single processor configurations.  In SMP configurations, however,
435the read-write data must be initialized since this function must determine the
436state of the other processors and request them to shut-down if necessary.
437
438Non-initial extensions require in addition valid read-write data.  The board
439support package (BSP) may install an initial extension that performs a system
440reset.  In this case the non-initial extensions will be not called.
441
442The fatal extensions are called with three parameters:
443
444- the fatal source,
445
446- a legacy parameter which is always false, and
447
448- an error code with a fatal source dependent content.
449
450Once all fatal extensions executed, the error information will be stored to
451:c:data:`_Internal_errors_What_happened` and the system state is set to
452:c:macro:`SYSTEM_STATE_TERMINATED`.
453
454The final step is to call the CPU port specific :c:func:`_CPU_Fatal_halt()`.
455
456Directives
457==========
458
459This section details the fatal error manager's directives.  A subsection is
460dedicated to each of this manager's directives and describes the calling
461sequence, related constants, usage, and status codes.
462
463.. raw:: latex
464
465   \clearpage
466
467.. index:: announce fatal error
468.. index:: fatal error, announce
469.. index:: rtems_fatal
470
471.. _rtems_fatal:
472
473FATAL - Invoke the fatal error handler
474--------------------------------------
475
476CALLING SEQUENCE:
477    .. code-block:: c
478
479        void rtems_fatal(
480          rtems_fatal_source fatal_source,
481          rtems_fatal_code   error_code
482        ) RTEMS_NO_RETURN;
483
484DIRECTIVE STATUS CODES:
485    NONE - This function will not return to the caller.
486
487DESCRIPTION:
488    This directive terminates the system.
489
490NOTE:
491    Registered :c:func:`atexit()` or :c:func:`on_exit()` handlers are not
492    called.  Use :c:func:`exit()` in case these handlers should be invoked.
493
494.. raw:: latex
495
496   \clearpage
497
498.. index:: panic
499.. index:: rtems_panic
500
501.. _rtems_panic:
502
503PANIC - Print a message and invoke the fatal error handler
504----------------------------------------------------------
505
506CALLING SEQUENCE:
507    .. code-block:: c
508
509        void rtems_panic(
510          const char *fmt,
511          ...
512        ) RTEMS_NO_RETURN RTEMS_PRINTFLIKE( 1, 2 );
513
514DIRECTIVE STATUS CODES:
515    NONE - This function will not return to the caller.
516
517DESCRIPTION:
518    This directive prints a message via :c:func:`printk` specified by the
519    format and optional parameters and then terminates the system with the
520    :c:macro:`RTEMS_FATAL_SOURCE_PANIC` fatal source.  The fatal code is set to
521    the format string address.
522
523NOTE:
524    Registered :c:func:`atexit()` or :c:func:`on_exit()` handlers are not
525    called.  Use :c:func:`exit()` in case these handlers should be invoked.
526
527.. raw:: latex
528
529   \clearpage
530
531.. index:: shutdown RTEMS
532.. index:: rtems_shutdown_executive
533
534.. _rtems_shutdown_executive:
535
536SHUTDOWN_EXECUTIVE - Shutdown RTEMS
537-----------------------------------
538
539CALLING SEQUENCE:
540    .. code-block:: c
541
542        void rtems_shutdown_executive(
543            uint32_t result
544        );
545
546DIRECTIVE STATUS CODES:
547    NONE - This function will not return to the caller.
548
549DESCRIPTION:
550    This directive is called when the application wishes to shutdown RTEMS.
551    The system is terminated with a fatal source of ``RTEMS_FATAL_SOURCE_EXIT``
552    and the specified ``result`` code.
553
554NOTES:
555    This directive *must* be the last RTEMS directive invoked by an application
556    and it *does not return* to the caller.
557
558    This directive may be called any time.
559
560.. raw:: latex
561
562   \clearpage
563
564.. index:: exception frame
565.. index:: rtems_exception_frame_print
566
567.. _rtems_exception_frame_print:
568
569EXCEPTION_FRAME_PRINT - Prints the exception frame
570--------------------------------------------------
571
572CALLING SEQUENCE:
573    .. code-block:: c
574
575        void rtems_exception_frame_print(
576            const rtems_exception_frame *frame
577        );
578
579DIRECTIVE STATUS CODES:
580    NONE
581
582DESCRIPTION:
583    Prints the exception frame via ``printk()``.
584
585.. raw:: latex
586
587   \clearpage
588
589.. index:: fatal error
590.. index:: rtems_fatal_source_text
591
592.. _rtems_fatal_source_text:
593
594FATAL_SOURCE_TEXT - Returns a text for a fatal source
595-----------------------------------------------------
596
597CALLING SEQUENCE:
598    .. code-block:: c
599
600        const char *rtems_fatal_source_text(
601            rtems_fatal_source source
602        );
603
604DIRECTIVE STATUS CODES:
605    The fatal source text or "?" in case the passed fatal source is invalid.
606
607DESCRIPTION:
608    Returns a text for a fatal source.  The text for fatal source is the
609    enumerator constant.
610
611.. raw:: latex
612
613   \clearpage
614
615.. index:: fatal error
616.. index:: rtems_internal_error_text
617
618.. _rtems_internal_error_text:
619
620INTERNAL_ERROR_TEXT - Returns a text for an internal error code
621---------------------------------------------------------------
622
623CALLING SEQUENCE:
624    .. code-block:: c
625
626        const char *rtems_internal_error_text(
627            rtems_fatal_code error
628        );
629
630DIRECTIVE STATUS CODES:
631    The error code text or "?" in case the passed error code is invalid.
632
633DESCRIPTION:
634    Returns a text for an internal error code.  The text for each internal
635    error code is the enumerator constant.
636
637.. raw:: latex
638
639   \clearpage
640
641.. index:: announce fatal error
642.. index:: fatal error, announce
643.. index:: rtems_fatal_error_occurred
644
645.. _rtems_fatal_error_occurred:
646
647FATAL_ERROR_OCCURRED - Invoke the fatal error handler (deprecated)
648------------------------------------------------------------------
649
650CALLING SEQUENCE:
651    .. code-block:: c
652
653        void rtems_fatal_error_occurred(
654            uint32_t  the_error
655        ) RTEMS_NO_RETURN;
656
657DIRECTIVE STATUS CODES:
658    NONE - This function will not return to the caller.
659
660DESCRIPTION:
661    This directive processes fatal errors.  If the FATAL error extension is
662    defined in the configuration table, then the user-defined error extension
663    is called.  If configured and the provided FATAL error extension returns,
664    then the RTEMS default error handler is invoked.  This directive can be
665    invoked by RTEMS or by the user's application code including initialization
666    tasks, other tasks, and ISRs.
667
668NOTES:
669    This directive is deprecated and should not be used in new code.
670
671    This directive supports local operations only.
672
673    Unless the user-defined error extension takes special actions such as
674    restarting the calling task, this directive WILL NOT RETURN to the caller.
675
676    The user-defined extension for this directive may wish to initiate a global
677    shutdown.
Note: See TracBrowser for help on using the repository browser.