Browse Source

Eradicate pfStackTrace

Adam Johnson 13 years ago
parent
commit
5fa14466c8
  1. 9
      README.rst
  2. 1
      Sources/Plasma/Apps/plClient/CMakeLists.txt
  3. 1
      Sources/Plasma/FeatureLib/CMakeLists.txt
  4. 27
      Sources/Plasma/FeatureLib/pfStackTrace/CMakeLists.txt
  5. 128
      Sources/Plasma/FeatureLib/pfStackTrace/pfArray.h
  6. 334
      Sources/Plasma/FeatureLib/pfStackTrace/pfMapFile.cpp
  7. 94
      Sources/Plasma/FeatureLib/pfStackTrace/pfMapFile.h
  8. 70
      Sources/Plasma/FeatureLib/pfStackTrace/pfMapFileEntry.cpp
  9. 64
      Sources/Plasma/FeatureLib/pfStackTrace/pfMapFileEntry.h
  10. 70
      Sources/Plasma/FeatureLib/pfStackTrace/pfPrintStackTrace.cpp
  11. 26
      Sources/Plasma/FeatureLib/pfStackTrace/pfPrintStackTrace.h
  12. 190
      Sources/Plasma/FeatureLib/pfStackTrace/pfStackTrace.cpp
  13. 49
      Sources/Plasma/FeatureLib/pfStackTrace/pfStackTrace.h
  14. 261
      Sources/Plasma/FeatureLib/pfStackTrace/pfTextFile.cpp
  15. 102
      Sources/Plasma/FeatureLib/pfStackTrace/pfTextFile.h
  16. 1
      Sources/Tools/MaxMain/CMakeLists.txt
  17. 1
      Sources/Tools/MaxPlasmaLights/CMakeLists.txt

9
README.rst

@ -119,12 +119,3 @@ Independent JPEG Group (IJG) JPEG Library
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This software is based in part on the work of the Independent JPEG Group. This software is based in part on the work of the Independent JPEG Group.
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.

1
Sources/Plasma/Apps/plClient/CMakeLists.txt

@ -89,7 +89,6 @@ target_link_libraries(plClient pfLocalizationMgr)
target_link_libraries(plClient pfMessage) target_link_libraries(plClient pfMessage)
target_link_libraries(plClient pfPython) target_link_libraries(plClient pfPython)
target_link_libraries(plClient pfSecurePreloader) target_link_libraries(plClient pfSecurePreloader)
target_link_libraries(plClient pfStackTrace)
target_link_libraries(plClient pfSurface) target_link_libraries(plClient pfSurface)
target_link_libraries(plClient plAgeDescription) target_link_libraries(plClient plAgeDescription)
target_link_libraries(plClient plAgeLoader) target_link_libraries(plClient plAgeLoader)

1
Sources/Plasma/FeatureLib/CMakeLists.txt

@ -23,5 +23,4 @@ add_subdirectory(pfLocalizationMgr)
add_subdirectory(pfMessage) add_subdirectory(pfMessage)
add_subdirectory(pfPython) add_subdirectory(pfPython)
add_subdirectory(pfSecurePreloader) add_subdirectory(pfSecurePreloader)
add_subdirectory(pfStackTrace)
add_subdirectory(pfSurface) add_subdirectory(pfSurface)

27
Sources/Plasma/FeatureLib/pfStackTrace/CMakeLists.txt

@ -1,27 +0,0 @@
include_directories(../../CoreLib)
if(WIN32)
add_definitions(-DWIN32)
endif(WIN32)
set(pfStackTrace_SOURCES
pfMapFile.cpp
pfMapFileEntry.cpp
pfPrintStackTrace.cpp
pfStackTrace.cpp
pfTextFile.cpp
)
set(pfStackTrace_HEADERS
pfArray.h
pfMapFile.h
pfMapFileEntry.h
pfPrintStackTrace.h
pfStackTrace.h
pfTextFile.h
)
add_library(pfStackTrace STATIC ${pfStackTrace_SOURCES} ${pfStackTrace_HEADERS})
source_group("Source Files" FILES ${pfStackTrace_SOURCES})
source_group("Header Files" FILES ${pfStackTrace_HEADERS})

128
Sources/Plasma/FeatureLib/pfStackTrace/pfArray.h

