00001
00002
00003
00004
00005
00006
00007 #include "wvcrash.h"
00008
00009 #include <errno.h>
00010 #include <stdio.h>
00011 #include <stdlib.h>
00012 #include <string.h>
00013
00014 IWvStream *WvCrashInfo::in_stream = NULL;
00015 const char *WvCrashInfo::in_stream_id = NULL;
00016 enum WvCrashInfo::InStreamState WvCrashInfo::in_stream_state = UNUSED;
00017 static const int ring_buffer_order = wvcrash_ring_buffer_order;
00018 static const int ring_buffer_size = wvcrash_ring_buffer_size;
00019 static const int ring_buffer_mask = ring_buffer_size - 1;
00020 static char ring_buffer[ring_buffer_size+1];
00021 static int ring_buffer_start = 0, ring_buffer_used = 0;
00022
00023 void wvcrash_ring_buffer_put(const char *str)
00024 {
00025 wvcrash_ring_buffer_put(str, strlen(str));
00026 }
00027
00028
00029 void wvcrash_ring_buffer_put(const char *str, size_t len)
00030 {
00031 while (len > 0)
00032 {
00033 int pos = (ring_buffer_start + ring_buffer_used) & ring_buffer_mask;
00034 ring_buffer[pos] = *str++;
00035 --len;
00036 if (ring_buffer_used == ring_buffer_size)
00037 ring_buffer_start = (ring_buffer_start + 1) & ring_buffer_mask;
00038 else
00039 ++ring_buffer_used;
00040 }
00041 }
00042
00043
00044 const char *wvcrash_ring_buffer_get()
00045 {
00046 if (ring_buffer_used == 0)
00047 return NULL;
00048 const char *result;
00049 if (ring_buffer_start + ring_buffer_used >= ring_buffer_size)
00050 {
00051 ring_buffer[ring_buffer_size] = '\0';
00052 result = &ring_buffer[ring_buffer_start];
00053 ring_buffer_used -= ring_buffer_size - ring_buffer_start;
00054 ring_buffer_start = 0;
00055 }
00056 else
00057 {
00058 ring_buffer[ring_buffer_start + ring_buffer_used] = '\0';
00059 result = &ring_buffer[ring_buffer_start];
00060 ring_buffer_start += ring_buffer_used;
00061 ring_buffer_used = 0;
00062 }
00063 return result;
00064 }
00065
00066
00067
00068
00069 #if 1
00070
00071 #ifdef __USE_GNU
00072 static const char *argv0 = program_invocation_short_name;
00073 #else
00074 static const char *argv0 = "UNKNOWN";
00075 #endif // __USE_GNU
00076
00077
00078 static const int buffer_size = 2048;
00079 static char will_msg[buffer_size];
00080 static char assert_msg[buffer_size];
00081
00082
00083 extern "C"
00084 {
00085
00086 void __assert_fail(const char *__assertion, const char *__file,
00087 unsigned int __line, const char *__function)
00088 {
00089
00090 snprintf(assert_msg, buffer_size,
00091 "%s: %s:%u: %s: Assertion `%s' failed.\n",
00092 argv0, __file, __line, __function, __assertion);
00093 assert_msg[buffer_size - 1] = '\0';
00094
00095
00096 fprintf(stderr, "%s: %s:%u: %s: Assertion `%s' failed.\n",
00097 argv0, __file, __line, __function, __assertion);
00098 abort();
00099 }
00100
00101
00102
00103 void __assert(const char *__assertion, const char *__file,
00104 unsigned int __line, const char *__function)
00105 {
00106 __assert_fail(__assertion, __file, __line, __function);
00107 }
00108
00109
00110
00111 void __assert_perror_fail(int __errnum, const char *__file,
00112 unsigned int __line, const char *__function)
00113 {
00114
00115 snprintf(assert_msg, buffer_size,
00116 "%s: %s:%u: %s: Unexpected error: %s.\n",
00117 argv0, __file, __line, __function, strerror(__errnum));
00118 assert_msg[buffer_size - 1] = '\0';
00119
00120
00121 fprintf(stderr, "%s: %s:%u: %s: Unexpected error: %s.\n",
00122 argv0, __file, __line, __function, strerror(__errnum));
00123 abort();
00124 }
00125 }
00126
00127
00128
00129
00130 void wvcrash_leave_will(const char *will)
00131 {
00132 if (will)
00133 {
00134 strncpy(will_msg, will, buffer_size);
00135 will_msg[buffer_size - 1] = '\0';
00136 }
00137 else
00138 will_msg[0] = '\0';
00139 }
00140
00141
00142 const char *wvcrash_read_will()
00143 {
00144 return will_msg;
00145 }
00146
00147
00148 const char *wvcrash_read_assert()
00149 {
00150 return assert_msg;
00151 }
00152
00153
00154 void __wvcrash_init_buffers(const char *program_name)
00155 {
00156 if (program_name)
00157 argv0 = program_name;
00158 will_msg[0] = '\0';
00159 assert_msg[0] = '\0';
00160 }
00161
00162
00163 #else // this is NOT __linux
00164
00165 void wvcrash_leave_will(const char *will) {}
00166 const char *wvcrash_read_will() { return NULL; }
00167
00168 #endif // __linux