forked from osmocom/wireshark
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
This commit is contained in:
parent
b003633f3b
commit
f618b54d36
|
@ -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:
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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 *));
|
||||
|
|
|
@ -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))
|
||||
|
|
Loading…
Reference in New Issue