@ -1,128 +0,0 @@
#ifndef _DEV_ARRAY_H
#define _DEV_ARRAY_H
namespace dev
{
/** Very simple dynamic array. */
template <class T> class Array
{
public:
/** Creates an empty array. */
Array() :
m_data(0), m_len(0), m_cap(0)
{
}
/** Creates an array of specified size. */
explicit Array( int size ) :
m_data(0), m_len(0), m_cap(0)
{
setSize( size );
}
///
~Array()
{
delete[] m_data;
}
/** Appends an item at the end of the array. */
void add( const T& item )
{
if ( m_len+1 > m_cap )
setCapacity( m_len + 1 );
m_data[m_len++] = item;
}
/** Resizes the array. */
void setSize( int size )
{
if ( size > m_cap )
setCapacity( size );
m_len = size;
}
/** Returns ith item. */
T& operator[]( int i )
{
return m_data[i];
}
/** Returns pointer to the first element in the vector. */
T* begin()
{
return m_data;
}
/** Returns pointer to one beyond the last element in the vector. */
T* end()
{
return m_data + m_len;
}
/** Returns number of items in the array. */
int size() const
{
return m_len;
}
/** Returns ith item. */
const T& operator[]( int i ) const
{
return m_data[i];
}
/** Returns pointer to the first element in the vector. */
const T* begin() const
{
return m_data;
}
/** Returns pointer to one beyond the last element in the vector. */
const T* end() const
{
return m_data + m_len;
}
private:
T* m_data;
int m_len;
int m_cap;
void setCapacity( int cap )
{
++cap;
if ( cap < 8 )
cap = 8;
else if ( cap < m_cap*2 )
cap = m_cap*2;
m_cap = cap;
T* data = new T[cap];
for ( int i = 0 ; i < m_len ; ++i )
data[i] = m_data[i];
delete[] m_data;
m_data = data;
}
};
} // dev
#endif // _DEV_ARRAY_H
/*
* 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.
*/

334
Sources/Plasma/FeatureLib/pfStackTrace/pfMapFile.cpp

