~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/pbms/src/cslib/CSException.cc

  • Committer: Brian Aker
  • Date: 2010-11-22 00:16:44 UTC
  • mto: (1945.2.1 quick)
  • mto: This revision was merged to the branch mainline in revision 1947.
  • Revision ID: brian@tangent.org-20101122001644-pi6jv0d65e82xn38
Merge in lock refactor, this just encapsulates.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (c) 2008 PrimeBase Technologies GmbH, Germany
 
2
 *
 
3
 * PrimeBase Media Stream for MySQL
 
4
 *
 
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.
 
9
 *
 
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.
 
14
 *
 
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
 
18
 *
 
19
 * Original author: Paul McCullagh (H&G2JCtL)
 
20
 * Continued development: Barry Leslie
 
21
 *
 
22
 * 2007-05-20
 
23
 *
 
24
 * The main exception classes
 
25
 *
 
26
 */
 
27
 
 
28
#include "CSConfig.h"
 
29
 
 
30
#ifdef OS_WINDOWS
 
31
#define strsignal(s) NULL
 
32
#else
 
33
#include <sys/signal.h>
 
34
#endif
 
35
 
 
36
#include <limits.h>
 
37
#include <string.h>
 
38
 
 
39
#include "CSGlobal.h"
 
40
#include "CSException.h"
 
41
#include "CSStrUtil.h"
 
42
#include "CSLog.h"
 
43
 
 
44
void CSException::setStackTrace(CSThread *self, const char *stack)
 
45
{
 
46
        char buffer[CS_EXC_CONTEXT_SIZE];
 
47
 
 
48
        self->myException.iStackTrace.setLength(0);
 
49
        if (stack)
 
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');
 
56
        }
 
57
}
 
58
 
 
59
void CSException::setStackTrace(CSThread *self)
 
60
{
 
61
        setStackTrace(self, NULL);
 
62
}
 
63
 
 
64
const char *CSException::getStackTrace()
 
65
{
 
66
        return iStackTrace.getCString();
 
67
}
 
68
 
 
69
void CSException::log(CSThread *self)
 
70
{
 
71
        CSL.lock();
 
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());
 
78
#endif
 
79
        CSL.unlock();
 
80
}
 
81
 
 
82
void CSException::log(CSThread *self, const char *message)
 
83
{
 
84
        CSL.lock();
 
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());
 
93
#endif
 
94
        CSL.unlock();
 
95
}
 
96
 
 
97
void CSException::initException_va(const char *func, const char *file, int line, int err, const char *fmt, va_list ap)
 
98
{
 
99
 
 
100
        cs_format_context(CS_EXC_CONTEXT_SIZE, iContext, func, file, line);
 
101
        iErrorCode = err;
 
102
#ifdef OS_WINDOWS
 
103
        vsprintf(iMessage, fmt, ap);
 
104
#else
 
105
        size_t len;
 
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;
 
109
        iMessage[len] = 0;
 
110
#endif
 
111
}
 
112
 
 
113
void CSException::initExceptionf(const char *func, const char *file, int line, int err, const char *fmt, ...)
 
114
{
 
115
        va_list ap;
 
116
 
 
117
        va_start(ap, fmt);
 
118
        initException_va(func, file, line, err, fmt, ap);
 
119
        va_end(ap);
 
120
}
 
121
 
 
122
void CSException::initException(const char *func, const char *file, int line, int err, const char *message)
 
123
{
 
124
        cs_format_context(CS_EXC_CONTEXT_SIZE, iContext, func, file, line);
 
125
        iErrorCode = err;
 
126
        cs_strcpy(CS_EXC_MESSAGE_SIZE, iMessage, message);
 
127
}
 
128
 
 
129
void CSException::initException(CSException &exception)
 
130
{
 
131
        iErrorCode = exception.iErrorCode;
 
132
        strcpy(iContext, exception.iContext);
 
133
        strcpy(iMessage, exception.iMessage);
 
134
        
 
135
        iStackTrace.setLength(0);
 
136
        iStackTrace.append(exception.iStackTrace.getCString());
 
137
 
 
138
}
 
139
 
 
140
void CSException::initAssertion(const char *func, const char *file, int line, const char *message)
 
