Click here to Skip to main content
15,883,901 members
Articles / Mobile Apps / Windows Mobile

Code that debugs itself

Rate me:
Please Sign up or sign in to vote.
4.78/5 (74 votes)
17 Feb 200534 min read 311.4K   5K   184  
A set of macros for detecting and reporting critical errors, combined with a technique of writing solid code.
/////////////////////////////////////////////////////////////////////////////////
//
//  QAFDebug critical error log
//
//  Copyright (c) 2000-2004
//  Andrew Schetinin
//
//  This software is provided "as is" without express or implied warranty, 
//  and with no claim as to its suitability for any purpose.
//
//  Permission to use or copy this software for any purpose is hereby granted 
//  without fee, provided the above notices are retained on all copies.
//  Permission to modify the code and to distribute modified code is granted,
//  provided the above notices are retained, and a notice that the code was
//  modified is included with the above copyright notice.
//
//  This software accompanies the article "Code that debugs itself"
//  located at http://www.codeproject.com/debug/qafdebug.asp
//
//  You are welcomed to report bugs, send comments and post code modifications 
//  to aschetinin@hotmail.com 
//
/////////////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////
/// @file QSockErr.h
/// @brief Part of QAFDebug facility for reporting WinSock errors.
//////////////////////////////////////////////////////////////////////////

#ifndef _QSOCKERR_29347284234_H_
#define _QSOCKERR_29347284234_H_

// The error constants are taken from WinSock2.h but I think they are 
// similar to ones defined in WinSock.h. 
// Errors are usually returned by WSAGetLastError()
#ifdef _WINSOCKAPI_

#include <string>

#include "QAFDebug.h"

/// Macro that reports about a socket error if it happens, 
/// it reports also about the source code position.
/// The macro returns the same error code that it got as input.
#ifndef QAF_DISABLED
	#define Q_SOCKET_ERROR( iSocketError ) QAFDebug::ReportSocketErrorImpl( (iSocketError), _T(__FILE__), __LINE__ )
#else 
	#define Q_SOCKET_ERROR( iSocketError ) (iSocketError)
#endif