@ -1,334 +0,0 @@
#include "HeadSpin.h"
#include "pfMapFile.h"
#include "pfMapFileEntry.h"
#include "pfTextFile.h"
#include "pfArray.h"
#include <algorithm>
#include <string.h>
#include <ctype.h>
//-----------------------------------------------------------------------------
namespace dev
{
class MapFile::MapFileImpl
{
public:
long loadAddr;
char name[256];
Array<MapFileEntry> segments;
Array<MapFileEntry> entries;
MapFileImpl( const char* filename ) :
loadAddr(0), m_file( filename ), m_err( MapFile::ERROR_NONE )
{
m_file.readString( name, sizeof(name) );
char buf[1024];
while ( m_file.readString(buf,sizeof(buf)) )
{
if ( !strcmp("Preferred",buf) )
parseLoadAddress();
else if ( !strcmp("Start",buf) )
parseSegments();
else if ( !strcmp("Address",buf) )
parseEntries();
else
m_file.skipLine();
}
std::sort( segments.begin(), segments.end() );
std::sort( entries.begin(), entries.end() );
}
~MapFileImpl()
{
}
ErrorType error() const
{
if ( m_err != MapFile::ERROR_NONE )
return m_err;
switch ( m_file.error() )
{
case TextFile::ERROR_OPEN: return MapFile::ERROR_OPEN;
case TextFile::ERROR_READ: return MapFile::ERROR_READ;
case TextFile::ERROR_PARSE: return MapFile::ERROR_PARSE;
default: return MapFile::ERROR_NONE;
}
}
int line() const
{
if ( m_err != MapFile::ERROR_NONE )
return m_errLine;
return m_file.line();
}
private:
TextFile m_file;
MapFile::ErrorType m_err;
int m_errLine;
/**
* Returns true if the next line is empty.
*/
bool nextLineEmpty()
{
m_file.skipLine();
char ch;
while ( m_file.peekChar(&ch) && isspace(ch) && ch != '\n' )
m_file.readChar( &ch );
if ( m_file.peekChar(&ch) && ch == '\n' )
return true;
return false;
}
/**
* Parses specified string.
* Sets error if parsed string doesnt match.
*/
void parse( const char* str )
{
char buf[256];
m_file.readString( buf, sizeof(buf) );
if ( strcmp(str,buf) )
{
m_err = MapFile::ERROR_PARSE;
m_errLine = m_file.line();
}
}
/**
* Parses specified character.
* Sets error if parsed character doesnt match.
*/
void parse( char ch )
{
char ch2;
if ( !m_file.readChar(&ch2) || ch2 != ch )
{
m_err = MapFile::ERROR_PARSE;
m_errLine = m_file.line();
}
}
/**
* Example:
* (Preferred) load address is 00400000
*/
void parseLoadAddress()
{
parse( "load" ); parse( "address" ); parse( "is" );
loadAddr = m_file.readHex();
}
/**
* Example:
* (Start) Length Name Class
* 0001:00000000 00002c05H .text CODE
*/
void parseSegments()
{
parse( "Length" );
parse( "Name" );
parse( "Class" );
m_file.skipWhitespace();
while ( !error() )
{
int seg = m_file.readHex();
parse( ':' );
int offs = m_file.readHex();
int len = m_file.readHex();
parse( 'H' );
char buf[256];
m_file.readString( buf, sizeof(buf) );
segments.add( MapFileEntry(seg,offs,len,buf) );
// break at empty line
if ( nextLineEmpty() )
break;
}
}
/**
* Example:
* (Address) Publics by Value Rva+Base Lib:Object
* 0001:000001a0 ?stackTrace@@YAXXZ 004011a0 f main.obj
*/
void parseEntries()
{
parse( "Publics" ); parse( "by" ); parse( "Value" );
parse( "Rva+Base" );
parse( "Lib:Object" );
m_file.skipWhitespace();
while ( !error() )
{
int seg = m_file.readHex();
parse( ':' );
int offs = m_file.readHex();
char buf[256];
m_file.readString( buf, sizeof(buf) );
char* entryname = buf;
// chop entry name at @@
char* end = strstr( entryname, "@@" );
if ( end )
*end = 0;
// skip preceding ?01..
while ( isdigit(*entryname) || *entryname == '?' || *entryname == '$' )
++entryname;
// conv @ -> .
for ( char* str = entryname ; *str ; ++str )
if ( *str == '@' )
*str = '.';
// Added 9.5.02 mcn - Reverse the order of the symbols to be more natural
if( strlen( entryname ) < 512 )
{
static char newName[ 512 ];
char *search;
newName[ 0 ] = 0;
while( ( search = strrchr( entryname, '.' ) ) != 0 )
{
*search = 0;
if( newName[ 0 ] != 0 )
strcat( newName, "::" );
strcat( newName, search + 1 );
}
if( newName[ 0 ] != 0 )
strcat( newName, "::" );
strcat( newName, entryname );
entryname = newName;
}
entries.add( MapFileEntry(seg,offs,0,entryname) );
// break at empty line
if ( nextLineEmpty() )
break;
}
}
};
//-----------------------------------------------------------------------------
MapFile::MapFile( const char* filename )
{
m_this = new MapFileImpl( filename );
}
MapFile::~MapFile()
{
delete m_this;
}
long MapFile::loadAddress() const
{
return m_this->loadAddr;
}
const MapFileEntry& MapFile::getSegment( int i ) const
{
return m_this->segments[i];
}
const MapFileEntry& MapFile::getEntry( int i ) const
{
return m_this->entries[i];
}
int MapFile::segments() const
{
return m_this->segments.size();
}
int MapFile::entries() const
{
return m_this->entries.size();
}
MapFile::ErrorType MapFile::error() const
{
return m_this->error();
}
int MapFile::line() const
{
return m_this->line();
}
int MapFile::findEntry( long addr ) const
{
for ( int j = 0 ; j < segments() ; ++j )
{
const MapFileEntry& segment = getSegment( j );
long section = segment.section();
long segmentBegin = loadAddress() + (segment.section() << 12) + segment.offset();
long segmentEnd = segmentBegin + segment.length();
if ( addr >= segmentBegin && addr < segmentEnd )
{
for ( int i = entries()-1 ; i >= 0 ; --i )
{
const MapFileEntry entry = getEntry( i );
if ( entry.section() == section )
{
long entryAddr = loadAddress() + (entry.section() << 12) + entry.offset();
if ( entryAddr <= addr )
return i;
}
}
}
}
return -1;
}
void MapFile::getModuleMapFilename( char* buffer, int bufferSize )
{
int len = 0;
buffer[len] = 0;
#ifdef WIN32
// get name of the exe/dll
len = GetModuleFileName( GetModuleHandle(0), buffer, bufferSize-1 );
buffer[len] = 0;
#endif
// remove .exe or .dll extension
if ( len > 3 &&
(!strcmp(buffer+len-4,".exe") || !strcmp(buffer+len-4,".EXE") ||
!strcmp(buffer+len-4,".DLL") || !strcmp(buffer+len-4,".dll")) )
{
buffer[len-4] = 0;
}
// append .map extension
if ( (int)strlen(buffer)+4 < bufferSize )
{
strcat( buffer, ".map" );
}
}
} // 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.
*/

