source: rtems/c/src/lib/libc/error.c @ 85734b3

4.104.114.84.95
Last change on this file since 85734b3 was 85734b3, checked in by Joel Sherrill <joel.sherrill@…>, on Aug 31, 1998 at 10:53:42 PM

Patch from Eric Norum <eric@…>:

I think I figured out why rtems_panic was locking up instead of
shutting down the executive and returning to the code that called
boot_card().

Later on there is code to print some messages on the standard error
stream, a recursive call back to rtems_verror (through rtems_error)
and finally a call to _exit().

I think that the _Thread_Disable_dispatch() is preventing the final
context switch back to the boot_card() code. Does this sound right
to you?

  • Property mode set to 100644
File size: 6.1 KB
Line 
1/*
2 *  report errors and panics to RTEMS' stderr.
3 *  Currently just used by RTEMS monitor.
4 *
5 *  $Id$
6 */
7
8
9/*
10 * These routines provide general purpose error reporting.
11 * rtems_error reports an error to stderr and allows use of
12 * printf style formatting.  A newline is appended to all messages.
13 *
14 * error_flag can be specified as any of the following:
15 *
16 *      RTEMS_ERROR_ERRNO       -- include errno text in output
17 *      RTEMS_ERROR_PANIC       -- halts local system after output
18 *      RTEMS_ERROR_ABORT       -- abort after output
19 *
20 * It can also include a rtems_status value which can be OR'd
21 * with the above flags. *
22 *
23 * EXAMPLE
24 *      #include <rtems.h>
25 *      #include <rtems/error.h>
26 *      rtems_error(0, "stray interrupt %d", intr);
27 *
28 * EXAMPLE
29 *        if ((status = rtems_task_create(...)) != RTEMS_SUCCCESSFUL)
30 *        {
31 *            rtems_error(status | RTEMS_ERROR_ABORT,
32 *                        "could not create task");
33 *        }
34 *
35 * EXAMPLE
36 *        if ((fd = open(pathname, O_RDNLY)) < 0)
37 *        {
38 *            rtems_error(RTEMS_ERROR_ERRNO, "open of '%s' failed", pathname);
39 *            goto failed;
40 *        }
41 */
42
43#define __RTEMS_VIOLATE_KERNEL_VISIBILITY__
44#include <rtems.h>
45
46#include "error.h"
47#include <rtems/assoc.h>
48
49#include <stdio.h>
50#include <stdarg.h>
51#include <errno.h>
52#include <stdlib.h>
53#include <string.h>
54#include <unistd.h>             /* _exit() */
55
56/* bug in hpux <errno.h>: no prototypes unless you are C++ */
57#ifdef hpux9
58char *strerror(int);
59#endif
60
61extern char *rtems_progname;
62int          rtems_panic_in_progress;
63
64rtems_assoc_t rtems_status_assoc[] = {
65    { "successful completion",              RTEMS_SUCCESSFUL, },
66    { "returned from a thread",             RTEMS_TASK_EXITTED, },
67    { "multiprocessing not configured",     RTEMS_MP_NOT_CONFIGURED, },
68    { "invalid object name",                RTEMS_INVALID_NAME, },
69    { "invalid object id",                  RTEMS_INVALID_ID, },
70    { "too many",                           RTEMS_TOO_MANY, },
71    { "timed out waiting",                  RTEMS_TIMEOUT, },
72    { "object deleted while waiting",       RTEMS_OBJECT_WAS_DELETED, },
73    { "specified size was invalid",         RTEMS_INVALID_SIZE, },
74    { "address specified is invalid",       RTEMS_INVALID_ADDRESS, },
75    { "number was invalid",                 RTEMS_INVALID_NUMBER, },
76    { "item has not been initialized",      RTEMS_NOT_DEFINED, },
77    { "resources still outstanding",        RTEMS_RESOURCE_IN_USE, },
78    { "request not satisfied",              RTEMS_UNSATISFIED, },
79    { "thread is in wrong state",           RTEMS_INCORRECT_STATE, },
80    { "thread already in state",            RTEMS_ALREADY_SUSPENDED, },
81    { "illegal on calling thread",          RTEMS_ILLEGAL_ON_SELF, },
82    { "illegal for remote object",          RTEMS_ILLEGAL_ON_REMOTE_OBJECT, },
83    { "called from wrong environment",      RTEMS_CALLED_FROM_ISR, },
84    { "invalid thread priority",            RTEMS_INVALID_PRIORITY, },
85    { "invalid date/time",                  RTEMS_INVALID_CLOCK, },
86    { "invalid node id",                    RTEMS_INVALID_NODE, },
87    { "directive not configured",           RTEMS_NOT_CONFIGURED, },
88    { "not owner of resource",              RTEMS_NOT_OWNER_OF_RESOURCE , },
89    { "directive not implemented",          RTEMS_NOT_IMPLEMENTED, },
90    { "RTEMS inconsistency detected",       RTEMS_INTERNAL_ERROR, },
91    { "could not get enough memory",        RTEMS_NO_MEMORY, },
92    { "internal multiprocessing only",      THREAD_STATUS_PROXY_BLOCKING, },
93    { 0, 0, 0 },
94};
95
96
97const char *
98rtems_status_text(
99    rtems_status_code status
100)
101{
102    return rtems_assoc_name_by_local(rtems_status_assoc, status);
103}
104
105
106static int rtems_verror(
107    unsigned32   error_flag,
108    const char   *printf_format,
109    va_list      arglist
110)
111{
112    int               local_errno = 0;
113    int               chars_written = 0;
114    rtems_status_code status;
115
116    if (error_flag & RTEMS_ERROR_PANIC)
117    {
118        if (rtems_panic_in_progress++)
119            _Thread_Disable_dispatch();       /* disable task switches */
120
121        /* don't aggravate things */
122        if (rtems_panic_in_progress > 2)
123            return 0;
124    }
125
126    (void) fflush(stdout);          /* in case stdout/stderr same */
127
128    status = error_flag & ~RTEMS_ERROR_MASK;
129    if (error_flag & RTEMS_ERROR_ERRNO)     /* include errno? */
130        local_errno = errno;
131
132    if (_System_state_Is_multiprocessing)
133        fprintf(stderr, "[%d] ", _Configuration_MP_table->node);
134   
135    if (rtems_progname && *rtems_progname)
136        chars_written += fprintf(stderr, "%s: ", rtems_progname);
137    chars_written += vfprintf(stderr, printf_format, arglist);
138   
139    if (status)
140        chars_written += fprintf(stderr, " (status: %s)", rtems_status_text(status));
141
142    if (local_errno)
143    {
144      if ((local_errno > 0) && *strerror(local_errno))
145        chars_written += fprintf(stderr, " (errno: %s)", strerror(local_errno));
146      else
147        chars_written += fprintf(stderr, " (unknown errno=%d)", local_errno);
148    }
149   
150    chars_written += fprintf(stderr, "\n");
151
152    (void) fflush(stderr);
153
154    if (error_flag & (RTEMS_ERROR_PANIC | RTEMS_ERROR_ABORT))
155    {
156        if (error_flag & RTEMS_ERROR_PANIC)
157        {
158            rtems_error(0, "fatal error, exiting");
159            _exit(local_errno);
160        }
161        else
162        {
163            rtems_error(0, "fatal error, aborting");
164            abort();
165        }
166    }
167    return chars_written;
168}
169
170
171/*
172 * Report an error.
173 * error_flag is as above; printf_format is a normal
174 * printf(3) format string, with its concommitant arguments.
175 *
176 * Returns the number of characters written.
177 */
178
179int rtems_error(
180    int   error_flag,
181    const char *printf_format,
182    ...
183  )
184{
185    va_list arglist;
186    int chars_written;
187
188    va_start(arglist, printf_format);
189    chars_written = rtems_verror(error_flag, printf_format, arglist);
190    va_end(arglist);
191   
192    return chars_written;
193}
194
195/*
196 * rtems_panic is shorthand for rtems_error(RTEMS_ERROR_PANIC, ...)
197 */
198
199void rtems_panic(
200    const char *printf_format,
201    ...
202  )
203{
204    va_list arglist;
205
206    va_start(arglist, printf_format);
207    (void) rtems_verror(RTEMS_ERROR_PANIC, printf_format, arglist);
208    va_end(arglist);
209}
Note: See TracBrowser for help on using the repository browser.