// namespace QAFDebug
namespace QAFDebug
{

/// Returns the error message by the error code.
/// An empty string is returned in case no error occured.
#ifdef _UNICODE
inline int GetSocketErrorMessage( const int iSocketError, std::wstring & szRet )
#else
inline int GetSocketErrorMessage( const int iSocketError, std::string & szRet )
#endif
{
	szRet = _T(""); // empty the result string
	if( 0 == iSocketError )
		return iSocketError;
	switch( iSocketError )
	{
		case WSAEINTR:
			szRet = ( _T("WSAEINTR: Interrupted function call") );
			break;
		case WSAEACCES:
			szRet = ( _T("WSAEACCES: Permission denied") );
			break;
		case WSAEFAULT:
			szRet = ( _T("WSAEFAULT: Invalid pointer address") );
			break;
		case WSAEINVAL:
			szRet = ( _T("WSAEINVAL: Invalid argument") );
			break;
		case WSAEMFILE:
			szRet = ( _T("WSAEMFILE: Too many open sockets") );
			break;
		case WSAEWOULDBLOCK:
			szRet = ( _T("WSAEWOULDBLOCK: Resource temporarily unavailable") );
			break;
		case WSAEINPROGRESS:
			szRet = ( _T("WSAEINPROGRESS: Operation now in progress") );
			break;
		case WSAEALREADY:
			szRet = ( _T("WSAEALREADY: Operation already in progress") );
			break;
		case WSAENOTSOCK:
			szRet = ( _T("WSAENOTSOCK: Socket operation on nonsocket") );
			break;
		case WSAEDESTADDRREQ:
			szRet = ( _T("WSAEDESTADDRREQ: Destination address required") );
			break;
		case WSAEMSGSIZE:
			szRet = ( _T("WSAEMSGSIZE: Message too long") );
			break;
		case WSAEPROTOTYPE:
			szRet = ( _T("WSAEPROTOTYPE: Protocol wrong type for socket") );
			break;
		case WSAENOPROTOOPT:
			szRet = ( _T("WSAENOPROTOOPT: Bad protocol option") );
			break;
		case WSAEPROTONOSUPPORT:
			szRet = ( _T("WSAEPROTONOSUPPORT: Protocol not supported") );
			break;
		case WSAESOCKTNOSUPPORT:
			szRet = ( _T("WSAESOCKTNOSUPPORT: Socket type not supported") );
			break;
		case WSAEOPNOTSUPP:
			szRet = ( _T("WSAEOPNOTSUPP: Operation not supported") );
			break;
		case WSAEPFNOSUPPORT:
			szRet = ( _T("WSAEPFNOSUPPORT: Protocol family not supported") );
			break;
		case WSAEAFNOSUPPORT:
			szRet = ( _T("WSAEAFNOSUPPORT: Address family not supported by protocol family") );
			break;
		case WSAEADDRINUSE:
			szRet = ( _T("WSAEADDRINUSE: Address already in use") );
			break;
		case WSAEADDRNOTAVAIL:
			szRet = ( _T("WSAEADDRNOTAVAIL: Cannot assign requested address") );
			break;
		case WSAENETDOWN:
			szRet = ( _T("WSAENETDOWN: Network is down") );
			break;
		case WSAENETUNREACH:
			szRet = ( _T("WSAENETUNREACH: Network is unreachable") );
			break;
		case WSAENETRESET:
			szRet = ( _T("WSAENETRESET: Network dropped connection on reset") );
			break;
		case WSAECONNABORTED:
			szRet = ( _T("WSAECONNABORTED: Software caused connection abort") );
			break;
		case WSAECONNRESET:
			szRet = ( _T("WSAECONNRESET: Connection reset by peer") );
			break;
		case WSAENOBUFS:
			szRet = ( _T("WSAENOBUFS: No buffer space available") );
			break;
		case WSAEISCONN:
			szRet = ( _T("WSAEISCONN: Socket is already connected") );
			break;
		case WSAENOTCONN:
			szRet = ( _T("WSAENOTCONN: Socket is not connected") );
			break;
		case WSAESHUTDOWN:
			szRet = ( _T("WSAESHUTDOWN: Cannot send after socket shutdown") );
			break;
		case WSAETIMEDOUT:
			szRet = ( _T("WSAETIMEDOUT: Connection timed out") );
			break;
		case WSAECONNREFUSED:
			szRet = ( _T("WSAECONNREFUSED: Connection refused") );
			break;
		case WSAEHOSTDOWN:
			szRet = ( _T("WSAEHOSTDOWN: Host is down") );
			break;
		case WSAEHOSTUNREACH:
			szRet = ( _T("WSAEHOSTUNREACH: No route to host") );
			break;
		case WSAEPROCLIM:
			szRet = ( _T("WSAEPROCLIM: Too many processes") );
			break;
		case WSASYSNOTREADY:
			szRet = ( _T("WSASYSNOTREADY: Network subsystem is unavailable") );
			break;
		case WSAVERNOTSUPPORTED:
			szRet = ( _T("WSAVERNOTSUPPORTED: Winsock.dll version out of range") );
			break;
		case WSANOTINITIALISED:
			szRet = ( _T("WSANOTINITIALISED: Successful WSAStartup not yet performed") );
			break;
		case WSAEDISCON:
			szRet = ( _T("WSAEDISCON: Graceful shutdown in progress") );
			break;
		case WSATYPE_NOT_FOUND:
			szRet = ( _T("WSATYPE_NOT_FOUND: Class type not found") );
			break;
		case WSAHOST_NOT_FOUND:
			szRet = ( _T("WSAHOST_NOT_FOUND: Host not found") );
			break;
		case WSATRY_AGAIN:
			szRet = ( _T("WSATRY_AGAIN: Nonauthoritative host not found") );
			break;
		case WSANO_RECOVERY:
			szRet = ( _T("WSANO_RECOVERY: This is a nonrecoverable error") );
			break;
		case WSANO_DATA:
			szRet = ( _T("WSANO_DATA: Valid name, no data record of requested type") );
			break;
		case WSA_INVALID_HANDLE:
			szRet = ( _T("WSA_INVALID_HANDLE: Specified event object handle is invalid") );
			break;
		case WSA_INVALID_PARAMETER:
			szRet = ( _T("WSA_INVALID_PARAMETER: One or more parameters are invalid") );
			break;
		case WSA_IO_INCOMPLETE:
			szRet = ( _T("WSA_IO_INCOMPLETE: Overlapped I/O event object not in signaled state") );
			break;
		case WSA_IO_PENDING:
			szRet = ( _T("WSA_IO_PENDING: Overlapped operations will complete later") );
			break;
		case WSA_NOT_ENOUGH_MEMORY:
			szRet = ( _T("WSA_NOT_ENOUGH_MEMORY: Insufficient memory available") );
			break;
		case WSA_OPERATION_ABORTED:
			szRet = ( _T("WSA_OPERATION_ABORTED: Overlapped operation aborted") );
			break;
		/* Not defined even in .NET SDK
		case WSAINVALIDPROCTABLE:
			szRet = ( _T("WSAINVALIDPROCTABLE: Invalid procedure table from service provider") );
			break;
		case WSAINVALIDPROVIDER:
			szRet = ( _T("WSAINVALIDPROVIDER: Invalid service provider version number") );
			break;
		case WSAPROVIDERFAILEDINIT:
			szRet = ( _T("WSAPROVIDERFAILEDINIT: Unable to initialize a service provider") );
			break;
		*/
		case WSASYSCALLFAILURE:
			szRet = ( _T("WSASYSCALLFAILURE: System call failure") );
			break;
		default:
			TCHAR szBuf[40] = { 0 };
			_stprintf( szBuf, _T("%d: Unspecified socket error") );
			szRet = ( szBuf );
			break;
	}
	return iSocketError;
}

/// Returns the error message by the error code.
/// An empty string is returned in case no error occured.
#ifdef _UNICODE
inline std::wstring GetSocketErrorMessage( const int iSocketError )
#else
inline std::string GetSocketErrorMessage( const int iSocketError )
#endif
{
#ifdef _UNICODE
	std::wstring szError;
#else
	std::string szError;
#endif
	GetSocketErrorMessage( iSocketError, szError );
	if( szError.empty() )
		szError = _T("No error");
	return szError;
}

/// Internal function that report about socket error if it happens,
/// it reports also about the source code position.
/// The function returns the same error code that it got as input.
inline int ReportSocketErrorImpl( const int iSocketError, LPCTSTR const szFile, const int iLine )
{
	if( 0 == iSocketError )
		return 0;
#ifdef _UNICODE
	std::wstring szError;
#else
	std::string szError;
#endif
	// this call itself must return an error code
	Q_ASSERT( 0 != GetSocketErrorMessage( iSocketError, szError ) );
	Q_ASSERT( !szError.empty() );
	// report the error
	QAFDebug::OutputDebugStringEx( szFile, iLine, QAFDEBUG_ERROR_LOG, szError.c_str() );
	return iSocketError;
}

// namespace QAFDebug
};

#endif


#endif 

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Team Leader OpTier
Israel Israel
Programming computers since entering the university in 1992, but dreaming of programming long time before putting hands on my first computer.

Experienced in cross-platform software development using C++ and Java, as well as rapid GUI development using Delphi/C#. Strong background in networking, relational databases, Web development, and mobile platforms.

Like playing guitar, visiting historical sites (not in the Internet, in the car Smile | :) ) and cooking meat with friends (sorry about vegetarians). Look for more information on www.schetinin.com

Comments and Discussions