94
Sources/Plasma/FeatureLib/pfStackTrace/pfMapFile.h

@ -1,94 +0,0 @@
#ifndef _DEV_MAPFILE_H
#define _DEV_MAPFILE_H
namespace dev
{
class MapFileEntry;
/**
* Linker generated module map file parser.
*/
class MapFile
{
public:
/** Error code. */
enum ErrorType
{
/** No error. */
ERROR_NONE,
/** File open failed. */
ERROR_OPEN,
/** File reading failed. */
ERROR_READ,
/** Syntax error. */
ERROR_PARSE
};
/** Reads a map file. */
explicit MapFile( const char* filename );
///
~MapFile();
/** Returns preferred load address. */
long loadAddress() const;
/** Returns ith entry from the map file. */
const MapFileEntry& getEntry( int i ) const;
/** Returns ith segment from the map file. */
const MapFileEntry& getSegment( int i ) const;
/** Returns number of segments in the map file. */
int segments() const;
/** Returns number of entries in the map file. */
int entries() const;
/** Returns error code or 0 (ERROR_NONE) if no error. */
ErrorType error() const;
/** Returns line number of last successful read character. */
int line() const;
/**
* Finds entry which contains specified address.
* @return Entry index or -1 if not found.
*/
int findEntry( long addr ) const;
/**
* Returns current module name, with map extension.
* The output buffer is always 0-terminated.
*/
static void getModuleMapFilename( char* buffer, int bufferSize );
private:
class MapFileImpl;
MapFileImpl* m_this;
MapFile( const MapFile& );
MapFile& operator=( const MapFile& );
};
} // dev
#endif // _DEV_MAPFILE_H
/*
* 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.
*/

70
Sources/Plasma/FeatureLib/pfStackTrace/pfMapFileEntry.cpp

@ -1,70 +0,0 @@
#include "pfMapFileEntry.h"
#include <string.h>
//-----------------------------------------------------------------------------
namespace dev
{
MapFileEntry::MapFileEntry()
{
m_sec = 0;
m_addr = 0;
m_len = 0;
m_name[0] = 0;
}
MapFileEntry::MapFileEntry( long section, long offset, long length, const char* name )
{
m_sec = section;
m_addr = offset;
m_len = length;
strncpy( m_name, name, MAX_NAME );
m_name[MAX_NAME] = 0;
}
long MapFileEntry::section() const
{
return m_sec;
}
long MapFileEntry::offset() const
{
return m_addr;
}
long MapFileEntry::length() const
{
return m_len;
}
const char* MapFileEntry::name() const
{
return m_name;
}
bool MapFileEntry::operator<( const MapFileEntry& other ) const
{
if ( m_sec < other.m_sec )
return true;
if ( m_sec > other.m_sec )
return false;
return m_addr < other.m_addr;
}
} // 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.
*/

64
Sources/Plasma/FeatureLib/pfStackTrace/pfMapFileEntry.h

