Darryl Pogue
13 years ago
11 changed files with 1 additions and 732 deletions
@ -1,16 +0,0 @@ |
|||||||
include_directories(../../CoreLib) |
|
||||||
include_directories(../../NucleusLib) |
|
||||||
|
|
||||||
set(pnCrash_SOURCES |
|
||||||
pnCrash.cpp |
|
||||||
) |
|
||||||
|
|
||||||
set(pnCrash_HEADERS |
|
||||||
Pch.h |
|
||||||
pnCrash.h |
|
||||||
) |
|
||||||
|
|
||||||
add_library(pnCrash STATIC ${pnCrash_SOURCES} ${pnCrash_HEADERS}) |
|
||||||
|
|
||||||
source_group("Source Files" FILES ${pnCrash_SOURCES}) |
|
||||||
source_group("Header Files" FILES ${pnCrash_HEADERS}) |
|
@ -1,54 +0,0 @@ |
|||||||
/*==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/>.
|
|
||||||
|
|
||||||
Additional permissions under GNU GPL version 3 section 7 |
|
||||||
|
|
||||||
If you modify this Program, or any covered work, by linking or |
|
||||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK, |
|
||||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent |
|
||||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK |
|
||||||
(or a modified version of those libraries), |
|
||||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA, |
|
||||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG |
|
||||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the |
|
||||||
licensors of this Program grant you additional |
|
||||||
permission to convey the resulting work. Corresponding Source for a |
|
||||||
non-source form of such a combination shall include the source code for |
|
||||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered |
|
||||||
work. |
|
||||||
|
|
||||||
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==*/ |
|
||||||
/*****************************************************************************
|
|
||||||
* |
|
||||||
* $/Plasma20/Sources/Plasma/NucleusLib/pnCrash/Pch.h |
|
||||||
*
|
|
||||||
***/ |
|
||||||
|
|
||||||
#ifdef PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNCRASH_PCH_H |
|
||||||
#error "Header $/Plasma20/Sources/Plasma/NucleusLib/pnCrash/Pch.h included more than once" |
|
||||||
#endif |
|
||||||
#define PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNCRASH_PCH_H |
|
||||||
|
|
||||||
|
|
||||||
#include "pnUtils/pnUtils.h" |
|
@ -1,6 +0,0 @@ |
|||||||
@echo off |
|
||||||
:Top |
|
||||||
echo Running pnCrash.py |
|
||||||
C:\Python23\python pnCrash.py |
|
||||||
Sleep 1 |
|
||||||
goto :Top |
|
@ -1,49 +0,0 @@ |
|||||||
/*==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/>.
|
|
||||||
|
|
||||||
Additional permissions under GNU GPL version 3 section 7 |
|
||||||
|
|
||||||
If you modify this Program, or any covered work, by linking or |
|
||||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK, |
|
||||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent |
|
||||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK |
|
||||||
(or a modified version of those libraries), |
|
||||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA, |
|
||||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG |
|
||||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the |
|
||||||
licensors of this Program grant you additional |
|
||||||
permission to convey the resulting work. Corresponding Source for a |
|
||||||
non-source form of such a combination shall include the source code for |
|
||||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered |
|
||||||
work. |
|
||||||
|
|
||||||
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==*/ |
|
||||||
/*****************************************************************************
|
|
||||||
* |
|
||||||
* $/Plasma20/Sources/Plasma/NucleusLib/pnCrash/pnCrash.cpp |
|
||||||
*
|
|
||||||
***/ |
|
||||||
|
|
||||||
#include "Pch.h" |
|
||||||
#pragma hdrstop |
|
@ -1,99 +0,0 @@ |
|||||||
/*==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/>.
|
|
||||||
|
|
||||||
Additional permissions under GNU GPL version 3 section 7 |
|
||||||
|
|
||||||
If you modify this Program, or any covered work, by linking or |
|
||||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK, |
|
||||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent |
|
||||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK |
|
||||||
(or a modified version of those libraries), |
|
||||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA, |
|
||||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG |
|
||||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the |
|
||||||
licensors of this Program grant you additional |
|
||||||
permission to convey the resulting work. Corresponding Source for a |
|
||||||
non-source form of such a combination shall include the source code for |
|
||||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered |
|
||||||
work. |
|
||||||
|
|
||||||
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==*/ |
|
||||||
/*****************************************************************************
|
|
||||||
* |
|
||||||
* $/Plasma20/Sources/Plasma/NucleusLib/pnCrash/pnCrash.h |
|
||||||
*
|
|
||||||
***/ |
|
||||||
|
|
||||||
#ifndef PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNCRASH_PNCRASH_H |
|
||||||
#define PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNCRASH_PNCRASH_H |
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
* |
|
||||||
* Crash API |
|
||||||
* |
|
||||||
***/ |
|
||||||
|
|
||||||
void CrashExceptionDump (const char occasion[], void * info); |
|
||||||
|
|
||||||
void CrashSetEmailParameters ( |
|
||||||
const char smtp[], |
|
||||||
const char sender[], |
|
||||||
const char recipients[], // separate multiple recipients with semicolons
|
|
||||||
const char username[], // optional (see auth notes in pnMail.h)
|
|
||||||
const char password[], // optional (see auth notes in pnMail.h)
|
|
||||||
const char replyTo[] // optional
|
|
||||||
); |
|
||||||
|
|
||||||
void * CrashAddModule ( |
|
||||||
uintptr_t address, |
|
||||||
unsigned buildId, |
|
||||||
unsigned branchId, |
|
||||||
const wchar_t name[], |
|
||||||
const wchar_t buildString[] |
|
||||||
); |
|
||||||
|
|
||||||
void CrashRemoveModule ( |
|
||||||
void * module |
|
||||||
); |
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
* |
|
||||||
* Deadlock detection (server only) |
|
||||||
* |
|
||||||
***/ |
|
||||||
|
|
||||||
#ifdef SERVER |
|
||||||
void * CrashAddDeadlockCheck (void * thread, const wchar_t debugstr[] ); |
|
||||||
void CrashRemoveDeadlockCheck (void * check); |
|
||||||
void CrashSetDeadlockCheckTimes (unsigned emailSec, unsigned terminateSec); |
|
||||||
// returns previous setting
|
|
||||||
bool CrashEnableDeadlockChecking (bool enable); |
|
||||||
void CrashDeadlockCheckNow (); |
|
||||||
void CrashSendThreadReport (); |
|
||||||
#endif |
|
||||||
|
|
||||||
|
|
||||||
#endif // PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNCRASH_PNCRASH_H
|
|
@ -1,469 +0,0 @@ |
|||||||
""" *==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/>. |
|
||||||
|
|
||||||
Additional permissions under GNU GPL version 3 section 7 |
|
||||||
|
|
||||||
If you modify this Program, or any covered work, by linking or |
|
||||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK, |
|
||||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent |
|
||||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK |
|
||||||
(or a modified version of those libraries), |
|
||||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA, |
|
||||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG |
|
||||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the |
|
||||||
licensors of this Program grant you additional |
|
||||||
permission to convey the resulting work. Corresponding Source for a |
|
||||||
non-source form of such a combination shall include the source code for |
|
||||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered |
|
||||||
work. |
|
||||||
|
|
||||||
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==* """ |
|
||||||
import sys, os, re, poplib, smtplib, time |
|
||||||
|
|
||||||
|
|
||||||
#***************************************************************************** |
|
||||||
#* |
|
||||||
#* Private data |
|
||||||
#* |
|
||||||
#*** |
|
||||||
|
|
||||||
s_pop3Srv = 'catherine.cyan.com' |
|
||||||
s_pop3User = 'crashhandler' |
|
||||||
s_pop3Pass = 'crashhandler' |
|
||||||
|
|
||||||
s_smtpSrv = 'catherine.cyan.com' |
|
||||||
#s_smtpRecipients = ['eric@cyan.com'] |
|
||||||
s_smtpRecipients = ['crash2@cyan.com'] |
|
||||||
|
|
||||||
#s_mapFileBasePath = 'P:\\Plasma20\\Scripts\\Server\\Admin\\'; |
|
||||||
s_mapFileBasePath = '\\\\dirtcake\\MapFiles\\'; |
|
||||||
|
|
||||||
s_modules = {} |
|
||||||
s_mapfiles = {} |
|
||||||
s_sortedModuleKeys = [] |
|
||||||
|
|
||||||
|
|
||||||
#***************************************************************************** |
|
||||||
#* |
|
||||||
#* Local functions |
|
||||||
#* |
|
||||||
#*** |
|
||||||
|
|
||||||
#============================================================================= |
|
||||||
def UndecorateCppName (name): |
|
||||||
name = re.sub('^\?', '', name, 1) |
|
||||||
name = re.sub('^_', '', name, 1) |
|
||||||
name = re.sub('@', ' ', name) |
|
||||||
name = re.sub('\s+', ' ', name) |
|
||||||
return name |
|
||||||
|
|
||||||
#============================================================================= |
|
||||||
# returns index of the first entry for which 'eval' returns false |
|
||||||
def bsearch (a, eval): |
|
||||||
low = 0 |
|
||||||
high = len(a) |
|
||||||
|
|
||||||
if low != high: |
|
||||||
while True: |
|
||||||
mid = (low + high) // 2 |
|
||||||
result = eval(a[mid]) |
|
||||||
if result > 0: |
|
||||||
if mid == low: |
|
||||||
break |
|
||||||
low = mid |
|
||||||
else: |
|
||||||
high = mid |
|
||||||
if mid == low: |
|
||||||
break |
|
||||||
return high |
|
||||||
|
|
||||||
|
|
||||||
#***************************************************************************** |
|
||||||
#* |
|
||||||
#* Function class |
|
||||||
#* |
|
||||||
#*** |
|
||||||
|
|
||||||
class Function: |
|
||||||
|
|
||||||
#========================================================================= |
|
||||||
def __init__ (self, name, baseAddr, relocAddr, module): |
|
||||||
self.name = UndecorateCppName(name) |
|
||||||
self.baseAddr = baseAddr |
|
||||||
self.relocAddr = relocAddr |
|
||||||
self.module = module |
|
||||||
#print "Function: %08x,%s,%s" % (self.relocAddr, self.module, self.name) |
|
||||||
|
|
||||||
|
|
||||||
#***************************************************************************** |
|
||||||
#* |
|
||||||
#* Mapfile class |
|
||||||
#* |
|
||||||
#*** |
|
||||||
|
|
||||||
class Mapfile: |
|
||||||
#========================================================================= |
|
||||||
def __init__ (self, filename): |
|
||||||
self.filename = filename |
|
||||||
self.prefLoadAddr = 0 |
|
||||||
self.functions = {} |
|
||||||
self.sortedFunctionKeys = [] |
|
||||||
|
|
||||||
try: |
|
||||||
file = open(filename, 'rb') |
|
||||||
# print "mapfile opened " + filename |
|
||||||
lines = file.readlines() |
|
||||||
file.close() |
|
||||||
self.ParseMapfile(lines) |
|
||||||
except IOError: |
|
||||||
# print 'mapfile not found: ' + filename |
|
||||||
pass |
|
||||||
|
|
||||||
#========================================================================= |
|
||||||
def ParseMapfile (self, lines): |
|
||||||
# Preferred load address is xxxxxxxx |
|
||||||
pattern = re.compile('\s*Preferred.*([\dA-Fa-f]{8})') |
|
||||||
for line in lines: |
|
||||||
match = pattern.match(line) |
|
||||||
if not match: |
|
||||||
continue |
|
||||||
self.prefLoadAddr = int(match.group(1), 16) |
|
||||||
break |
|
||||||
|
|
||||||
# section:baseAddr functionName relocAddr flags module |
|
||||||
pattern = re.compile('^\s?([\dA-Fa-f]{4}:[\dA-Fa-f]{8})\s+(\S+)\s+([\dA-Fa-f]{8})\s(.)\s.\s(\S+)') |
|
||||||
for line in lines: |
|
||||||
match = pattern.match(line) |
|
||||||
if not match: |
|
||||||
continue |
|
||||||
baseAddr = match.group(1) |
|
||||||
name = match.group(2) |
|
||||||
relocAddr = int(match.group(3), 16) |
|
||||||
if match.group(4) != 'f': |
|
||||||
continue |
|
||||||
module = match.group(5) |
|
||||||
if self.functions.has_key(relocAddr): |
|
||||||
# print " duplicate: %s %08x %s" % (baseAddr, relocAddr, name) |
|
||||||
# print " with : %s %08x %s" % (self.functions[relocAddr].baseAddr, self.functions[relocAddr].relocAddr, self.functions[relocAddr].name) |
|
||||||
pass |
|
||||||
else: |
|
||||||
self.functions[relocAddr] = Function(name, baseAddr, relocAddr, module) |
|
||||||
|
|
||||||
self.sortedFunctionKeys = self.functions.keys() |
|
||||||
self.sortedFunctionKeys.sort() |
|
||||||
# print " function count: %u" % (len(self.sortedFunctionKeys)) |
|
||||||
|
|
||||||
#========================================================================= |
|
||||||
def FindNearestFunction (self, relocAddr): |
|
||||||
|
|
||||||
#===================================================================== |
|
||||||
def eval (a, b=relocAddr): |
|
||||||
return b > a |
|
||||||
|
|
||||||
index = bsearch(self.sortedFunctionKeys, eval) |
|
||||||
if index > 0 and index < len(self.sortedFunctionKeys): |
|
||||||
return self.functions[self.sortedFunctionKeys[index-1]] |
|
||||||
return Function("<FunctionNotFound> relocAddr %x" % (relocAddr), 0, relocAddr, self.filename) |
|
||||||
|
|
||||||
#============================================================================= |
|
||||||
def LoadMapfile (mapfilename): |
|
||||||
global s_mapfiles |
|
||||||
if not s_mapfiles.has_key(mapfilename): |
|
||||||
s_mapfiles[mapfilename] = Mapfile(mapfilename) |
|
||||||
return s_mapfiles[mapfilename] |
|
||||||
|
|
||||||
|
|
||||||
#***************************************************************************** |
|
||||||
#* |
|
||||||
#* Module class |
|
||||||
#* |
|
||||||
#*** |
|
||||||
|
|
||||||
class Module: |
|
||||||
#========================================================================= |
|
||||||
def __init__ (self, loadAddr, name, buildId, buildMark): |
|
||||||
# print 'module: %s:%u, loadaddr: %08x' % (name, buildId, loadAddr) |
|
||||||
self.loadAddr = loadAddr |
|
||||||
self.name = name |
|
||||||
self.buildMark = buildMark |
|
||||||
self.buildId = buildId |
|
||||||
mapfilename = s_mapFileBasePath + buildMark + '\\' + name.split('.')[0].split('_')[0] + '.map' |
|
||||||
self.mapfile = LoadMapfile(mapfilename) |
|
||||||
|
|
||||||
#========================================================================= |
|
||||||
def FindNearestFunction (self, trueAddr): |
|
||||||
relocAddr = trueAddr + self.mapfile.prefLoadAddr - self.loadAddr |
|
||||||
# print 'searching for function near Pc:%08x, Ra:%08x in %s' % (trueAddr, relocAddr, self.mapfile.filename) |
|
||||||
function = self.mapfile.FindNearestFunction(relocAddr) |
|
||||||
if function: |
|
||||||
# print " found function %s, Ra:%08x, %s" % (function.baseAddr, function.relocAddr, function.name) |
|
||||||
return function |
|
||||||
print "Function not found for Pc:%08x, Ra:%08x in %s" % (trueAddr, relocAddr, self.mapfile.filename) |
|
||||||
return None |
|
||||||
|
|
||||||
|
|
||||||
#============================================================================= |
|
||||||
def FindNearestModule (loadAddr): |
|
||||||
|
|
||||||
#========================================================================= |
|
||||||
def eval (a, b=loadAddr): |
|
||||||
return b > a |
|
||||||
|
|
||||||
global s_modules |
|
||||||
global s_sortedModuleKeys |
|
||||||
|
|
||||||
if len(s_sortedModuleKeys) == 0: |
|
||||||
return None |
|
||||||
|
|
||||||
index = bsearch(s_sortedModuleKeys, eval) |
|
||||||
if index > 0 and index <= len(s_sortedModuleKeys): |
|
||||||
return s_modules[s_sortedModuleKeys[index-1]] |
|
||||||
|
|
||||||
print "Module not found for loadAddr %08x" % (loadAddr) |
|
||||||
return Module(loadAddr, "<ModuleNotFound> loadAddr %x" %(loadAddr), 0, "<NoBuildMark>") |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#***************************************************************************** |
|
||||||
#* |
|
||||||
#* pnCrash class |
|
||||||
#* |
|
||||||
#*** |
|
||||||
|
|
||||||
class pnCrash: |
|
||||||
#========================================================================= |
|
||||||
def SendCrash (self, msgLines, smtp): |
|
||||||
pass |
|
||||||
|
|
||||||
#========================================================================= |
|
||||||
def GetModules (self, msgLines): |
|
||||||
global s_modules |
|
||||||
global s_sortedModuleKeys |
|
||||||
# Parse modules and open mapfiles |
|
||||||
pattern = re.compile('^([\dA-Fa-f]{8})\s(.*)\((\d+)\.\d+\.(.*)\)') |
|
||||||
for line in msgLines: |
|
||||||
match = pattern.match(line) |
|
||||||
if not match: |
|
||||||
continue |
|
||||||
loadAddr = int(match.group(1), 16) |
|
||||||
filename = os.path.basename(match.group(2)).strip() |
|
||||||
buildId = int(match.group(3)) |
|
||||||
buildMark = match.group(4) |
|
||||||
#assert not s_modules.has_key(loadAddr) |
|
||||||
s_modules[loadAddr] = Module(loadAddr, filename, buildId, buildMark) |
|
||||||
s_sortedModuleKeys = s_modules.keys() |
|
||||||
s_sortedModuleKeys.sort() |
|
||||||
|
|
||||||
# if no modules found, use the reporting application's info |
|
||||||
if len(s_sortedModuleKeys) == 0: |
|
||||||
buildId = 0 |
|
||||||
loadAddr = int('00400000', 16) # temp hack |
|
||||||
patternApp = re.compile('^App\s+:\s+(.*)') |
|
||||||
patternBuildMark = re.compile('^BuildMark\s+:\s+(.*)') |
|
||||||
for line in msgLines: |
|
||||||
if patternApp: |
|
||||||
match = patternApp.match(line) |
|
||||||
if match: |
|
||||||
patternApp = None |
|
||||||
filename = os.path.basename(match.group(1)).strip().strip('\r\n') |
|
||||||
continue |
|
||||||
else: |
|
||||||
match = patternBuildMark.match(line) |
|
||||||
if match: |
|
||||||
buildMark = match.group(1).strip().strip('\r\n') |
|
||||||
# print 'No modules found, adding %s, %08x, %u, %s' % (filename, loadAddr, buildId, buildMark) |
|
||||||
s_modules[loadAddr] = Module(loadAddr, filename, buildId, buildMark) |
|
||||||
s_sortedModuleKeys = s_modules.keys() |
|
||||||
s_sortedModuleKeys.sort() |
|
||||||
break |
|
||||||
|
|
||||||
|
|
||||||
#========================================================================= |
|
||||||
def ConvertTraces (self, msgLines): |
|
||||||
lines = [] |
|
||||||
callstack = [] |
|
||||||
intrace = False |
|
||||||
|
|
||||||
pattern = re.compile('Pc:([\dA-Fa-f]{8})\s+Fr:[\dA-Fa-f]{8}\s+Rt:([\dA-Fa-f]{8})') |
|
||||||
for rawline in msgLines: |
|
||||||
line = rawline.strip('\r\n') |
|
||||||
if line.find('|') >= 0: # a previous conversion, skip over it |
|
||||||
continue |
|
||||||
lines.append(line) |
|
||||||
match = pattern.match(line) |
|
||||||
if not match: |
|
||||||
if intrace: |
|
||||||
callstack.append('') |
|
||||||
lines += callstack |
|
||||||
callstack = [] |
|
||||||
lines.append('') |
|
||||||
intrace = False |
|
||||||
continue |
|
||||||
if not intrace: |
|
||||||
callstack.append('|--------> Callstack <--------') |
|
||||||
intrace = True |
|
||||||
returnAddr = int(match.group(2), 16) |
|
||||||
if not returnAddr: |
|
||||||
continue |
|
||||||
programCounter = int(match.group(1), 16) |
|
||||||
module = FindNearestModule(programCounter) |
|
||||||
function = module.FindNearestFunction(programCounter) |
|
||||||
callstack.append('| %s, %s:%s' % (function.name, function.module, module.name)) |
|
||||||
|
|
||||||
if intrace: |
|
||||||
callstack.append('') |
|
||||||
lines += callstack |
|
||||||
callstack = [] |
|
||||||
intrace = False |
|
||||||
|
|
||||||
return lines |
|
||||||
|
|
||||||
|
|
||||||
#========================================================================= |
|
||||||
def ProcessClientCrash(self, msgLines): |
|
||||||
lines = [] |
|
||||||
fd = open('untranslated.txt', 'w') |
|
||||||
for x in msgLines: |
|
||||||
fd.write(x) |
|
||||||
fd.write('\n') |
|
||||||
fd.close() |
|
||||||
os.spawnl(os.P_WAIT, 'plStackTrace.exe', 'plStackTrace.exe', 'untranslated.txt') |
|
||||||
fd = open('out.txt', 'r') |
|
||||||
lines = fd.readlines() |
|
||||||
return lines |
|
||||||
|
|
||||||
|
|
||||||
#========================================================================= |
|
||||||
def ProcessCrash (self, msgLines, smtp): |
|
||||||
global s_modules |
|
||||||
global s_sortedModuleKeys |
|
||||||
|
|
||||||
subject = '[Crash]' |
|
||||||
pattern = re.compile('^Subject: (.*)$') |
|
||||||
serverPattern = re.compile('App : plServer.exe') |
|
||||||
serverCrash = 0 |
|
||||||
|
|
||||||
for line in msgLines: |
|
||||||
match = serverPattern.match(line) |
|
||||||
if match: |
|
||||||
serverCrash = 1 |
|
||||||
break |
|
||||||
|
|
||||||
if not serverCrash: |
|
||||||
subject = 'Client Crash Report' |
|
||||||
|
|
||||||
for line in msgLines: |
|
||||||
match = pattern.match(line) |
|
||||||
if match: |
|
||||||
subject = match.group(1) |
|
||||||
subject.strip('\r\n') |
|
||||||
|
|
||||||
from_ = 'crash2@cyan.com' |
|
||||||
pattern = re.compile('^From: (.*)$') |
|
||||||
for line in msgLines: |
|
||||||
match = pattern.match(line) |
|
||||||
if match: |
|
||||||
from_ = match.group(1) |
|
||||||
from_.strip('\r\n') |
|
||||||
break |
|
||||||
|
|
||||||
print "Rcvd: %s from %s" % (subject, from_) |
|
||||||
|
|
||||||
smtp.helo() |
|
||||||
smtp.mail(from_, []) |
|
||||||
for rcpt in s_smtpRecipients: |
|
||||||
smtp.rcpt(rcpt, []) |
|
||||||
|
|
||||||
lines = [] |
|
||||||
lines.append('From: %s' % (from_)) |
|
||||||
lines.append('Subject: %s' % (subject)) |
|
||||||
lines.append('') |
|
||||||
|
|
||||||
if not serverCrash: |
|
||||||
lines += self.ProcessClientCrash(msgLines) # process client callstack |
|
||||||
for x in range(len(lines)): |
|
||||||
lines[x] = lines[x].strip('\r\n') |
|
||||||
|
|
||||||
if serverCrash: |
|
||||||
s_modules.clear() |
|
||||||
s_sortedModuleKeys = [] |
|
||||||
self.GetModules(msgLines) |
|
||||||
lines += self.ConvertTraces(msgLines) |
|
||||||
s_sortedModuleKeys = [] |
|
||||||
s_modules.clear() |
|
||||||
|
|
||||||
msg = '\n'.join([line for line in lines]) |
|
||||||
smtp.data(msg) |
|
||||||
print "Sent: %s from %s" % (subject, from_) |
|
||||||
|
|
||||||
|
|
||||||
#========================================================================= |
|
||||||
def GetAndProcessCrashes (self): |
|
||||||
global s_mapfiles |
|
||||||
s_mapfiles.clear() |
|
||||||
|
|
||||||
# print "initializing pop3" |
|
||||||
pop3 = poplib.POP3(s_pop3Srv) |
|
||||||
pop3.user(s_pop3User) |
|
||||||
pop3.pass_(s_pop3Pass) |
|
||||||
pop3.list() |
|
||||||
(numMsgs, totalSize) = pop3.stat() |
|
||||||
|
|
||||||
if numMsgs > 0: |
|
||||||
# print "initializing smtp" |
|
||||||
smtp = smtplib.SMTP(s_smtpSrv) |
|
||||||
|
|
||||||
# print "retrieving emails" |
|
||||||
for i in range(1, numMsgs + 1): |
|
||||||
(header, msg, octets) = pop3.retr(i) |
|
||||||
self.ProcessCrash(msg, smtp) |
|
||||||
pop3.dele(i) |
|
||||||
|
|
||||||
smtp.quit() |
|
||||||
|
|
||||||
pop3.quit() |
|
||||||
|
|
||||||
s_mapfiles.clear() |
|
||||||
|
|
||||||
#========================================================================= |
|
||||||
def RunForever (self): |
|
||||||
global s_modules |
|
||||||
s_modules[0] = Module(0, "<NilModule>", 0, "<NilBuild>") |
|
||||||
while 1: |
|
||||||
self.GetAndProcessCrashes() |
|
||||||
# sleep for an interruptable minute |
|
||||||
for i in range(1, 20): |
|
||||||
time.sleep(1) |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#***************************************************************************** |
|
||||||
#* |
|
||||||
#* Program entry point |
|
||||||
#* |
|
||||||
#*** |
|
||||||
|
|
||||||
#============================================================================= |
|
||||||
if __name__ == '__main__': |
|
||||||
pnCrash().RunForever() |
|
Loading…
Reference in new issue