interim commit while adding vmprim.assertfail
This commit is contained in:
		
							
								
								
									
										146
									
								
								lib/cb-impl.h
									
									
									
									
									
								
							
							
						
						
									
										146
									
								
								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 <windows.h>
 | 
			
		||||
#	include <errno.h>
 | 
			
		||||
#elif defined(__OS2__)
 | 
			
		||||
#	define INCL_DOSPROCESS
 | 
			
		||||
#	define INCL_DOSFILEMGR
 | 
			
		||||
#	define INCL_DOSERRORS
 | 
			
		||||
#	include <os2.h>
 | 
			
		||||
#elif defined(__DOS__)
 | 
			
		||||
#	include <dos.h>
 | 
			
		||||
#	if defined(_INTELC32_)
 | 
			
		||||
#		define DOS_EXIT 0x4C
 | 
			
		||||
#	else
 | 
			
		||||
#		include <dosfunc.h>
 | 
			
		||||
#	endif
 | 
			
		||||
#	include <errno.h>
 | 
			
		||||
#elif defined(vms) || defined(__vms)
 | 
			
		||||
#	define __NEW_STARLET 1
 | 
			
		||||
#	include <starlet.h> /* (SYS$...) */
 | 
			
		||||
#	include <ssdef.h> /* (SS$...) */
 | 
			
		||||
#	include <lib$routines.h> /* (lib$...) */
 | 
			
		||||
#elif defined(macintosh)
 | 
			
		||||
#	include <MacErrors.h>
 | 
			
		||||
#	include <Process.h>
 | 
			
		||||
#	include <Dialogs.h>
 | 
			
		||||
#	include <TextUtils.h>
 | 
			
		||||
#else
 | 
			
		||||
#	include <sys/types.h>
 | 
			
		||||
#	include <unistd.h>
 | 
			
		||||
#	include <signal.h>
 | 
			
		||||
#	include <errno.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if defined(HCL_ENABLE_LIBUNWIND)
 | 
			
		||||
#include <libunwind.h>
 | 
			
		||||
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), "<unknown>");
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		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 <execinfo.h>
 | 
			
		||||
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
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										146
									
								
								lib/err.c
									
									
									
									
									
								
							
							
						
						
									
										146
									
								
								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 <libunwind.h>
 | 
			
		||||
#elif defined(HAVE_EXECINFO_H)
 | 
			
		||||
#	include <execinfo.h>
 | 
			
		||||
#	include <stdlib.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if defined(_WIN32)
 | 
			
		||||
#	include <windows.h>
 | 
			
		||||
#	include <errno.h>
 | 
			
		||||
#elif defined(__OS2__)
 | 
			
		||||
#	define INCL_DOSPROCESS
 | 
			
		||||
#	define INCL_DOSFILEMGR
 | 
			
		||||
#	define INCL_DOSERRORS
 | 
			
		||||
#	include <os2.h>
 | 
			
		||||
#elif defined(__DOS__)
 | 
			
		||||
#	include <dos.h>
 | 
			
		||||
#	if defined(_INTELC32_)
 | 
			
		||||
#		define DOS_EXIT 0x4C
 | 
			
		||||
#	else
 | 
			
		||||
#		include <dosfunc.h>
 | 
			
		||||
#	endif
 | 
			
		||||
#	include <errno.h>
 | 
			
		||||
#elif defined(vms) || defined(__vms)
 | 
			
		||||
#	define __NEW_STARLET 1
 | 
			
		||||
#	include <starlet.h> /* (SYS$...) */
 | 
			
		||||
#	include <ssdef.h> /* (SS$...) */
 | 
			
		||||
#	include <lib$routines.h> /* (lib$...) */
 | 
			
		||||
#elif defined(macintosh)
 | 
			
		||||
#	include <MacErrors.h>
 | 
			
		||||
#	include <Process.h>
 | 
			
		||||
#	include <Dialogs.h>
 | 
			
		||||
#	include <TextUtils.h>
 | 
			
		||||
#else
 | 
			
		||||
#	include <sys/types.h>
 | 
			
		||||
#	include <unistd.h>
 | 
			
		||||
#	include <signal.h>
 | 
			
		||||
#	include <errno.h>
 | 
			
		||||
#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), "<unknown>");
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		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) */
 | 
			
		||||
 | 
			
		||||
@ -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) 
 | 
			
		||||
 | 
			
		||||
@ -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;
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										10
									
								
								lib/hcl.h
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								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
 | 
			
		||||
 | 
			
		||||
/* =========================================================================
 | 
			
		||||
 | 
			
		||||
@ -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) 
 | 
			
		||||
 | 
			
		||||
@ -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;
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user