@ -1,64 +0,0 @@
#ifndef _DEV_MAPFILEENTRY_H
#define _DEV_MAPFILEENTRY_H
namespace dev
{
/** An entry in the map file. */
class MapFileEntry
{
public:
/** Class constants. */
enum Constants
{
/** Maximum number of characters in map file entry name. */
MAX_NAME = 256
};
///
MapFileEntry();
/** Creates an entry with specified section, offset, length and name. */
MapFileEntry( long section, long offset, long length, const char* name );
/** Returns section of the entry. */
long section() const;
/** Returns offset of the entry. */
long offset() const;
/** Returns length of the entry (only defined for segments). */
long length() const;
/** Returns name of the entry. */
const char* name() const;
/** Returns true if the offset of this entry is before the other one. */
bool operator<( const MapFileEntry& other ) const;
private:
long m_sec;
long m_addr;
long m_len;
char m_name[MAX_NAME+1];
};
} // dev
#endif // _DEV_MAPFILEENTRY_H
/*
* 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.
*/

70
Sources/Plasma/FeatureLib/pfStackTrace/pfPrintStackTrace.cpp

@ -1,70 +0,0 @@
#include "pfPrintStackTrace.h"
#include "pfStackTrace.h"
#include "pfMapFile.h"
#include <stdio.h>
#include <string.h>
#pragma optimize( "y", off )
//-----------------------------------------------------------------------------
using namespace dev;
//-----------------------------------------------------------------------------
/**
* Prints stack trace to user defined buffer.
* Always terminates the buffer with 0.
*/
void printStackTrace( char* buffer, int bufferSize, unsigned long stackPtr, unsigned long opPtr )
{
// find out map file name
char modname[500];
MapFile::getModuleMapFilename( modname, sizeof(modname) );
// parse map file
static char buf[5000];
MapFile map( modname );
switch ( map.error() )
{
case MapFile::ERROR_OPEN: sprintf( buf, "Failed to open map file %s\n", modname ); break;
case MapFile::ERROR_READ: sprintf( buf, "Error while reading map file %s(%i)\n", modname, map.line() ); break;
case MapFile::ERROR_PARSE: sprintf( buf, "Parse error in map file %s(%i)\n", modname, map.line() ); break;
default: break;
}
// print stack trace to buffer
if ( !map.error() )
{
MapFile* maps[] = {&map};
StackTrace::printStackTrace( maps, 1, 1, 16, buf, sizeof(buf), stackPtr, opPtr );
}
else
{
// 9.5.2002 mcn - Even if we can't open the map file, still print out the stack trace for later reference
StackTrace::printStackTrace( 0, 0, 1, 16, buf, sizeof(buf), stackPtr, opPtr );
}
// copy to user buffer
if ( bufferSize > 0 )
{
if( buffer[ 0 ] == 0 )
strncpy( buffer, buf, bufferSize );
else
strncat( buffer, buf, bufferSize );
buffer[bufferSize-1] = 0;
}
}
/*
* 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.
*/

26
Sources/Plasma/FeatureLib/pfStackTrace/pfPrintStackTrace.h

@ -1,26 +0,0 @@
#ifndef _PRINTSTACKTRACE_H
#define _PRINTSTACKTRACE_H
/**
* Prints formatted call stack to the user defined buffer,
* always terminating the buffer with 0.
* Uses stack frame to find out the caller function address and
* the map file to find out the function name.
*/
void printStackTrace( char* buffer, int bufferSize, unsigned long stackPtr = 0, unsigned long opPtr = 0 );
#endif // _PRINTSTACKTRACE_H
/*
* 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.
*/

190
Sources/Plasma/FeatureLib/pfStackTrace/pfStackTrace.cpp

@ -1,190 +0,0 @@
#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.
*/

49
Sources/Plasma/FeatureLib/pfStackTrace/pfStackTrace.h

@ -1,49 +0,0 @@
#ifndef _DEV_STACKTRACE_H
#define _DEV_STACKTRACE_H
namespace dev
{
class MapFile;
/** Stack tracing utility. */
class StackTrace
{
public:
/**
* Prints formatted call stack to the user buffer.
* Always terminates the user buffer with 0.
*
* @param map Array of pointers to map files.
* @param maps Number of map files.
* @param initLevel Number of functions to skip before starting the tracing.
* @param maxDepth Maximum number of levels in the stack trace.
* @param buffer [out] Output buffer for the formatted stack trace.
* @param bufferSize Size of the output buffer.
* @return Needed buffer size.
*/
static int printStackTrace( MapFile** map, int maps,
int initLevel, int maxDepth,
char* buffer, int bufferSize, unsigned long stackPtr = 0, unsigned long opPtr = 0 );
};
} // dev
#endif // _DEV_STACKTRACE_H
/*
* 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.
*/

