This section of the archives stores flipcode's complete Developer Toolbox collection, featuring a variety of mini-articles and source code contributions from our readers.

| Function Guarding Submitted by

this is another technic of error/exception handling. It uses the exception mechanism to report the function calling stack for easier reconstruction where the exception comes from. I've extracted it from my current project and rewrote some parts so it can be compiled. It's completely free, so use it in your project if you want, but some credits will be nice :) Hope it's usefull for someone... chris

Currently browsing [funcguarding.zip] (2,506 bytes) - [ErrHandler.h] - (938 bytes)

    // Copyright (C) 2002 Christian Weis

    #pragma once

    // guards func
    #define GUARD(FUNC) \
    		{ \
    			static const char* const __pfunc__ = #FUNC; \
    			try \
    			{ \

    // unguard func
    #define UNGUARD \
    			} \
    			catch (const char *pe) \
    			{ \
    				apiHandleErr (pe, __pfunc__); \
    				THROW (0) \
    			} \
    			catch (...) \
    			{ \
    				apiHandleErr ("Unexpected Exception!", __pfunc__); \
    				THROW (0) \
    			} \
    		} \

    // throws err msg
    #define THROW(MSG) {throw (const char*) (MSG);}

    // protected code
    #define PROTECTED(CODE) {try {CODE} catch (...) {}}

    // func guarding in time critical funcs
    #ifdef _DEBUG
    #define GUARD_FAST(FUNC) GUARD (FUNC)
    #define UNGUARD_FAST UNGUARD
    #else
    #define GUARD_FAST(FUNC) {
    #define UNGUARD_FAST }
    #endif

    // err handler api
    extern void apiHandleErr (const char *pe, const char *pfunc);
    extern void apiShowErr (const char *pcap = 0);
    extern void apiDisableErrHandler ();

Currently browsing [funcguarding.zip] (2,506 bytes) - [Example.cpp] - (1,806 bytes)

    // Copyright (C) 2002 Christian Weis
    //
    // this is just an example of demonstrating the working
    // of function guarding and how to use it in your projects.
    //
    // i use MS VC++ 6.0 and it works fine :)
    //
    // you may get some warnings that some code is unreachable or something else.
    // you can simply disable it with:
    // #pragma warning (disable: 4702) // unreachable source code

    // own includes
    #include "ErrHandler.h"

    // compiler includes
    #define WIN32_LEAN_AND_MEAN
    #define VC_EXTRALEAN
    #define WIN32_EXTRALEAN

    #include <windows.h>
    #include <windowsx.h>

    // a time critical func :)
    static unsigned TimeCriticalFunc (unsigned a)
    	GUARD_FAST (TimeCriticalFunc)
    	return 12 / a;
    	UNGUARD_FAST

    // does anything
    static bool DoAnyInitHere ()
    	GUARD (DoAnyInitHere)

    	// ...

    	THROW ("Damn thing!")

    	// ...

    	return false;
    	UNGUARD

    // inits app
    void AppInit ()
    	GUARD (AppInit)

    	// ...

    	if (!DoAnyInitHere ())
    		THROW ("Init failed!")

    	// ...

    	UNGUARD

    // uninits app
    void AppUninit ()
    	GUARD (AppUninit)

    	// ...

    	THROW ("Uninit failed badly!")

    	// ...

    	UNGUARD

    // runs app
    void AppRun ()
    	GUARD (AppRun)

    	// ...

    	// call this one
    	int a = TimeCriticalFunc (0);
    	a;

    	// ...

    	UNGUARD

    // app cleanup after err
    void AppErr ()
    	GUARD (AppErr)

    	// ...

    	THROW ("Ops!")

    	// ...

    	UNGUARD

    // enter app
    int WINAPI WinMain (HINSTANCE, HINSTANCE, LPSTR, int)
    {
    	// this try/catch construct is needed here
    	try
    	{
    		GUARD (WinMain)

    		// call app
    		AppInit ();
    		AppRun ();
    		AppUninit ();

    		UNGUARD
    	}

    	catch (...)
    	// exception handling
    	{
    		PROTECTED (apiDisableErrHandler ();)
    		PROTECTED (AppErr ();)
    		PROTECTED (apiShowErr ();)
    		PROTECTED (AppUninit ();)
    	}

    	return 0;
    }

Currently browsing [funcguarding.zip] (2,506 bytes) - [ErrHandler.cpp] - (1,453 bytes)

    // Copyright (C) 2002 Christian Weis

    // own includes
    #include "ErrHandler.h"

    // compiler includes
    #define WIN32_LEAN_AND_MEAN
    #define VC_EXTRALEAN
    #define WIN32_EXTRALEAN

    #include <windows.h>
    #include <windowsx.h>
    #include <string.h>

    // history init string
    #define STR_HISTORY "Exception History: "

    enum {HISTORY = 1 << 10}; // history zstring len

    // history zstring
    static char history [HISTORY] = STR_HISTORY;
    static bool disabled = 0;
    static bool first_func = !0;

    // disables err handling
    void apiDisableErrHandler () {PROTECTED (disabled = !0;)}

    // handles any exception with func call stack
    void apiHandleErr (const char *pe, const char *pfunc)
    {
    	PROTECTED
    	(
    		if (!disabled)
    		{
    			if (pe && *pe)
    			// add exception
    			{
    				strncat (history, pe, HISTORY);
    				strncat (history, "\n\n", HISTORY);
    			}

    			if (pfunc && *pfunc)
    			// add func
    			{
    				if (!first_func) strncat (history, " -> ", HISTORY);
    				strncat (history, pfunc, HISTORY);
    				first_func = 0;
    			}
    		}
    	)
    }

    // shows err and func call stack
    void apiShowErr (const char *pcap)
    {
    	PROTECTED
    	(
    		PROTECTED (OutputDebugString (history);)
    		PROTECTED
    		(
    			const char *pc = pcap && *pcap ? pcap : "Exception detected";
    			MessageBox (0, history, pc, MB_OK | MB_ICONERROR | MB_TASKMODAL);
    		)

    		// re-init err handler
    		strncpy (history, STR_HISTORY, HISTORY);
    		disabled = 0;
    		first_func = !0;
    	)
    }

The zip file viewer built into the Developer Toolbox made use of the zlib library, as well as the zlibdll source additions.

Copyright 1999-2008 (C) FLIPCODE.COM and/or the original content author(s). All rights reserved.
Please read our Terms, Conditions, and Privacy information.