1
/* Copyright (C) 2008 PrimeBase Technologies GmbH, Germany
3
* PrimeBase Media Stream for MySQL
5
* This program is free software; you can redistribute it and/or modify
6
* it under the terms of the GNU General Public License as published by
7
* the Free Software Foundation; either version 2 of the License, or
8
* (at your option) any later version.
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the Free Software
17
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19
* Original author: Paul McCullagh (H&G2JCtL)
20
* Continued development: Barry Leslie
24
* The main exception classes
31
#define strsignal(s) NULL
33
#include <sys/signal.h>
40
#include "CSException.h"
41
#include "CSStrUtil.h"
44
void CSException::setStackTrace(CSThread *self, const char *stack)
46
char buffer[CS_EXC_CONTEXT_SIZE];
48
self->myException.iStackTrace.setLength(0);
50
self->myException.iStackTrace.append(stack);
51
for (int i=self->callTop-1; i>=0; i--) {
52
cs_format_context(CS_EXC_CONTEXT_SIZE, buffer,
53
self->callStack[i].cs_func, self->callStack[i].cs_file, self->callStack[i].cs_line);
54
self->myException.iStackTrace.append(buffer);
55
self->myException.iStackTrace.append('\n');
59
void CSException::setStackTrace(CSThread *self)
61
setStackTrace(self, NULL);
64
const char *CSException::getStackTrace()
66
return iStackTrace.getCString();
69
void CSException::log(CSThread *self)
72
CSL.log(self, CSLog::Error, getContext());
73
CSL.log(self, CSLog::Error, " ");
74
CSL.log(self, CSLog::Error, getMessage());
75
CSL.eol(self, CSLog::Error);
76
#ifdef DUMP_STACK_TRACE
77
CSL.log(self, CSLog::Error, getStackTrace());
82
void CSException::log(CSThread *self, const char *message)
85
CSL.log(self, CSLog::Error, message);
86
CSL.eol(self, CSLog::Error);
87
CSL.log(self, CSLog::Error, getContext());
88
CSL.log(self, CSLog::Error, " ");
89
CSL.log(self, CSLog::Error, getMessage());
90
CSL.eol(self, CSLog::Error);
91
#ifdef DUMP_STACK_TRACE
92
CSL.log(self, CSLog::Error, getStackTrace());
97
void CSException::initException_va(const char *func, const char *file, int line, int err, const char *fmt, va_list ap)
100
cs_format_context(CS_EXC_CONTEXT_SIZE, iContext, func, file, line);
103
vsprintf(iMessage, fmt, ap);
106
len = vsnprintf(iMessage, CS_EXC_MESSAGE_SIZE-1, fmt, ap);
107
if (len > CS_EXC_MESSAGE_SIZE-1)
108
len = CS_EXC_MESSAGE_SIZE-1;
113
void CSException::initExceptionf(const char *func, const char *file, int line, int err, const char *fmt, ...)
118
initException_va(func, file, line, err, fmt, ap);
122
void CSException::initException(const char *func, const char *file, int line, int err, const char *message)
124
cs_format_context(CS_EXC_CONTEXT_SIZE, iContext, func, file, line);
126
cs_strcpy(CS_EXC_MESSAGE_SIZE, iMessage, message);
129
void CSException::initException(CSException &exception)
131
iErrorCode = exception.iErrorCode;
132
strcpy(iContext, exception.iContext);
133
strcpy(iMessage, exception.iMessage);
135
iStackTrace.setLength(0);
136
iStackTrace.append(exception.iStackTrace.getCString());
140
void CSException::initAssertion(const char *func, const char *file, int line, const char *message)
142
cs_format_context(CS_EXC_CONTEXT_SIZE, iContext, func, file, line);
143
iErrorCode = CS_ERR_ASSERTION;
144
cs_strcpy(CS_EXC_MESSAGE_SIZE, iMessage, "Assertion failed: ");
145
cs_strcat(CS_EXC_MESSAGE_SIZE, iMessage, message);
148
void CSException::getCoreError(uint32_t size, char *buffer, int err)
150
const char *message = NULL;
153
case CS_ERR_JUMP_OVERFLOW: message = "Jump stack overflow"; break;
154
case CS_ERR_BAD_ADDRESS: message = "Incorrect network address: %"; break;
155
case CS_ERR_UNKNOWN_SERVICE: message = "Unknown network service: %"; break;
156
case CS_ERR_UNKNOWN_HOST: message = "Unknown host: %"; break;
157
case CS_ERR_UNKNOWN_METHOD: message = "Unknown HTTP method: %"; break;
158
case CS_ERR_NO_LISTENER: message = "Listening port has been closed"; break;
159
case CS_ERR_RELEASE_OVERFLOW: message = "Release stack overflow"; break;
160
case CS_ERR_IMPL_MISSING: message = "Function %s not implemented"; break;
161
case CS_ERR_BAD_HEADER_MAGIC: message = "Incorrect file type"; break;
162
case CS_ERR_VERSION_TOO_NEW: message = "Incompatible file version"; break;
165
cs_strcpy(size, buffer, message);
167
cs_strcpy(size, buffer, "Unknown system error ");
168
cs_strcat(size, buffer, err);
172
void CSException::initCoreError(const char *func, const char *file, int line, int err)
174
cs_format_context(CS_EXC_CONTEXT_SIZE, iContext, func, file, line);
176
getCoreError(CS_EXC_MESSAGE_SIZE, iMessage, err);
179
void CSException::initCoreError(const char *func, const char *file, int line, int err, const char *item)
181
cs_format_context(CS_EXC_CONTEXT_SIZE, iContext, func, file, line);
183
getCoreError(CS_EXC_MESSAGE_SIZE, iMessage, err);
184
cs_replace_string(CS_EXC_MESSAGE_SIZE, iMessage, "%s", item);
187
void CSException::initOSError(const char *func, const char *file, int line, int err)
191
cs_format_context(CS_EXC_CONTEXT_SIZE, iContext, func, file, line);
195
if (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, err, 0, iMessage, CS_EXC_MESSAGE_SIZE, NULL)) {
198
ptr = &iMessage[strlen(iMessage)];
199
while (ptr-1 > err_msg) {
200
if (*(ptr-1) != '\n' && *(ptr-1) != '\r' && *(ptr-1) != '.')
206
cs_strcat(CS_EXC_MESSAGE_SIZE, iMessage, " (");
207
cs_strcat(CS_EXC_MESSAGE_SIZE, iMessage, err);
208
cs_strcat(CS_EXC_MESSAGE_SIZE, iMessage, ")");
215
cs_strcpy(CS_EXC_MESSAGE_SIZE, iMessage, msg);
216
cs_strcat(CS_EXC_MESSAGE_SIZE, iMessage, " (");
217
cs_strcat(CS_EXC_MESSAGE_SIZE, iMessage, err);
218
cs_strcat(CS_EXC_MESSAGE_SIZE, iMessage, ")");
221
cs_strcpy(CS_EXC_MESSAGE_SIZE, iMessage, "Unknown OS error code ");
222
cs_strcat(CS_EXC_MESSAGE_SIZE, iMessage, err);
226
void CSException::initFileError(const char *func, const char *file, int line, const char *path, int err)
228
initOSError(func, file, line, err);
229
cs_strcat(CS_EXC_MESSAGE_SIZE, iMessage, ": '");
230
cs_strcat(CS_EXC_MESSAGE_SIZE, iMessage, path);
231
cs_strcat(CS_EXC_MESSAGE_SIZE, iMessage, "'");
234
void CSException::initSignal(const char *func, const char *file, int line, int sig)
238
cs_format_context(CS_EXC_CONTEXT_SIZE, iContext, func, file, line);
240
if (!(str = strsignal(sig))) {
241
cs_strcpy(CS_EXC_MESSAGE_SIZE, iMessage, "Unknown signal ");
242
cs_strcat(CS_EXC_MESSAGE_SIZE, iMessage, sig);
245
cs_strcpy(CS_EXC_MESSAGE_SIZE, iMessage, str);
246
cs_strcat(CS_EXC_MESSAGE_SIZE, iMessage, " (");
247
cs_strcat(CS_EXC_MESSAGE_SIZE, iMessage, sig);
248
cs_strcat(CS_EXC_MESSAGE_SIZE, iMessage, ")");
252
void CSException::initEOFError(const char *func, const char *file, int line, const char *path)
254
cs_format_context(CS_EXC_CONTEXT_SIZE, iContext, func, file, line);
255
iErrorCode = CS_ERR_EOF;
256
cs_strcpy(CS_EXC_MESSAGE_SIZE, iMessage, "EOF encountered: '");
257
cs_strcat(CS_EXC_MESSAGE_SIZE, iMessage, path);
258
cs_strcat(CS_EXC_MESSAGE_SIZE, iMessage, "'");
261
void CSException::RecordException(const char *func, const char *file, int line, int err, const char *message)
265
if ((self = CSThread::getSelf())) {
266
if (!self->myException.getErrorCode())
267
self->myException.initException(func, file, line, err, message);
271
void CSException::ClearException()
275
if ((self = CSThread::getSelf())) {
276
self->myException.setErrorCode(0);
280
void CSException::throwException(const char *func, const char *file, int line, int err, const char *message, const char *stack)
284
if ((self = CSThread::getSelf())) {
285
self->myException.initException(func, file, line, err, message);
286
self->myException.setStackTrace(self, stack);
287
self->throwException();
292
e.initException(func, file, line, err, message);
293
e.log(NULL, "*** Uncaught error");
297
void CSException::throwException(const char *func, const char *file, int line, int err, const char *message)
299
throwException(func, file, line, err, message, NULL);
302
void CSException::throwExceptionf(const char *func, const char *file, int line, int err, const char *fmt, ...)
308
if ((self = CSThread::getSelf())) {
309
self->myException.initException_va(func, file, line, err, fmt, ap);
311
self->myException.setStackTrace(self, NULL);
312
self->throwException();
317
e.initException_va(func, file, line, err, fmt, ap);
319
e.log(NULL, "*** Uncaught error");
323
void CSException::throwAssertion(const char *func, const char *file, int line, const char *message)
327
if ((self = CSThread::getSelf())) {
328
self->myException.initAssertion(func, file, line, message);
329
self->myException.setStackTrace(self);
330
/* Not sure why we log the excpetion down here?!
331
self->logException();
333
self->throwException();
338
e.initAssertion(func, file, line, message);
339
e.log(NULL, "*** Uncaught error");
343
void CSException::throwCoreError(const char *func, const char *file, int line, int err)
347
if ((self = CSThread::getSelf())) {
348
self->myException.initCoreError(func, file, line, err);
349
self->myException.setStackTrace(self);
350
self->throwException();
355
e.initCoreError(func, file, line, err);
356
e.log(NULL, "*** Uncaught error");
360
void CSException::throwCoreError(const char *func, const char *file, int line, int err, const char *item)
364
if ((self = CSThread::getSelf())) {
365
self->myException.initCoreError(func, file, line, err, item);
366
self->myException.setStackTrace(self);
367
self->throwException();
372
e.initCoreError(func, file, line, err, item);
373
e.log(NULL, "*** Uncaught error");
377
void CSException::throwOSError(const char *func, const char *file, int line, int err)
381
if ((self = CSThread::getSelf())) {
382
/* A pending signal has priority over a system error,
383
* In fact, the pending signal may be the reason for
387
self->myException.initOSError(func, file, line, err);
388
self->myException.setStackTrace(self);
389
self->throwException();
394
e.initOSError(func, file, line, err);
395
e.log(NULL, "*** Uncaught error");
399
void CSException::throwFileError(const char *func, const char *file, int line, const char *path, int err)
403
if ((self = CSThread::getSelf())) {
405
self->myException.initFileError(func, file, line, path, err);
406
self->myException.setStackTrace(self);
407
self->throwException();
412
e.initFileError(func, file, line, path, err);
413
e.log(NULL, "*** Uncaught error");
417
void CSException::throwFileError(const char *func, const char *file, int line, CSString *path, int err)
421
if ((self = CSThread::getSelf())) {
423
self->myException.initFileError(func, file, line, path->getCString(), err);
424
self->myException.setStackTrace(self);
425
self->throwException();
430
e.initFileError(func, file, line, path->getCString(), err);
431
e.log(NULL, "*** Uncaught error");
435
void CSException::throwSignal(const char *func, const char *file, int line, int sig)
439
if ((self = CSThread::getSelf())) {
440
self->myException.initSignal(func, file, line, sig);
441
self->myException.setStackTrace(self);
442
self->throwException();
447
e.initSignal(func, file, line, sig);
448
e.log(NULL, "*** Uncaught error");
452
void CSException::throwEOFError(const char *func, const char *file, int line, const char *path)
456
if ((self = CSThread::getSelf())) {
458
self->myException.initEOFError(func, file, line, path);
459
self->myException.setStackTrace(self);
460
self->throwException();
465
e.initEOFError(func, file, line, path);
466
e.log(NULL, "*** Uncaught error");
470
void CSException::throwLastError(const char *func, const char *file, int line)
473
throwOSError(func, file, line, (int) GetLastError());
475
throwOSError(func, file, line, (int) errno);
479
void CSException::logOSError(const char *func, const char *file, int line, int err)
483
if ((self = CSThread::getSelf())) {
484
self->myException.initOSError(func, file, line, err);
485
self->myException.setStackTrace(self);
486
self->logException();
491
e.initOSError(func, file, line, err);
496
void CSException::logOSError(CSThread *self, const char *func, const char *file, int line, int err)
498
self->myException.initOSError(func, file, line, err);
499
self->myException.setStackTrace(self);
500
self->logException();
503
void CSException::logException(const char *func, const char *file, int line, int err, const char *message)
507
if ((self = CSThread::getSelf())) {
508
self->myException.initException(func, file, line, err, message);
509
self->logException();
514
e.initException(func, file, line, err,message);