mirror of
https://foundry.openuru.org/gitblit/r/CWE-ou-minkata.git
synced 2025-07-14 14:37:41 +00:00
Fix line endings and tabs
This commit is contained in:
@ -1,215 +1,215 @@
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
#include "pfStackTrace.h"
|
||||
#include "pfMapFile.h"
|
||||
#include "pfMapFileEntry.h"
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#pragma optimize( "y", off )
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#define MAX_DEPTH 32
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
namespace dev
|
||||
{
|
||||
|
||||
static long getCallerFromStack( unsigned long stackPtr, int index )
|
||||
{
|
||||
#if /*defined(_DEBUG) && */defined(_MSC_VER) && defined(_M_IX86)
|
||||
|
||||
long caller = 0;
|
||||
__asm
|
||||
{
|
||||
mov ebx, stackPtr
|
||||
mov ecx, index
|
||||
inc ecx
|
||||
xor eax, eax
|
||||
StackTrace_getCaller_next:
|
||||
mov eax, [ebx+4]
|
||||
mov ebx, [ebx]
|
||||
test eax,eax
|
||||
jz StackTrace_getCallerFromStack_done
|
||||
dec ecx
|
||||
jnz StackTrace_getCaller_next
|
||||
StackTrace_getCallerFromStack_done:
|
||||
mov caller, eax
|
||||
}
|
||||
return caller;
|
||||
|
||||
#else
|
||||
|
||||
return 0;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
static long getCaller( int index )
|
||||
{
|
||||
#if /*defined(_DEBUG) && */defined(_MSC_VER) && defined(_M_IX86)
|
||||
|
||||
long caller = 0;
|
||||
__asm
|
||||
{
|
||||
mov ebx, ebp
|
||||
mov ecx, index
|
||||
inc ecx
|
||||
xor eax, eax
|
||||
StackTrace_getCaller_next:
|
||||
mov eax, [ebx+4]
|
||||
mov ebx, [ebx]
|
||||
test eax,eax
|
||||
jz StackTrace_getCaller_done
|
||||
dec ecx
|
||||
jnz StackTrace_getCaller_next
|
||||
StackTrace_getCaller_done:
|
||||
mov caller, eax
|
||||
}
|
||||
return caller;
|
||||
|
||||
#else
|
||||
|
||||
return 0;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
int StackTrace::printStackTrace( MapFile** map, int maps,
|
||||
int initLevel, int maxDepth,
|
||||
char* buffer, int bufferSize, unsigned long stackPtr, unsigned long opPtr )
|
||||
{
|
||||
if ( maxDepth > MAX_DEPTH )
|
||||
maxDepth = MAX_DEPTH;
|
||||
bool sucks = false;
|
||||
|
||||
// list callers
|
||||
long callersAddr[MAX_DEPTH];
|
||||
int callers = 0;
|
||||
int i;
|
||||
for ( i = initLevel ; i < maxDepth ; ++i )
|
||||
{
|
||||
long addr;
|
||||
if( stackPtr != 0 )
|
||||
{
|
||||
if( i == initLevel )
|
||||
addr = opPtr;
|
||||
else
|
||||
addr = getCallerFromStack( stackPtr, i - initLevel - 1 );
|
||||
}
|
||||
else
|
||||
addr = getCaller( i );
|
||||
callersAddr[callers++] = addr;
|
||||
|
||||
// end tracing here if the entry is not in a map file
|
||||
if( map != 0 )
|
||||
{
|
||||
int entry = -1;
|
||||
for ( int j = 0 ; j < maps ; ++j )
|
||||
{
|
||||
entry = map[j]->findEntry( addr );
|
||||
if ( -1 != entry )
|
||||
break;
|
||||
}
|
||||
if ( -1 == entry )
|
||||
{
|
||||
sucks = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int needed = 0;
|
||||
if ( bufferSize > 0 )
|
||||
*buffer = 0;
|
||||
|
||||
sprintf( buffer, "Call stack (%d levels%s):\r\n", callers - initLevel, sucks ? ", truncated" : "" );
|
||||
needed = strlen( buffer );
|
||||
|
||||
// output call stack
|
||||
for ( i = initLevel ; i < callers ; ++i )
|
||||
{
|
||||
long addr = callersAddr[callers-i-1];
|
||||
|
||||
// find entry info
|
||||
int entry = -1;
|
||||
const MapFile* entryMap = 0;
|
||||
for ( int j = 0 ; j < maps ; ++j )
|
||||
{
|
||||
entry = map[j]->findEntry( addr );
|
||||
if ( -1 != entry )
|
||||
{
|
||||
entryMap = map[j];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// format entry to tempory buf
|
||||
char buf[MapFileEntry::MAX_NAME+MAX_DEPTH+20]; // name + margin + hex number
|
||||
buf[0] = 0;
|
||||
for ( int k = initLevel-1 ; k < i ; ++k )
|
||||
strcat( buf, " " );
|
||||
if ( !entryMap )
|
||||
sprintf( buf+strlen(buf), "0x%08X\r\n", addr );
|
||||
else
|
||||
{
|
||||
const MapFileEntry &en = entryMap->getEntry( entry );
|
||||
long entryAddr = entryMap->loadAddress() + (en.section() << 12) + en.offset();
|
||||
|
||||
sprintf( buf+strlen(buf), "%s (0x%08X + 0x%08X)\r\n", en.name(), entryAddr, addr - entryAddr );
|
||||
}
|
||||
|
||||
// append temporary buf to output buffer if space left
|
||||
needed += strlen( buf );
|
||||
if ( needed < bufferSize )
|
||||
strcat( buffer, buf );
|
||||
}
|
||||
|
||||
// terminate output buffer
|
||||
if ( needed < bufferSize )
|
||||
buffer[needed] = 0;
|
||||
else if ( bufferSize > 0 )
|
||||
buffer[bufferSize-1] = 0;
|
||||
return needed;
|
||||
}
|
||||
|
||||
|
||||
} // dev
|
||||
/*
|
||||
* Copyright (c) 2001 Jani Kajala
|
||||
*
|
||||
* Permission to use, copy, modify, distribute and sell this
|
||||
* software and its documentation for any purpose is hereby
|
||||
* granted without fee, provided that the above copyright notice
|
||||
* appear in all copies and that both that copyright notice and
|
||||
* this permission notice appear in supporting documentation.
|
||||
* Jani Kajala makes no representations about the suitability
|
||||
* of this software for any purpose. It is provided "as is"
|
||||
* without express or implied warranty.
|
||||
*/
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
#include "pfStackTrace.h"
|
||||
#include "pfMapFile.h"
|
||||
#include "pfMapFileEntry.h"
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#pragma optimize( "y", off )
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#define MAX_DEPTH 32
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
namespace dev
|
||||
{
|
||||
|
||||
static long getCallerFromStack( unsigned long stackPtr, int index )
|
||||
{
|
||||
#if /*defined(_DEBUG) && */defined(_MSC_VER) && defined(_M_IX86)
|
||||
|
||||
long caller = 0;
|
||||
__asm
|
||||
{
|
||||
mov ebx, stackPtr
|
||||
mov ecx, index
|
||||
inc ecx
|
||||
xor eax, eax
|
||||
StackTrace_getCaller_next:
|
||||
mov eax, [ebx+4]
|
||||
mov ebx, [ebx]
|
||||
test eax,eax
|
||||
jz StackTrace_getCallerFromStack_done
|
||||
dec ecx
|
||||
jnz StackTrace_getCaller_next
|
||||
StackTrace_getCallerFromStack_done:
|
||||
mov caller, eax
|
||||
}
|
||||
return caller;
|
||||
|
||||
#else
|
||||
|
||||
return 0;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
static long getCaller( int index )
|
||||
{
|
||||
#if /*defined(_DEBUG) && */defined(_MSC_VER) && defined(_M_IX86)
|
||||
|
||||
long caller = 0;
|
||||
__asm
|
||||
{
|
||||
mov ebx, ebp
|
||||
mov ecx, index
|
||||
inc ecx
|
||||
xor eax, eax
|
||||
StackTrace_getCaller_next:
|
||||
mov eax, [ebx+4]
|
||||
mov ebx, [ebx]
|
||||
test eax,eax
|
||||
jz StackTrace_getCaller_done
|
||||
dec ecx
|
||||
jnz StackTrace_getCaller_next
|
||||
StackTrace_getCaller_done:
|
||||
mov caller, eax
|
||||
}
|
||||
return caller;
|
||||
|
||||
#else
|
||||
|
||||
return 0;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
int StackTrace::printStackTrace( MapFile** map, int maps,
|
||||
int initLevel, int maxDepth,
|
||||
char* buffer, int bufferSize, unsigned long stackPtr, unsigned long opPtr )
|
||||
{
|
||||
if ( maxDepth > MAX_DEPTH )
|
||||
maxDepth = MAX_DEPTH;
|
||||
bool sucks = false;
|
||||
|
||||
// list callers
|
||||
long callersAddr[MAX_DEPTH];
|
||||
int callers = 0;
|
||||
int i;
|
||||
for ( i = initLevel ; i < maxDepth ; ++i )
|
||||
{
|
||||
long addr;
|
||||
if( stackPtr != 0 )
|
||||
{
|
||||
if( i == initLevel )
|
||||
addr = opPtr;
|
||||
else
|
||||
addr = getCallerFromStack( stackPtr, i - initLevel - 1 );
|
||||
}
|
||||
else
|
||||
addr = getCaller( i );
|
||||
callersAddr[callers++] = addr;
|
||||
|
||||
// end tracing here if the entry is not in a map file
|
||||
if( map != 0 )
|
||||
{
|
||||
int entry = -1;
|
||||
for ( int j = 0 ; j < maps ; ++j )
|
||||
{
|
||||
entry = map[j]->findEntry( addr );
|
||||
if ( -1 != entry )
|
||||
break;
|
||||
}
|
||||
if ( -1 == entry )
|
||||
{
|
||||
sucks = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int needed = 0;
|
||||
if ( bufferSize > 0 )
|
||||
*buffer = 0;
|
||||
|
||||
sprintf( buffer, "Call stack (%d levels%s):\r\n", callers - initLevel, sucks ? ", truncated" : "" );
|
||||
needed = strlen( buffer );
|
||||
|
||||
// output call stack
|
||||
for ( i = initLevel ; i < callers ; ++i )
|
||||
{
|
||||
long addr = callersAddr[callers-i-1];
|
||||
|
||||
// find entry info
|
||||
int entry = -1;
|
||||
const MapFile* entryMap = 0;
|
||||
for ( int j = 0 ; j < maps ; ++j )
|
||||
{
|
||||
entry = map[j]->findEntry( addr );
|
||||
if ( -1 != entry )
|
||||
{
|
||||
entryMap = map[j];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// format entry to tempory buf
|
||||
char buf[MapFileEntry::MAX_NAME+MAX_DEPTH+20]; // name + margin + hex number
|
||||
buf[0] = 0;
|
||||
for ( int k = initLevel-1 ; k < i ; ++k )
|
||||
strcat( buf, " " );
|
||||
if ( !entryMap )
|
||||
sprintf( buf+strlen(buf), "0x%08X\r\n", addr );
|
||||
else
|
||||
{
|
||||
const MapFileEntry &en = entryMap->getEntry( entry );
|
||||
long entryAddr = entryMap->loadAddress() + (en.section() << 12) + en.offset();
|
||||
|
||||
sprintf( buf+strlen(buf), "%s (0x%08X + 0x%08X)\r\n", en.name(), entryAddr, addr - entryAddr );
|
||||
}
|
||||
|
||||
// append temporary buf to output buffer if space left
|
||||
needed += strlen( buf );
|
||||
if ( needed < bufferSize )
|
||||
strcat( buffer, buf );
|
||||
}
|
||||
|
||||
// terminate output buffer
|
||||
if ( needed < bufferSize )
|
||||
buffer[needed] = 0;
|
||||
else if ( bufferSize > 0 )
|
||||
buffer[bufferSize-1] = 0;
|
||||
return needed;
|
||||
}
|
||||
|
||||
|
||||
} // dev
|
||||
/*
|
||||
* Copyright (c) 2001 Jani Kajala
|
||||
*
|
||||
* Permission to use, copy, modify, distribute and sell this
|
||||
* software and its documentation for any purpose is hereby
|
||||
* granted without fee, provided that the above copyright notice
|
||||
* appear in all copies and that both that copyright notice and
|
||||
* this permission notice appear in supporting documentation.
|
||||
* Jani Kajala makes no representations about the suitability
|
||||
* of this software for any purpose. It is provided "as is"
|
||||
* without express or implied warranty.
|
||||
*/
|
||||
|
Reference in New Issue
Block a user