141
{
 
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);
 
146
}
 
147
 
 
148
void CSException::getCoreError(uint32_t size, char *buffer, int err)
 
149
{
 
150
        const char *message = NULL;
 
151
 
 
152
        switch (err) {
 
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;
 
163
        }
 
164
        if (message)
 
165
                cs_strcpy(size, buffer, message);
 
166
        else {
 
167
                cs_strcpy(size, buffer, "Unknown system error ");
 
168
                cs_strcat(size, buffer, err);
 
169
        }
 
170
}
 
171
 
 
172
void CSException::initCoreError(const char *func, const char *file, int line, int err)
 
173
{
 
174
        cs_format_context(CS_EXC_CONTEXT_SIZE, iContext, func, file, line);
 
175
        iErrorCode = err;
 
176
        getCoreError(CS_EXC_MESSAGE_SIZE, iMessage, err);
 
177
}
 
178
 
 
179
void CSException::initCoreError(const char *func, const char *file, int line, int err, const char *item)
 
180
{
 
181
        cs_format_context(CS_EXC_CONTEXT_SIZE, iContext, func, file, line);
 
182
        iErrorCode = err;
 
183
        getCoreError(CS_EXC_MESSAGE_SIZE, iMessage, err);
 
184
        cs_replace_string(CS_EXC_MESSAGE_SIZE, iMessage, "%s", item);
 
185
}
 
186
 
 
187
void CSException::initOSError(const char *func, const char *file, int line, int err)
 
188
{
 
189
        char *msg;
 
190
 
 
191
        cs_format_context(CS_EXC_CONTEXT_SIZE, iContext, func, file, line);
 
192
        iErrorCode = err;
 
193
 
 
194
#ifdef XT_WIN
 
195
        if (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, err, 0, iMessage, CS_EXC_MESSAGE_SIZE, NULL)) {
 
196
                char *ptr;
 
197
 
 
198
                ptr = &iMessage[strlen(iMessage)];
 
199
                while (ptr-1 > err_msg) {
 
200
                        if (*(ptr-1) != '\n' && *(ptr-1) != '\r' && *(ptr-1) != '.')
 
201
                                break;
 
202
                        ptr--;
 
203
                }
 
204
                *ptr = 0;
 
205
 
 
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, ")");
 
209
                return;
 
210
        }
 
211
#endif
 
212
 
 
213
        msg = strerror(err);
 
214
        if (msg) {
 
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, ")");
 
219
        }
 
220
        else {
 
221
                cs_strcpy(CS_EXC_MESSAGE_SIZE, iMessage, "Unknown OS error code ");
 
222
                cs_strcat(CS_EXC_MESSAGE_SIZE, iMessage, err);
 
223
        }
 
224
}
 
225
 
 
226
void CSException::initFileError(const char *func, const char *file, int line, const char *path, int err)
 
227
{
 
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, "'");
 
232
}
 
233
 
 
234
void CSException::initSignal(const char *func, const char *file, int line, int sig)
 
235
{
 
236
        char *str;
 
237
 
 
238
        cs_format_context(CS_EXC_CONTEXT_SIZE, iContext, func, file, line);
 
239
        iErrorCode = sig;
 
240
        if (!(str = strsignal(sig))) {
 
241
                cs_strcpy(CS_EXC_MESSAGE_SIZE, iMessage, "Unknown signal ");
 
242
                cs_strcat(CS_EXC_MESSAGE_SIZE, iMessage, sig);
 
243
        }
 
244
        else {
 
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, ")");
 
249
        }
 
250
}
 
251
 
 
252
void CSException::initEOFError(const char *func, const char *file, int line, const char *path)
 
253
{
 
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, "'");
 
259
}
 
260
 
 
261
void CSException::RecordException(const char *func, const char *file, int line, int err, const char *message)
 
262
{
 
263
        CSThread *self;
 
264
 
 
265
        if ((self = CSThread::getSelf())) {
 
266
                if (!self->myException.getErrorCode())
 
267
                        self->myException.initException(func, file, line, err, message);
 
268
        }
 
269
}
 
270
 
 
271
void CSException::ClearException()
 
