Jump to content
  • Advertisement
Sign in to follow this  
transformation

stack trace giving problems. (switch from msvc 02 to 03 did it)

This topic is 4770 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I got this stack trace function from a book actually - game coding complete. And that guy got it from msdn. The link he gives to the article dosent work anymore. But anyway, it was working fine when i had msvc 2002. I installed msvc 2003 and now it dosent trace the stack anymore. It just gives the name of the last function called (which is the stack trace function). Now I really have no idea where to look, because I didn't write the code myself and I'm hoping maybe someone else had the same problem and knows what's up. here's the stack tracing code incase it makes any difference, all Im asking for is guidance though.

#include "stack_trace.h"
#include <imagehlp.h>

/*	Stack Tracing
	
	The stack tracing code is based on an article by John Robbins from Microsoft Systems 
    Journal Bugslayer Column - Feb 99

	http://www.microsoft.com/msj/defaultframe.asp?page=/msj/0299/bugslayer/bugslayer0299.htm

*/

#ifdef _DEBUG

// The address typedef.
typedef std::vector<nx::uint32> ADDRESS_VECTOR;

// The current process handle
static HANDLE g_hProcess = 0;


static nx::ptrsize_t __stdcall GetModBase( HANDLE hProcess, nx::ptrsize_t dwAddr )
{
    IMAGEHLP_MODULE imageHelp ;
    imageHelp.SizeOfStruct = sizeof( IMAGEHLP_MODULE );

    if( SymGetModuleInfo(g_hProcess, dwAddr, &imageHelp ) )
    {
        return( imageHelp.BaseOfImage );
    }
    else
    {
        MEMORY_BASIC_INFORMATION memoryBasicInfo;

        if( 0 != VirtualQueryEx(hProcess,
								(LPCVOID)dwAddr,
								&memoryBasicInfo,
								sizeof( memoryBasicInfo )  ) )
        {
            nx::uint32 dwNameLen = 0 ;
            char szFile[ MAX_PATH ];

            dwNameLen = GetModuleFileName((HINSTANCE)
                                            memoryBasicInfo.AllocationBase,
                                            szFile,
                                            MAX_PATH );

            HANDLE hFile = NULL ;

            if( 0 != dwNameLen )
            {
                hFile = CreateFile( szFile,
                                     GENERIC_READ,
                                     FILE_SHARE_READ,
                                     NULL,
                                     OPEN_EXISTING,
                                     0,
                                     0 );
            }

            SymLoadModule( g_hProcess, hFile,
                           ( dwNameLen ? szFile : NULL ),
                           NULL,
                           (nx::ptrsize_t)memoryBasicInfo.AllocationBase,
                           0 );

            return ((nx::ptrsize_t)memoryBasicInfo.AllocationBase);
        }
    }
    return( 0 );
}

static nx::ptrsize_t ConvertAddress( nx::uint32 dwAddr, LPTSTR szOutBuff )
{
    char szTemp [ MAX_PATH + sizeof( IMAGEHLP_SYMBOL ) ];

    PIMAGEHLP_SYMBOL pIHSymbol =(PIMAGEHLP_SYMBOL)&szTemp ;

    IMAGEHLP_MODULE imageHelp ;

    LPTSTR pCurrPos = szOutBuff ;

    ZeroMemory( pIHSymbol, MAX_PATH + sizeof( IMAGEHLP_SYMBOL ) );
    ZeroMemory( &imageHelp, sizeof( IMAGEHLP_MODULE ) );

    pIHSymbol->SizeOfStruct = sizeof( IMAGEHLP_SYMBOL );
    pIHSymbol->Address = dwAddr ;
    pIHSymbol->MaxNameLength = MAX_PATH ;

    imageHelp.SizeOfStruct = sizeof( IMAGEHLP_MODULE );

    // Always stick the address in first.
    pCurrPos += wsprintf( pCurrPos, "0x%08X ", dwAddr );

    // Get the module name.
    if( 0 != SymGetModuleInfo( g_hProcess, dwAddr, &imageHelp ) )
    {
        // Strip off the path.
        LPTSTR szName = strrchr( imageHelp.ImageName, '\\' );
        if( NULL != szName )
        {
            szName++;
        }
        else
        {
            szName = imageHelp.ImageName ;
        }
        pCurrPos += wsprintf( pCurrPos, "%s: ", szName );
    }
    else
    {
        pCurrPos += wsprintf( pCurrPos, "<unknown module>: " );
    }

    // Get the function.
    nx::uint32 dwDisp ;
    if( 0 != SymGetSymFromAddr( g_hProcess, dwAddr, &dwDisp, pIHSymbol ) )
    {
        if( 0 == dwDisp )
        {
            pCurrPos += wsprintf( pCurrPos, "%s", pIHSymbol->Name);
        }
        else
        {
            pCurrPos += wsprintf( pCurrPos,
                                  "%s + %d bytes",
                                  pIHSymbol->Name,
                                  dwDisp );
        }

        // If I got a symbol, give the source and line a whirl.
        IMAGEHLP_LINE stIHL ;

        ZeroMemory( &stIHL, sizeof( IMAGEHLP_LINE ) );

        stIHL.SizeOfStruct = sizeof( IMAGEHLP_LINE );

        if( 0 != SymGetLineFromAddr( g_hProcess, dwAddr,
                                     &dwDisp,
                                     &stIHL ) )
        {
            // Put this on the next line and indented a bit.
            pCurrPos += wsprintf( pCurrPos,
                                  "\n\t\t%s, Line %d",
                                  stIHL.FileName,
                                  stIHL.LineNumber );
            if( 0 != dwDisp )
            {
                pCurrPos += wsprintf( pCurrPos,
                                       " + %d bytes",
                                       dwDisp );
            }
        }
    }
    else
    {
        pCurrPos += wsprintf( pCurrPos, "<unknown symbol>" );
    }

    // Tack on a CRLF.
    pCurrPos += wsprintf( pCurrPos, "\n" );

    return nx::ptrsize_t( pCurrPos - szOutBuff );
}

