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