From 1c280a8cde7ee67ebb8b10495ed3ba46444a7f60 Mon Sep 17 00:00:00 2001 From: Andrew Kesterson Date: Sat, 30 Jul 2011 23:21:17 -0400 Subject: [PATCH] Better makefile, restructured, more demos --- Makefile | 18 +++++++---- demo/single.c | 23 +++++++++++++ demo/threelevel.c | 16 +++++++++ demo/trypair.c | 21 ++++++++++++ demo/twolevel.c | 21 ++++++++++++ exception_test.c | 63 ------------------------------------ exception_test_simple.c | 31 ------------------ exclib.h => include/exclib.h | 17 ++++++---- exclib.c => src/exclib.c | 55 ++++++++++++++++--------------- 9 files changed, 129 insertions(+), 136 deletions(-) create mode 100644 demo/single.c create mode 100644 demo/threelevel.c create mode 100644 demo/trypair.c create mode 100644 demo/twolevel.c delete mode 100644 exception_test.c delete mode 100644 exception_test_simple.c rename exclib.h => include/exclib.h (96%) rename exclib.c => src/exclib.c (81%) diff --git a/Makefile b/Makefile index 69441d2..be058a8 100644 --- a/Makefile +++ b/Makefile @@ -1,19 +1,23 @@ CC=gcc LD=gcc EXECOBJ= -OBJECTS=exclib.o exception_test.o +LIBOBJECTS=src/exclib.o +DEMOS=demo/single.exe demo/twolevel.exe demo/threelevel.exe demo/trypair.exe +LIBTARGET=lib/libexc.a LIBS= CFLAGS= -all: exception_test +all: $(LIBTARGET) $(DEMOS) + +demo/%.exe: demo/%.o + $(LD) -o $@ $(CFLAGS) -L./lib $< -lexc -ggdb -gstabs %.o: %.c - $(CC) -c -o $@ $(CFLAGS) -rdynamic -ggdb -gstabs $< + $(CC) -c -o $@ $(CFLAGS) -ggdb -gstabs -I./include $< -exception_test: $(OBJECTS) - $(LD) -o exception_test $(LIBS) $(OBJECTS) +$(LIBTARGET): $(LIBOBJECTS) + ar rcs $(LIBTARGET) $(LIBOBJECTS) .PHONY: clean clean: - rm -f *.o - rm -f exception_test \ No newline at end of file + rm -f demo/*o $(LIBOBJECTS) $(DEMOS) $(LIBTARGET) diff --git a/demo/single.c b/demo/single.c new file mode 100644 index 0000000..c49d0ac --- /dev/null +++ b/demo/single.c @@ -0,0 +1,23 @@ +#include "exclib.h" + +/* + * What this demo shows: + * 1- The general usage of this library + * 2- That a basic usage example works + */ + +int main(void) +{ + EXCLIB_TRACE("No stack to print?"); + + TRY { + THROW(3, NULL); + } CATCH(3) { + EXCLIB_TRACE("Caught 3"); + } ETRY; + + EXCLIB_TRACE("Exiting program"); + + return 0; + +} diff --git a/demo/threelevel.c b/demo/threelevel.c new file mode 100644 index 0000000..0310710 --- /dev/null +++ b/demo/threelevel.c @@ -0,0 +1,16 @@ +#include "exclib.h" + +int main(void) +{ + TRY { + TRY { + THROW(3, NULL); + } CATCH(5) { + EXCLIB_TRACE("Caught 5"); + } ETRY; + } CATCH(3) { + EXCLIB_TRACE("Caught 3"); + } ETRY; + + return 0; +} diff --git a/demo/trypair.c b/demo/trypair.c new file mode 100644 index 0000000..c6cc59c --- /dev/null +++ b/demo/trypair.c @@ -0,0 +1,21 @@ +#include "exclib.h" + +int main(void) +{ + TRY { + THROW(3, NULL); + } CATCH(3) { + } ETRY; + + TRY { + THROW(3, NULL); + } CATCH(3) { + TRY { + THROW(3, NULL); + } ETRY; + } ETRY; + + EXCLIB_TRACE("Should never get here"); + return 0; + +} diff --git a/demo/twolevel.c b/demo/twolevel.c new file mode 100644 index 0000000..e67fe1e --- /dev/null +++ b/demo/twolevel.c @@ -0,0 +1,21 @@ +#include "exclib.h" + +/* + * What this example shows: + * 1- That an exception will propagate up out of the current TRY/CATCH context + * 2- That an uncaught exception will generate an error + */ + +int main(void) +{ + TRY { + THROW(3, NULL); + } CATCH(3) { + THROW(3, NULL); + } ETRY; + + EXCLIB_TRACE("Should never get here"); + + return 0; + +} diff --git a/exception_test.c b/exception_test.c deleted file mode 100644 index 7cc6e24..0000000 --- a/exception_test.c +++ /dev/null @@ -1,63 +0,0 @@ -#include "exclib.h" -#include - -void nullfunc(int *something) -{ - THROW_ZERO(something, EXC_NULLPOINTER, NULL); - printf("nullfunc got %d\n", *something); -} - -void badfunc(void) -{ - // This function represents a function that you think you can trust; but there's a null - // pointer being passed here that you have no control over. Thankfully 'nullfunc' was - // written to be safe, so it will illustrate the usefulness of TRY/CATCH/ETRY. - int *ptr = NULL; - nullfunc(ptr); -} - -void testfunc(void) -{ - THROW(34, "Random test exception"); -} - -int main(void) -{ - int x = 2; - - printf("Stack frames are %d bytes in size\n\n", sizeof(struct exc_status)); - - TRY { - fprintf(stdout, "Throwing %d\n", x); - THROW(2, "First exception"); - } CATCH(-1) { - printf("Caught -1\n"); - THROW(1, "1 Exception"); - } CATCH(1) { - printf("Caught 1\n"); - } CATCH(2) { - printf("Caught 2\n"); - TRY { - testfunc(); - } CATCH(34) { - printf("Caught 34!\n"); - printf("Throwing 34 Back Out\n"); - THROW(34, "Second-layer exception 34"); - } ETRY; - } CATCH(34) { - printf("Caught 34 in upper level!\n"); - printf("Using THROW_NONZERO\n"); - THROW_NONZERO(strcmp("a", "b"), 0, "String Compare Exception"); - } FINALLY { - exclib_print_exception_stack("In finally clause", __FILE__, (char *)__func__, __LINE__); - } ETRY; - - TRY { - badfunc(); - } ETRY; - - /*printf("\nThrowing an exception with no toplevel TRY block, which should stacktrace and kill us...\n\n"); - - THROW(34, "Bad Exception");*/ - return 0; -} diff --git a/exception_test_simple.c b/exception_test_simple.c deleted file mode 100644 index 768e824..0000000 --- a/exception_test_simple.c +++ /dev/null @@ -1,31 +0,0 @@ -#include "exclib.h" - -int main(void) -{ - EXCLIB_TRACE("No stack to print?"); - - TRY { - EXCLIB_TRACE("Inside TRY"); - THROW(3, NULL); - } CATCH(3) { - EXCLIB_TRACE("Caught 3"); - THROW(5, NULL); - } CATCH(5) { - EXCLIB_TRACE("Caught 5"); - TRY { - THROW(6, NULL); - } CATCH (6) { - EXCLIB_TRACE("Caught 6"); - THROW(7, NULL); - } ETRY; - } CATCH(7) { - EXCLIB_TRACE("Caught 7"); - } FINALLY { - EXCLIB_TRACE("In finally clause"); - } ETRY; - - EXCLIB_TRACE("Exiting program"); - - return 0; - -} diff --git a/exclib.h b/include/exclib.h similarity index 96% rename from exclib.h rename to include/exclib.h index b0d9f1d..d2fef23 100644 --- a/exclib.h +++ b/include/exclib.h @@ -2,14 +2,10 @@ #define __EXCLIB_H__ #include -#ifdef WIN32 -#include "backtrace.h" -#else -#include -#endif #include #include #include +#include #include /* @@ -134,12 +130,19 @@ __exc_curidx--; #define FINALLY \ }; \ -if ( EXC_STATUS_LIST->caught ) { +if ( EXC_STATUS_LIST && EXC_STATUS_LIST->caught ) { #define THROW_NONZERO(x, y, z) int rc = (x); if ( rc != 0 ) THROW(rc + y, z); #define THROW_ZERO(x, y, z) if ( (x) == 0 ) THROW(y, z); -#define THROW(x, y) exclib_prep_throw(x, y, __FILE__, (char *)__func__, __LINE__); if ( EXC_STATUS_LIST ) { longjmp(EXC_STATUS_LIST->buf, x); } else { exclib_print_exception_stack("Unhandled Exception "#x"", __FILE__, (char *)__func__, __LINE__); }; +#define THROW(x, y) \ +exclib_prep_throw(x, y, __FILE__, (char *)__func__, __LINE__); \ +if ( EXC_STATUS_LIST->value > 0 ) { \ + longjmp(EXC_STATUS_LIST->buf, x); \ +} else { \ + exclib_print_exception_stack("Uncaught Exception "#x"", __FILE__, (char *)__func__, __LINE__); \ + exit(x); \ +} #define EXCLIB_TRACE(x) exclib_print_exception_stack(x, __FILE__, (char *)__func__, __LINE__) diff --git a/exclib.c b/src/exclib.c similarity index 81% rename from exclib.c rename to src/exclib.c index 2264735..a63a5f7 100644 --- a/exclib.c +++ b/src/exclib.c @@ -40,7 +40,8 @@ void exclib_print_exception_stack(char *mbuf, char *file, char *func, int line) if ( ! cur ) fprintf(stderr, "EXCLIB: #0: No exception stack\n"); - while ( cur != NULL ) { + else { + while ( cur != NULL ) { memset((char *)&buf, 0, 256); memset((char *)&flagbuf, 0, 256); if ( cur->catching == 1) { @@ -77,6 +78,7 @@ void exclib_print_exception_stack(char *mbuf, char *file, char *func, int line) fprintf(stderr, "%s", (char *)&buf); idx += 1; cur = cur->prev; + } } } @@ -123,6 +125,7 @@ void exclib_prep_throw(int value, char *msg, char *file, char *func, int line) { char stbuf[256]; memset((char *)&stbuf, 0, 256); + if ( EXC_STATUS_LIST && EXC_STATUS_LIST->tried == 1) { sprintf((char *)&stbuf, "Tried to THROW %d but couldn't create new exception frame", value); if ( EXC_STATUS_LIST->catching == 1 && EXC_STATUS_LIST->prev ) { @@ -131,26 +134,21 @@ void exclib_prep_throw(int value, char *msg, char *file, char *func, int line) exit(value); } memcpy(EXC_STATUS_LIST->buf, EXC_STATUS_LIST->prev->buf, sizeof(jmp_buf)); - } /*else if ( EXC_STATUS_LIST->catching == 1 && (EXC_STATUS_LIST->prev == NULL) ) { - if ( exclib_new_exc_frame(&__exc_statuses[__exc_curidx++], file, func, line) ) { - exclib_print_exception_stack((char *)&stbuf, file, func, line); - exit(value); - } - EXCLIB_TRACE("Condition 2"); + } else if ( EXC_STATUS_LIST->catching == 1 && (EXC_STATUS_LIST->prev == NULL) ) { exclib_clear_exc_frame(); - __exc_curidx--; - } */ else { + return; + } else { if ( exclib_new_exc_frame(EXC_STATUS_LIST, file, func, line) ) exclib_print_exception_stack((char *)&stbuf, file, func, line); } EXC_STATUS_LIST->value = value; EXC_STATUS_LIST->name = __exc_names[value]; EXC_STATUS_LIST->description = msg; - } else { - sprintf((char *)&stbuf, "Tried to THROW Exception %d but had no exception context. (Called outside of TRY block, or thrown while TRY was setting up?)", value); - exclib_print_exception_stack((char *)&stbuf, file, func, line); - exit(__exc_signals[value]); + return; } + sprintf((char *)&stbuf, "Tried to THROW Exception %d but had no exception context. (Called outside of TRY block, or thrown while TRY was setting up?)", value); + exclib_print_exception_stack((char *)&stbuf, file, func, line); + exit(__exc_signals[value]); } @@ -189,7 +187,7 @@ int exclib_clear_exc_frame() exit(1); } if ( es->prev ) - es->prev->next = NULL; + es->prev->next = NULL; if ( es->value && !es->caught ) { // thrown exception was unhandled - do we have anywhere else to go? if ( !es->prev ) { @@ -198,23 +196,24 @@ int exclib_clear_exc_frame() exit(es->value); //kill(getpid(), SIGKILL); } else if ( es->tried && es->prev && (es->catching == 0)) { - // copy this exception up into the upper frame and siglongjmp back to that - EXC_STATUS_LIST = es->prev; - EXC_STATUS_LIST->caught = 0; - memcpy(&EXC_STATUS_LIST->bt_frames, &es->bt_frames, (sizeof(void *)*EXC_BT_FRAMES)); - EXC_STATUS_LIST->file = es->file; - EXC_STATUS_LIST->function = es->function; - EXC_STATUS_LIST->line = es->line; - EXC_STATUS_LIST->name = es->name; - EXC_STATUS_LIST->description = es->description; - THROW(es->value, es->description); + // copy this exception up into the upper frame and siglongjmp back to that + EXC_STATUS_LIST = es->prev; + EXC_STATUS_LIST->caught = 0; + memcpy(&EXC_STATUS_LIST->bt_frames, &es->bt_frames, (sizeof(void *)*EXC_BT_FRAMES)); + EXC_STATUS_LIST->file = es->file; + EXC_STATUS_LIST->function = es->function; + EXC_STATUS_LIST->line = es->line; + EXC_STATUS_LIST->name = es->name; + EXC_STATUS_LIST->description = es->description; + int val = es->value; + memset((void *)es, 0x00, sizeof(struct exc_status)); + THROW(val, EXC_STATUS_LIST->description); } } else { + if ( es->prev) { EXC_STATUS_LIST = es->prev; - es->value = 0; - es->caught = 0; - es->tried = 0; - es->catching = 0; + } + memset((void *)es, 0x00, sizeof(struct exc_status)); } }