diff options
author | Guy Harris <guy@alum.mit.edu> | 2005-08-06 19:58:45 +0000 |
---|---|---|
committer | Guy Harris <guy@alum.mit.edu> | 2005-08-06 19:58:45 +0000 |
commit | f618b54d368be8ee5b26c982f492d4132cda1f16 (patch) | |
tree | 4b2184339504000339e2cc5ef6405aa2320fc255 | |
parent | b003633f3bc22bf99d9c1afcddb3b27ecffc9b30 (diff) |
Support throwing an exception with a null message pointer, and have the
message not be const (as we generate messages with "g_strdup_sprintf()",
which means they need to be freed; using a null message means that we
don't have to use a special string for exceptions with no message, and
don't have to worry about not freeing that).
Have THROW() throw an exception with a null message pointer. (This
means that you crash if you throw DissectorError with THROW(). Don't do
that - it means you don't get a more detailed explanation of the
dissector problem. Use the DISSECTOR_ASSERT, etc. macros in
epan/proto.h instead.)
Free the exception message for DissectorError, as it's mallocated.
svn path=/trunk/; revision=15250
-rw-r--r-- | epan/dissectors/packet-frame.c | 1 | ||||
-rw-r--r-- | epan/except.c | 53 | ||||
-rw-r--r-- | epan/except.h | 17 | ||||
-rw-r--r-- | epan/exceptions.h | 10 |
4 files changed, 65 insertions, 16 deletions
diff --git a/epan/dissectors/packet-frame.c b/epan/dissectors/packet-frame.c index ba98cfde20..d9b607732d 100644 --- a/epan/dissectors/packet-frame.c +++ b/epan/dissectors/packet-frame.c @@ -288,6 +288,7 @@ show_exception(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, pinfo->current_proto, exception_message); g_warning("Dissector bug, protocol %s, in packet %u: %s", pinfo->current_proto, pinfo->fd->num, exception_message); + g_free(exception_message); break; default: diff --git a/epan/except.c b/epan/except.c index 8b61edc317..3aa8d84908 100644 --- a/epan/except.c +++ b/epan/except.c @@ -17,6 +17,15 @@ * $Name: $ */ +/* + * Modified to support throwing an exception with a null message pointer, + * and to have the message not be const (as we generate messages with + * "g_strdup_sprintf()", which means they need to be freed; using + * a null message means that we don't have to use a special string + * for exceptions with no message, and don't have to worry about + * not freeing that). + */ + #include <assert.h> #include <stdlib.h> #include <stdio.h> @@ -194,9 +203,15 @@ static void do_throw(except_t *except) static void unhandled_catcher(except_t *except) { - fprintf(stderr, "Unhandled exception (\"%s\", group=%ld, code=%ld)\n", - except->except_message, except->except_id.except_group, - except->except_id.except_code); + if (except->except_message == NULL) { + fprintf(stderr, "Unhandled exception (group=%ld, code=%ld)\n", + except->except_id.except_group, + except->except_id.except_code); + } else { + fprintf(stderr, "Unhandled exception (\"%s\", group=%ld, code=%ld)\n", + except->except_message, except->except_id.except_group, + except->except_id.except_code); + } abort(); } @@ -244,7 +259,7 @@ void except_rethrow(except_t *except) do_throw(except); } -void except_throw(long group, long code, const char *msg) +void except_throw(long group, long code, char *msg) { except_t except; @@ -256,7 +271,7 @@ void except_throw(long group, long code, const char *msg) do_throw(&except); } -void except_throwd(long group, long code, const char *msg, void *data) +void except_throwd(long group, long code, char *msg, void *data) { except_t except; @@ -268,6 +283,11 @@ void except_throwd(long group, long code, const char *msg, void *data) do_throw(&except); } +/* + * XXX - should we use g_strdup_sprintf() here, so we're not limited by + * XCEPT_BUFFER_SIZE? We could then just use this to generate formatted + * messages. + */ void except_throwf(long group, long code, const char *fmt, ...) { char *buf = except_alloc(XCEPT_BUFFER_SIZE); @@ -301,7 +321,7 @@ unsigned long except_group(except_t *ex) return ex->except_id.except_group; } -const char *except_message(except_t *ex) +char *except_message(except_t *ex) { return ex->except_message; } @@ -369,6 +389,7 @@ int main(int argc, char **argv) { static const except_id_t catch[] = { { 1, 1 }, { 1, 2 } }; except_t *ex; + char *msg; /* * Nested exception ``try blocks'' @@ -383,15 +404,27 @@ int main(int argc, char **argv) top_level(); } else { /* inner catch */ - printf("caught exception (inner): \"%s\", s=%ld, c=%ld\n", - except_message(ex), except_group(ex), except_code(ex)); + msg = except_message(ex); + if (msg == NULL) { + printf("caught exception (inner): s=%ld, c=%ld\n", + except_group(ex), except_code(ex)); + } else { + printf("caught exception (inner): \"%s\", s=%ld, c=%ld\n", + msg, except_group(ex), except_code(ex)); + } except_rethrow(ex); } except_try_pop(); } else { /* outer catch */ - printf("caught exception (outer): \"%s\", s=%ld, c=%ld\n", - except_message(ex), except_group(ex), except_code(ex)); + msg = except_message(ex); + if (msg == NULL) { + printf("caught exception (outer): s=%ld, c=%ld\n", + except_group(ex), except_code(ex)); + } else { + printf("caught exception (outer): \"%s\", s=%ld, c=%ld\n", + except_message(ex), except_group(ex), except_code(ex)); + } } except_try_pop(); except_throw(99, 99, "exception in main"); diff --git a/epan/except.h b/epan/except.h index 459555d210..741cd0eabe 100644 --- a/epan/except.h +++ b/epan/except.h @@ -18,6 +18,15 @@ * $Name: $ */ +/* + * Modified to support throwing an exception with a null message pointer, + * and to have the message not be const (as we generate messages with + * "g_strdup_sprintf()", which means they need to be freed; using + * a null message means that we don't have to use a special string + * for exceptions with no message, and don't have to worry about + * not freeing that). + */ + #ifndef XCEPT_H #define XCEPT_H @@ -42,7 +51,7 @@ typedef struct { typedef struct { except_id_t volatile except_id; - const char *volatile except_message; + char *volatile except_message; void *volatile except_dyndata; } except_t; @@ -82,13 +91,13 @@ extern struct except_stacknode *except_pop(void); extern int except_init(void); extern void except_deinit(void); extern void except_rethrow(except_t *); -extern void except_throw(long, long, const char *); -extern void except_throwd(long, long, const char *, void *); +extern void except_throw(long, long, char *); +extern void except_throwd(long, long, char *, void *); extern void except_throwf(long, long, const char *, ...); extern void (*except_unhandled_catcher(void (*)(except_t *)))(except_t *); extern unsigned long except_code(except_t *); extern unsigned long except_group(except_t *); -extern const char *except_message(except_t *); +extern char *except_message(except_t *); extern void *except_data(except_t *); extern void *except_take_data(except_t *); extern void except_set_allocator(void *(*)(size_t), void (*)(void *)); diff --git a/epan/exceptions.h b/epan/exceptions.h index 355224e930..de223f4ebd 100644 --- a/epan/exceptions.h +++ b/epan/exceptions.h @@ -46,7 +46,13 @@ #define TypeError 3 /** - A bug was detected in a dissector + A bug was detected in a dissector. + + DO NOT throw this with THROW(); the handler expects there to be a + message, and even if it didn't, the developers expect there to be + a message to make it easier to figure out what the problem is. + + Instead, use the DISSECTOR_ASSERT(), etc. macros in epan/proto.h. **/ #define DissectorError 4 @@ -195,7 +201,7 @@ /* user's code goes here */ #define THROW(x) \ - except_throw(XCEPT_GROUP_ETHEREAL, (x), "XCEPT_GROUP_ETHEREAL") + except_throw(XCEPT_GROUP_ETHEREAL, (x), NULL) #define THROW_MESSAGE(x, y) \ except_throw(XCEPT_GROUP_ETHEREAL, (x), (y)) |