272
{
 
273
        CSThread *self;
 
274
 
 
275
        if ((self = CSThread::getSelf())) {
 
276
                self->myException.setErrorCode(0);
 
277
        }
 
278
}
 
279
 
 
280
void CSException::throwException(const char *func, const char *file, int line, int err, const char *message, const char *stack)
 
281
{
 
282
        CSThread *self;
 
283
 
 
284
        if ((self = CSThread::getSelf())) {
 
285
                self->myException.initException(func, file, line, err, message);
 
286
                self->myException.setStackTrace(self, stack);
 
287
                self->throwException();
 
288
        }
 
289
        else {
 
290
                CSException e;
 
291
                
 
292
                e.initException(func, file, line, err, message);
 
293
                e.log(NULL, "*** Uncaught error");
 
294
        }
 
295
}
 
296
 
 
297
void CSException::throwException(const char *func, const char *file, int line, int err, const char *message)
 
298
{
 
299
        throwException(func, file, line, err, message, NULL);
 
300
}
 
301
 
 
302
void CSException::throwExceptionf(const char *func, const char *file, int line, int err, const char *fmt, ...)
 
303
{
 
304
        CSThread        *self;
 
305
        va_list         ap;
 
306
 
 
307
        va_start(ap, fmt);
 
308
        if ((self = CSThread::getSelf())) {
 
309
                self->myException.initException_va(func, file, line, err, fmt, ap);
 
310
                va_end(ap);
 
311
                self->myException.setStackTrace(self, NULL);
 
312
                self->throwException();
 
313
        }
 
314
        else {
 
315
                CSException e;
 
316
                
 
317
                e.initException_va(func, file, line, err, fmt, ap);
 
318
                va_end(ap);
 
319
                e.log(NULL, "*** Uncaught error");
 
320
        }
 
321
}
 
322
 
 
323
void CSException::throwAssertion(const char *func, const char *file, int line, const char *message)
 
324
{
 
325
        CSThread *self;
 
326
 
 
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();
 
332
                */
 
333
                self->throwException();
 
334
        }
 
335
        else {
 
336
                CSException e;
 
337
                
 
338
                e.initAssertion(func, file, line, message);
 
339
                e.log(NULL, "*** Uncaught error");
 
340
        }
 
341
}
 
342
 
 
343
void CSException::throwCoreError(const char *func, const char *file, int line, int err)
 
344
{
 
345
        CSThread *self;
 
346
 
 
347
        if ((self = CSThread::getSelf())) {
 
348
                self->myException.initCoreError(func, file, line, err);
 
349
                self->myException.setStackTrace(self);
 
350
                self->throwException();
 
351
        }
 
352
        else {
 
353
                CSException e;
 
354
                
 
355
                e.initCoreError(func, file, line, err);
 
356
                e.log(NULL, "*** Uncaught error");
 
357
        }
 
358
}
 
359
 
 
360
void CSException::throwCoreError(const char *func, const char *file, int line, int err, const char *item)
 
361
{
 
362
        CSThread *self;
 
363
 
 
364
        if ((self = CSThread::getSelf())) {
 
365
                self->myException.initCoreError(func, file, line, err, item);
 
366
                self->myException.setStackTrace(self);
 
367
                self->throwException();
 
368
        }
 
369
        else {
 
370
                CSException e;
 
371
                
 
372
                e.initCoreError(func, file, line, err, item);
 
373
                e.log(NULL, "*** Uncaught error");
 
374
        }
 
375
}
 
376
 
 
377
void CSException::throwOSError(const char *func, const char *file, int line, int err)
 
378
{
 
379
        CSThread *self;
 
380
 
 
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
 
384
                 * system error:
 
385
                 */
 
386
                self->interrupted();
 
387
                self->myException.initOSError(func, file, line, err);
 
388
                self->myException.setStackTrace(self);
 
389
                self->throwException();
 
390
        }
 
391
        else {
 
392
                CSException e;
 
393
                
 
394
                e.initOSError(func, file, line, err);
 
395
                e.log(NULL, "*** Uncaught error");
 
396
        }
 
397
}
 
398
 
 
399
void CSException::throwFileError(const char *func, const char *file, int line, const char *path, int err)
 
