diff --git a/lib/cb-impl.h b/lib/cb-impl.h index 68efa10..e07bcd1 100644 --- a/lib/cb-impl.h +++ b/lib/cb-impl.h @@ -194,6 +194,150 @@ static hcl_errnum_t syserrstrb (hcl_t* hcl, int syserr_type, int syserr_code, hc } +/* -------------------------------------------------------------------------- + * ASSERTION SUPPORT + * -------------------------------------------------------------------------- */ + +#if defined(HCL_BUILD_RELEASE) + +void assert_failed (hcl_t* hcl, const hcl_bch_t* expr, const hcl_bch_t* file, hcl_oow_t line) +{ + /* do nothing */ +} + +#else /* defined(HCL_BUILD_RELEASE) */ + +/* -------------------------------------------------------------------------- + * SYSTEM DEPENDENT HEADERS + * -------------------------------------------------------------------------- */ + +#if defined(_WIN32) +# include +# include +#elif defined(__OS2__) +# define INCL_DOSPROCESS +# define INCL_DOSFILEMGR +# define INCL_DOSERRORS +# include +#elif defined(__DOS__) +# include +# if defined(_INTELC32_) +# define DOS_EXIT 0x4C +# else +# include +# endif +# include +#elif defined(vms) || defined(__vms) +# define __NEW_STARLET 1 +# include /* (SYS$...) */ +# include /* (SS$...) */ +# include /* (lib$...) */ +#elif defined(macintosh) +# include +# include +# include +# include +#else +# include +# include +# include +# include +#endif + +#if defined(HCL_ENABLE_LIBUNWIND) +#include +static void backtrace_stack_frames (hcl_t* hcl) +{ + unw_cursor_t cursor; + unw_context_t context; + int n; + + unw_getcontext(&context); + unw_init_local(&cursor, &context); + + hcl_logbfmt (hcl, HCL_LOG_UNTYPED | HCL_LOG_DEBUG, "[BACKTRACE]\n"); + for (n = 0; unw_step(&cursor) > 0; n++) + { + unw_word_t ip, sp, off; + char symbol[256]; + + unw_get_reg (&cursor, UNW_REG_IP, &ip); + unw_get_reg (&cursor, UNW_REG_SP, &sp); + + if (unw_get_proc_name(&cursor, symbol, HCL_COUNTOF(symbol), &off)) + { + hcl_copy_bcstr (symbol, HCL_COUNTOF(symbol), ""); + } + + hcl_logbfmt (hcl, HCL_LOG_UNTYPED | HCL_LOG_DEBUG, + "#%02d ip=0x%*p sp=0x%*p %s+0x%zu\n", + n, HCL_SIZEOF(void*) * 2, (void*)ip, HCL_SIZEOF(void*) * 2, (void*)sp, symbol, (hcl_oow_t)off); + } +} +#elif defined(HAVE_BACKTRACE) +#include +static void backtrace_stack_frames (hcl_t* hcl) +{ + void* btarray[128]; + hcl_oow_t btsize; + char** btsyms; + + btsize = backtrace (btarray, HCL_COUNTOF(btarray)); + btsyms = backtrace_symbols (btarray, btsize); + if (btsyms) + { + hcl_oow_t i; + hcl_logbfmt (hcl, HCL_LOG_UNTYPED | HCL_LOG_DEBUG, "[BACKTRACE]\n"); + + for (i = 0; i < btsize; i++) + { + hcl_logbfmt(hcl, HCL_LOG_UNTYPED | HCL_LOG_DEBUG, " %s\n", btsyms[i]); + } + free (btsyms); + } +} +#else +static void backtrace_stack_frames (hcl_t* hcl) +{ + /* do nothing. not supported */ +} +#endif + +static void assert_failed (hcl_t* hcl, const hcl_bch_t* expr, const hcl_bch_t* file, hcl_oow_t line) +{ + hcl_logbfmt (hcl, HCL_LOG_UNTYPED | HCL_LOG_FATAL, "ASSERTION FAILURE: %s at %s:%zu\n", expr, file, line); + backtrace_stack_frames (hcl); + +#if defined(_WIN32) + ExitProcess (249); +#elif defined(__OS2__) + DosExit (EXIT_PROCESS, 249); +#elif defined(__DOS__) + { + union REGS regs; + regs.h.ah = DOS_EXIT; + regs.h.al = 249; + intdos (®s, ®s); + } +#elif defined(vms) || defined(__vms) + lib$stop (SS$_ABORT); /* use SS$_OPCCUS instead? */ + /* this won't be reached since lib$stop() terminates the process */ + sys$exit (SS$_ABORT); /* this condition code can be shown with + * 'show symbol $status' from the command-line. */ +#elif defined(macintosh) + + ExitToShell (); + +#else + + kill (getpid(), SIGABRT); + _exit (1); +#endif +} + +#endif /* defined(HCL_BUILD_RELEASE) */ + + /* ----------------------------------------------------------------- * HEAP ALLOCATION * ----------------------------------------------------------------- */ @@ -792,3 +936,5 @@ static void* dl_getsym (hcl_t* hcl, void* handle, const hcl_ooch_t* name) return HCL_NULL; #endif } + + diff --git a/lib/err.c b/lib/err.c index 35ea53f..8eb0357 100644 --- a/lib/err.c +++ b/lib/err.c @@ -324,149 +324,3 @@ void hcl_setsynerrufmt (hcl_t* hcl, hcl_synerrnum_t num, const hcl_ioloc_t* loc, } } -/* -------------------------------------------------------------------------- - * ASSERTION SUPPORT - * -------------------------------------------------------------------------- */ - -#if defined(HCL_BUILD_RELEASE) - -void hcl_assertfailed (hcl_t* hcl, const hcl_bch_t* expr, const hcl_bch_t* file, hcl_oow_t line) -{ - /* do nothing */ -} - -#else /* defined(HCL_BUILD_RELEASE) */ - -/* -------------------------------------------------------------------------- - * SYSTEM DEPENDENT HEADERS - * -------------------------------------------------------------------------- */ -#if defined(HCL_ENABLE_LIBUNWIND) -# include -#elif defined(HAVE_EXECINFO_H) -# include -# include -#endif - -#if defined(_WIN32) -# include -# include -#elif defined(__OS2__) -# define INCL_DOSPROCESS -# define INCL_DOSFILEMGR -# define INCL_DOSERRORS -# include -#elif defined(__DOS__) -# include -# if defined(_INTELC32_) -# define DOS_EXIT 0x4C -# else -# include -# endif -# include -#elif defined(vms) || defined(__vms) -# define __NEW_STARLET 1 -# include /* (SYS$...) */ -# include /* (SS$...) */ -# include /* (lib$...) */ -#elif defined(macintosh) -# include -# include -# include -# include -#else -# include -# include -# include -# include -#endif - -#if defined(HCL_ENABLE_LIBUNWIND) -static void backtrace_stack_frames (hcl_t* hcl) -{ - unw_cursor_t cursor; - unw_context_t context; - int n; - - unw_getcontext(&context); - unw_init_local(&cursor, &context); - - hcl_logbfmt (hcl, HCL_LOG_UNTYPED | HCL_LOG_DEBUG, "[BACKTRACE]\n"); - for (n = 0; unw_step(&cursor) > 0; n++) - { - unw_word_t ip, sp, off; - char symbol[256]; - - unw_get_reg (&cursor, UNW_REG_IP, &ip); - unw_get_reg (&cursor, UNW_REG_SP, &sp); - - if (unw_get_proc_name(&cursor, symbol, HCL_COUNTOF(symbol), &off)) - { - hcl_copy_bcstr (symbol, HCL_COUNTOF(symbol), ""); - } - - hcl_logbfmt (hcl, HCL_LOG_UNTYPED | HCL_LOG_DEBUG, - "#%02d ip=0x%*p sp=0x%*p %s+0x%zu\n", - n, HCL_SIZEOF(void*) * 2, (void*)ip, HCL_SIZEOF(void*) * 2, (void*)sp, symbol, (hcl_oow_t)off); - } -} -#elif defined(HAVE_BACKTRACE) -static void backtrace_stack_frames (hcl_t* hcl) -{ - void* btarray[128]; - hcl_oow_t btsize; - char** btsyms; - - btsize = backtrace (btarray, HCL_COUNTOF(btarray)); - btsyms = backtrace_symbols (btarray, btsize); - if (btsyms) - { - hcl_oow_t i; - hcl_logbfmt (hcl, HCL_LOG_UNTYPED | HCL_LOG_DEBUG, "[BACKTRACE]\n"); - - for (i = 0; i < btsize; i++) - { - hcl_logbfmt(hcl, HCL_LOG_UNTYPED | HCL_LOG_DEBUG, " %s\n", btsyms[i]); - } - free (btsyms); - } -} -#else -static void backtrace_stack_frames (hcl_t* hcl) -{ - /* do nothing. not supported */ -} -#endif - -void hcl_assertfailed (hcl_t* hcl, const hcl_bch_t* expr, const hcl_bch_t* file, hcl_oow_t line) -{ - hcl_logbfmt (hcl, HCL_LOG_UNTYPED | HCL_LOG_FATAL, "ASSERTION FAILURE: %s at %s:%zu\n", expr, file, line); - backtrace_stack_frames (hcl); - -#if defined(_WIN32) - ExitProcess (249); -#elif defined(__OS2__) - DosExit (EXIT_PROCESS, 249); -#elif defined(__DOS__) - { - union REGS regs; - regs.h.ah = DOS_EXIT; - regs.h.al = 249; - intdos (®s, ®s); - } -#elif defined(vms) || defined(__vms) - lib$stop (SS$_ABORT); /* use SS$_OPCCUS instead? */ - /* this won't be reached since lib$stop() terminates the process */ - sys$exit (SS$_ABORT); /* this condition code can be shown with - * 'show symbol $status' from the command-line. */ -#elif defined(macintosh) - - ExitToShell (); - -#else - - kill (getpid(), SIGABRT); - _exit (1); -#endif -} - -#endif /* defined(HCL_BUILD_RELEASE) */ diff --git a/lib/hcl-c.c b/lib/hcl-c.c index 75cf576..d4178a2 100644 --- a/lib/hcl-c.c +++ b/lib/hcl-c.c @@ -821,6 +821,7 @@ hcl_client_t* hcl_client_open (hcl_mmgr_t* mmgr, hcl_oow_t xtnsize, hcl_client_p HCL_MEMSET (&vmprim, 0, HCL_SIZEOF(vmprim)); vmprim.log_write = log_write_for_dummy; vmprim.syserrstrb = syserrstrb; + vmprim.assertfail = assert_fail; hcl = hcl_open(mmgr, HCL_SIZEOF(*xtn), 2048, &vmprim, errnum); if (!hcl) diff --git a/lib/hcl-s.c b/lib/hcl-s.c index 004d83f..13aae72 100644 --- a/lib/hcl-s.c +++ b/lib/hcl-s.c @@ -720,6 +720,7 @@ hcl_server_proto_t* hcl_server_proto_open (hcl_oow_t xtnsize, hcl_server_worker_ } vmprim.log_write = log_write; vmprim.syserrstrb = syserrstrb; + vmprim.assertfail = assert_fail; vmprim.dl_open = dl_open; vmprim.dl_close = dl_close; vmprim.dl_getsym = dl_getsym; diff --git a/lib/hcl.h b/lib/hcl.h index 6d674a9..5f2154d 100644 --- a/lib/hcl.h +++ b/lib/hcl.h @@ -830,6 +830,13 @@ typedef hcl_errnum_t (*hcl_syserrstru_t) ( hcl_oow_t len ); +typedef void (*hcl_assertfail_t) ( + hcl_t* hcl, + const hcl_bch_t* expr, + const hcl_bch_t* file, + hcl_oow_t line +); + enum hcl_vmprim_dlopen_flag_t { HCL_VMPRIM_DLOPEN_PFMOD = (1 << 0) @@ -879,6 +886,7 @@ struct hcl_vmprim_t hcl_log_write_t log_write; /* required */ hcl_syserrstrb_t syserrstrb; /* one of syserrstrb or syserrstru required */ hcl_syserrstru_t syserrstru; + hcl_assertfail_t assertfail; hcl_vmprim_dlopen_t dl_open; /* required */ hcl_vmprim_dlclose_t dl_close; /* required */ @@ -1359,7 +1367,7 @@ struct hcl_t #if defined(HCL_BUILD_RELEASE) # define HCL_ASSERT(hcl,expr) ((void)0) #else -# define HCL_ASSERT(hcl,expr) ((void)((expr) || (hcl_assertfailed (hcl, #expr, __FILE__, __LINE__), 0))) +# define HCL_ASSERT(hcl,expr) ((void)((expr) || ((hcl)->vmprim.assertfail (hcl, #expr, __FILE__, __LINE__), 0))) #endif /* ========================================================================= diff --git a/lib/json.c b/lib/json.c index 2f6618b..bd49e3a 100644 --- a/lib/json.c +++ b/lib/json.c @@ -910,6 +910,7 @@ hcl_json_t* hcl_json_open (hcl_mmgr_t* mmgr, hcl_oow_t xtnsize, hcl_json_prim_t* HCL_MEMSET (&vmprim, 0, HCL_SIZEOF(vmprim)); vmprim.log_write = log_write_for_dummy; vmprim.syserrstrb = syserrstrb; + vmprim.assertfail = assert_fail; hcl = hcl_open(mmgr, HCL_SIZEOF(*xtn), 2048, &vmprim, errnum); if (!hcl) diff --git a/lib/main.c b/lib/main.c index 15ceaa2..461bb37 100644 --- a/lib/main.c +++ b/lib/main.c @@ -1193,6 +1193,7 @@ int main (int argc, char* argv[]) } vmprim.log_write = log_write; vmprim.syserrstrb = syserrstrb; + vmprim.assertfail = assert_fail; vmprim.dl_open = dl_open; vmprim.dl_close = dl_close; vmprim.dl_getsym = dl_getsym;