261
Sources/Plasma/FeatureLib/pfStackTrace/pfTextFile.cpp

@ -1,261 +0,0 @@
#include "HeadSpin.h"
#include "pfTextFile.h"
#include <stdio.h>
#include <ctype.h>
//-----------------------------------------------------------------------------
namespace dev
{
class TextFile::TextFileImpl
{
public:
TextFile::ErrorType err;
int line;
explicit TextFileImpl( const char* filename )
{
err = TextFile::ERROR_NONE;
line = 1;
m_peeked = false;
m_peekedChar = 0;
m_file = fopen( filename, "rt" );
if ( !m_file )
err = TextFile::ERROR_OPEN;
}
~TextFileImpl()
{
if ( m_file )
{
fclose( m_file );
m_file = 0;
}
}
bool eof() const
{
if ( err )
return true;
return 0 != feof(m_file);
}
bool peekChar( char* ch )
{
if ( err )
return false;
if ( !m_peeked )
{
int c = getc( m_file );
if ( EOF != c )
{
m_peeked = true;
m_peekedChar = (char)c;
}
else
{
if ( ferror(m_file) )
err = TextFile::ERROR_READ;
}
}
if ( m_peeked )
*ch = m_peekedChar;
return m_peeked;
}
bool readChar( char* ch )
{
if ( err )
return false;
bool more = peekChar( ch );
m_peeked = false;
if ( more && *ch == '\n' )
++line;
return more;
}
bool skipWhitespace()
{
if ( err )
return false;
char ch;
while ( peekChar(&ch) )
{
if ( !isspace(ch) )
break;
readChar( &ch );
}
return !eof();
}
bool readString( char* buf, int size )
{
if ( err )
return false;
skipWhitespace();
int count = 0;
char ch;
while ( peekChar(&ch) )
{
if ( isspace(ch) )
break;
if ( count+1 < size )
buf[count++] = ch;
readChar( &ch );
}
if ( size > 0 )
buf[count] = 0;
return count > 0;
}
void skipLine()
{
if ( err )
return;
char ch;
while ( readChar(&ch) )
{
if ( ch == '\n' )
break;
}
}
long readHex()
{
if ( err )
return 0;
skipWhitespace();
// hex must start with alphanumeric character
char ch;
if ( !peekChar(&ch) || !isalnum(ch) )
{
err = TextFile::ERROR_PARSE;
return 0;
}
long x = 0;
while ( peekChar(&ch) )
{
switch ( ch )
{
case '0': x <<= 4; x += 0; break;
case '1': x <<= 4; x += 1; break;
case '2': x <<= 4; x += 2; break;
case '3': x <<= 4; x += 3; break;
case '4': x <<= 4; x += 4; break;
case '5': x <<= 4; x += 5; break;
case '6': x <<= 4; x += 6; break;
case '7': x <<= 4; x += 7; break;
case '8': x <<= 4; x += 8; break;
case '9': x <<= 4; x += 9; break;
case 'a':
case 'A': x <<= 4; x += 0xA; break;
case 'b':
case 'B': x <<= 4; x += 0xB; break;
case 'c':
case 'C': x <<= 4; x += 0xC; break;
case 'd':
case 'D': x <<= 4; x += 0xD; break;
case 'e':
case 'E': x <<= 4; x += 0xE; break;
case 'f':
case 'F': x <<= 4; x += 0xF; break;
default: return x;
}
readChar( &ch );
}
return x;
}
private:
bool m_peeked;
char m_peekedChar;
FILE* m_file;
TextFileImpl( const TextFileImpl& );
TextFileImpl& operator=( const TextFileImpl& );
};
//-----------------------------------------------------------------------------
TextFile::TextFile( const char* filename )
{
m_this = new TextFileImpl( filename );
}
TextFile::~TextFile()
{
delete m_this;
}
bool TextFile::readString( char* buf, int size )
{
return m_this->readString( buf, size );
}
void TextFile::skipLine()
{
m_this->skipLine();
}
long TextFile::readHex()
{
return m_this->readHex();
}
bool TextFile::skipWhitespace()
{
return m_this->skipWhitespace();
}
TextFile::ErrorType TextFile::error() const
{
return m_this->err;
}
bool TextFile::readChar( char* ch )
{
return m_this->readChar( ch );
}
bool TextFile::peekChar( char* ch )
{
return m_this->peekChar( ch );
}
bool TextFile::eof() const
{
return m_this->eof();
}
int TextFile::line() const
{
return m_this->line;
}
} // 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.
*/