400
{
 
401
        CSThread *self;
 
402
 
 
403
        if ((self = CSThread::getSelf())) {
 
404
                self->interrupted();
 
405
                self->myException.initFileError(func, file, line, path, err);
 
406
                self->myException.setStackTrace(self);
 
407
                self->throwException();
 
408
        }
 
409
        else {
 
410
                CSException e;
 
411
                
 
412
                e.initFileError(func, file, line, path, err);
 
413
                e.log(NULL, "*** Uncaught error");
 
414
        }
 
415
}
 
416
 
 
417
void CSException::throwFileError(const char *func, const char *file, int line, CSString *path, int err)
 
418
{
 
419
        CSThread *self;
 
420
 
 
421
        if ((self = CSThread::getSelf())) {
 
422
                self->interrupted();
 
423
                self->myException.initFileError(func, file, line, path->getCString(), err);
 
424
                self->myException.setStackTrace(self);
 
425
                self->throwException();
 
426
        }
 
427
        else {
 
428
                CSException e;
 
429
                
 
430
                e.initFileError(func, file, line, path->getCString(), err);
 
431
                e.log(NULL, "*** Uncaught error");
 
432
        }
 
433
}
 
434
 
 
435
void CSException::throwSignal(const char *func, const char *file, int line, int sig)
 
436
{
 
437
        CSThread *self;
 
438
 
 
439
        if ((self = CSThread::getSelf())) {
 
440
                self->myException.initSignal(func, file, line, sig);
 
441
                self->myException.setStackTrace(self);
 
442
                self->throwException();
 
443
        }
 
444
        else {
 
445
                CSException e;
 
446
                
 
447
                e.initSignal(func, file, line, sig);
 
448
                e.log(NULL, "*** Uncaught error");
 
449
        }
 
450
}
 
451
 
 
452
void CSException::throwEOFError(const char *func, const char *file, int line, const char *path)
 
453
{
 
454
        CSThread *self;
 
455
 
 
456
        if ((self = CSThread::getSelf())) {
 
457
                self->interrupted();
 
458
                self->myException.initEOFError(func, file, line, path);
 
459
                self->myException.setStackTrace(self);
 
460
                self->throwException();
 
461
        }
 
462
        else {
 
463
                CSException e;
 
464
                
 
465
                e.initEOFError(func, file, line, path);
 
466
                e.log(NULL, "*** Uncaught error");
 
467
        }
 
468
}
 
469
 
 
470
void CSException::throwLastError(const char *func, const char *file, int line)
 
471
{
 
472
#ifdef OS_WINDOWS
 
473
        throwOSError(func, file, line, (int) GetLastError());
 
474
#else
 
475
        throwOSError(func, file, line, (int) errno);
 
476
#endif
 
477
}
 
478
 
 
479
void CSException::logOSError(const char *func, const char *file, int line, int err)
 
480
{
 
481
        CSThread *self;
 
482
 
 
483
        if ((self = CSThread::getSelf())) {
 
484
                self->myException.initOSError(func, file, line, err);
 
485
                self->myException.setStackTrace(self);
 
486
                self->logException();
 
487
        }
 
488
        else {
 
489
                CSException e;
 
490
                
 
491
                e.initOSError(func, file, line, err);
 
492
                e.log(NULL);
 
493
        }
 
494
}
 
495
 
 
496
void CSException::logOSError(CSThread *self, const char *func, const char *file, int line, int err)
 
497
{
 
498
        self->myException.initOSError(func, file, line, err);
 
499
        self->myException.setStackTrace(self);
 
500
        self->logException();
 
501
}
 
502
 
 
503
void CSException::logException(const char *func, const char *file, int line, int err, const char *message)
 
504
{
 
505
        CSThread *self;
 
506
 
 
507
        if ((self = CSThread::getSelf())) {
 
508
                self->myException.initException(func, file, line, err, message);
 
509
                self->logException();
 
510
        }
 
511
        else {
 
512
                CSException e;
 
513
                
 
514
                e.initException(func, file, line, err,message);
 
515
                e.log(NULL);
 
516
        }
 
517
}
 
518
 
 
519