#endif

namespace nx {
namespace sys {


void BuildStackTrace( char* szString,
                          uint32  dwSize,
                          uint32  dwNumSkip  )
{
#ifdef _DEBUG
    HANDLE hProcess = GetCurrentProcess( );

    // if the symbol handler is not initialized, 
	// set it up now.
    if( !g_hProcess && SymInitialize(hProcess, NULL, FALSE))
    {
        uint32 dwOpts = SymGetOptions( );

        // Turn on load lines.
        SymSetOptions( dwOpts|SYMOPT_LOAD_LINES );

		g_hProcess = hProcess;
    }

    ADDRESS_VECTOR vAddrs;
    CONTEXT context;

    context.ContextFlags = CONTEXT_FULL ;

    if( GetThreadContext( GetCurrentThread( ), &context ) )
    {
        STACKFRAME stackFrame ;
        uint32      dwMachine ;

        ZeroMemory( &stackFrame, sizeof( STACKFRAME ) );

        stackFrame.AddrPC.Mode = AddrModeFlat ;

        dwMachine                = IMAGE_FILE_MACHINE_I386 ;
        stackFrame.AddrPC.Offset    = context.Eip   ;
        stackFrame.AddrStack.Offset = context.Esp   ;
        stackFrame.AddrStack.Mode   = AddrModeFlat ;
        stackFrame.AddrFrame.Offset = context.Ebp   ;
        stackFrame.AddrFrame.Mode   = AddrModeFlat ;

        // Loop for the first 512 stack elements.
        for( uint32 i = 0 ; i < 512 ; i++ )
        {
            
            if( FALSE == StackWalk( dwMachine,
                                    hProcess,
                                    hProcess,
                                    &stackFrame,
                                    &context,
                                    NULL,
                                    SymFunctionTableAccess,
                                    (PGET_MODULE_BASE_ROUTINE)GetModBase,
                                    NULL ) )
            {
                break ;
            }
            if( i > dwNumSkip )
            {
                // Also check that the address is not zero.  Sometimes
                //  StackWalk returns TRUE with a frame of zero.
                if( 0 != stackFrame.AddrPC.Offset )
                {
                    vAddrs.push_back( stackFrame.AddrPC.Offset );
                }
            }
        }

        // Now start converting the addresses.
        uint32 dwSizeLeft = dwSize ;
        uint32 dwSymSize ;

        TCHAR szSym [ MAX_PATH * 2 ];
        LPTSTR szCurrPos = szString ;

        ADDRESS_VECTOR::iterator loop ;
        for( loop =  vAddrs.begin( );
              loop != vAddrs.end( )  ;
              loop++                     )
        {

            dwSymSize = ConvertAddress( *loop, szSym );
            if( dwSizeLeft < dwSymSize )
            {
                break ;
            }
            strcpy( szCurrPos, szSym );
            szCurrPos += dwSymSize ;
            dwSizeLeft -= dwSymSize ;
        }
    }
#else
    szString[0] = 0;
#endif
}

} // ns sys
} // ns nx

Share this post


Link to post
Share on other sites
Advertisement
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!