102
Sources/Plasma/FeatureLib/pfStackTrace/pfTextFile.h

@ -1,102 +0,0 @@
#ifndef _DEV_TEXTFILE_H
#define _DEV_TEXTFILE_H
namespace dev
{
/**
* ASCII-7 text file parser. Doesnt throw exceptions.
*/
class TextFile
{
public:
/** Error code. */
enum ErrorType
{
/** No error. */
ERROR_NONE,
/** File open failed. */
ERROR_OPEN,
/** File reading failed. */
ERROR_READ,
/** Syntax error. */
ERROR_PARSE
};
/** Opens a file. */
explicit TextFile( const char* filename );
///
~TextFile();
/**
* Reads a single character.
* @return true if read ok.
*/
bool readChar( char* ch );
/**
* Peeks a single character.
* @return true if peek ok.
*/
bool peekChar( char* ch );
/**
* Reads whitespace delimited string.
* If the string doesnt fit to the buffer then
* the rest of the string is skipped. Buffer
* is always 0-terminated.
* @param buf [out] Pointer to string buffer.
* @param size String buffer size. Must be larger than 0.
* @return false if end-of-file reached before any characters was read.
*/
bool readString( char* buf, int size );
/** Skips the rest of the line. */
void skipLine();
/** Reads hex integer. Skips preceding whitespace. */
long readHex();
/**
* Skips whitespace characters.
* @return false if end-of-file reached.
*/
bool skipWhitespace();
/** Returns true if end-of-file have been reached. */
bool eof() const;
/** Returns error code or 0 (ERROR_NONE) if no error. */
ErrorType error() const;
/** Returns line number of last successful read character. */
int line() const;
private:
class TextFileImpl;
TextFileImpl* m_this;
TextFile( const TextFile& );
TextFile& operator=( const TextFile& );
};
} // dev
#endif // _DEV_TEXTFILE_H
/*
* 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.
*/

1
Sources/Tools/MaxMain/CMakeLists.txt

@ -126,7 +126,6 @@ target_link_libraries(MaxMain pfLocalizationMgr)
target_link_libraries(MaxMain pfMessage) target_link_libraries(MaxMain pfMessage)
target_link_libraries(MaxMain pfPython) target_link_libraries(MaxMain pfPython)
target_link_libraries(MaxMain pfSecurePreloader) target_link_libraries(MaxMain pfSecurePreloader)
target_link_libraries(MaxMain pfStackTrace)
target_link_libraries(MaxMain pfSurface) target_link_libraries(MaxMain pfSurface)
target_link_libraries(MaxMain plAgeDescription) target_link_libraries(MaxMain plAgeDescription)
target_link_libraries(MaxMain plAgeLoader) target_link_libraries(MaxMain plAgeLoader)

1
Sources/Tools/MaxPlasmaLights/CMakeLists.txt

@ -62,7 +62,6 @@ target_link_libraries(MaxPlasmaLights pfLocalizationMgr)
target_link_libraries(MaxPlasmaLights pfMessage) target_link_libraries(MaxPlasmaLights pfMessage)
target_link_libraries(MaxPlasmaLights pfPython) target_link_libraries(MaxPlasmaLights pfPython)
target_link_libraries(MaxPlasmaLights pfSecurePreloader) target_link_libraries(MaxPlasmaLights pfSecurePreloader)
target_link_libraries(MaxPlasmaLights pfStackTrace)
target_link_libraries(MaxPlasmaLights pfSurface) target_link_libraries(MaxPlasmaLights pfSurface)
target_link_libraries(MaxPlasmaLights plAgeDescription) target_link_libraries(MaxPlasmaLights plAgeDescription)
target_link_libraries(MaxPlasmaLights plAgeLoader) target_link_libraries(MaxPlasmaLights plAgeLoader)

Loading…
Cancel
Save