source: rtems/cpukit/libcsupport/src/error.c @ 01b0755

4.115
Last change on this file since 01b0755 was 01b0755, checked in by Nick Withers <nick.withers@…>, on 08/14/13 at 07:56:27

Expose rtems_verror()

  • Property mode set to 100644
File size: 4.6 KB
Line 
1/**
2 *  @file
3 *
4 *  @brief Error and Panic Report Support
5 *  @ingroup ErrorPanicSupport
6 */
7
8#if HAVE_CONFIG_H
9#include "config.h"
10#endif
11
12#include <rtems.h>
13#include <rtems/error.h>
14#include <rtems/assoc.h>
15#include <rtems/score/sysstate.h>
16#include <rtems/score/threadimpl.h>
17#include <inttypes.h>
18#include <stdio.h>
19#include <stdarg.h>
20#include <errno.h>
21#include <stdlib.h>
22#include <string.h>
23#include <unistd.h>     /* _exit() */
24
25int          rtems_panic_in_progress;
26
27const rtems_assoc_t rtems_status_assoc[] = {
28  { "successful completion",              RTEMS_SUCCESSFUL, 0 },
29  { "returned from a thread",             RTEMS_TASK_EXITTED, 0 },
30  { "multiprocessing not configured",     RTEMS_MP_NOT_CONFIGURED, 0 },
31  { "invalid object name",                RTEMS_INVALID_NAME, 0 },
32  { "invalid object id",                  RTEMS_INVALID_ID, 0 },
33  { "too many",                           RTEMS_TOO_MANY, 0 },
34  { "timed out waiting",                  RTEMS_TIMEOUT, 0 },
35  { "object deleted while waiting",       RTEMS_OBJECT_WAS_DELETED, 0 },
36  { "specified size was invalid",         RTEMS_INVALID_SIZE, 0 },
37  { "address specified is invalid",       RTEMS_INVALID_ADDRESS, 0 },
38  { "number was invalid",                 RTEMS_INVALID_NUMBER, 0 },
39  { "item has not been initialized",      RTEMS_NOT_DEFINED, 0 },
40  { "resources still outstanding",        RTEMS_RESOURCE_IN_USE, 0 },
41  { "request not satisfied",              RTEMS_UNSATISFIED, 0 },
42  { "thread is in wrong state",           RTEMS_INCORRECT_STATE, 0 },
43  { "thread already in state",            RTEMS_ALREADY_SUSPENDED, 0 },
44  { "illegal on calling thread",          RTEMS_ILLEGAL_ON_SELF, 0 },
45  { "illegal for remote object",          RTEMS_ILLEGAL_ON_REMOTE_OBJECT, 0 },
46  { "called from wrong environment",      RTEMS_CALLED_FROM_ISR, 0 },
47  { "invalid thread priority",            RTEMS_INVALID_PRIORITY, 0 },
48  { "invalid date/time",                  RTEMS_INVALID_CLOCK, 0 },
49  { "invalid node id",                    RTEMS_INVALID_NODE, 0 },
50  { "directive not configured",           RTEMS_NOT_CONFIGURED, 0 },
51  { "not owner of resource",              RTEMS_NOT_OWNER_OF_RESOURCE , 0 },
52  { "directive not implemented",          RTEMS_NOT_IMPLEMENTED, 0 },
53  { "RTEMS inconsistency detected",       RTEMS_INTERNAL_ERROR, 0 },
54  { "could not get enough memory",        RTEMS_NO_MEMORY, 0 },
55  { "driver IO error",                    RTEMS_IO_ERROR, 0 },
56  { "internal multiprocessing only",      THREAD_STATUS_PROXY_BLOCKING, 0 },
57  { 0, 0, 0 },
58};
59
60
61const char *rtems_status_text(
62  rtems_status_code status
63)
64{
65  return rtems_assoc_name_by_local(rtems_status_assoc, status);
66}
67
68
69int rtems_verror(
70  rtems_error_code_t  error_flag,
71  const char         *printf_format,
72  va_list             arglist
73)
74{
75  int               local_errno = 0;
76  int               chars_written = 0;
77  rtems_status_code status;
78
79  if (error_flag & RTEMS_ERROR_PANIC) {
80    if (rtems_panic_in_progress++)
81      _Thread_Disable_dispatch();       /* disable task switches */
82
83    /* don't aggravate things */
84    if (rtems_panic_in_progress > 2)
85      return 0;
86  }
87
88  (void) fflush(stdout);            /* in case stdout/stderr same */
89
90  status = error_flag & ~RTEMS_ERROR_MASK;
91  if (error_flag & RTEMS_ERROR_ERRNO)     /* include errno? */
92    local_errno = errno;
93
94  #if defined(RTEMS_MULTIPROCESSING)
95    if (_System_state_Is_multiprocessing)
96      fprintf(stderr, "[%" PRIu32 "] ", _Configuration_MP_table->node);
97  #endif
98
99  chars_written += vfprintf(stderr, printf_format, arglist);
100
101  if (status)
102    chars_written +=
103      fprintf(stderr, " (status: %s)", rtems_status_text(status));
104
105  if (local_errno) {
106    if ((local_errno > 0) && *strerror(local_errno))
107      chars_written += fprintf(stderr, " (errno: %s)", strerror(local_errno));
108    else
109      chars_written += fprintf(stderr, " (unknown errno=%d)", local_errno);
110  }
111
112  chars_written += fprintf(stderr, "\n");
113
114  (void) fflush(stderr);
115
116  return chars_written;
117}
118
119int rtems_error(
120  rtems_error_code_t error_flag,
121  const char *printf_format,
122  ...
123)
124{
125  va_list arglist;
126  int chars_written;
127
128  va_start(arglist, printf_format);
129  chars_written = rtems_verror(error_flag, printf_format, arglist);
130  va_end(arglist);
131
132  if (error_flag & RTEMS_ERROR_PANIC) {
133    rtems_error(0, "fatal error, exiting");
134    _exit(errno);
135  }
136  if (error_flag & RTEMS_ERROR_ABORT) {
137    rtems_error(0, "fatal error, aborting");
138    abort();
139  }
140
141  return chars_written;
142}
143
144void rtems_panic(
145  const char *printf_format,
146  ...
147)
148{
149  va_list arglist;
150
151  va_start(arglist, printf_format);
152  (void) rtems_verror(RTEMS_ERROR_PANIC, printf_format, arglist);
153  va_end(arglist);
154
155  rtems_error(0, "fatal error, exiting");
156  _exit(errno);
157}
Note: See TracBrowser for help on using the repository browser.