5.06.2010

tcpmp source code - use default language, exception

tcpmp 會利用 GetLocaleInfo( ) 來取得 platform 的語系資訊。

如過想要強制使用英文,可以修改 platform_win32.c 的 DefaultLang( ),強制 return LANG_DEFAULT 就可以。

tcpmp 還有一段 : SafeException( ) ,將整個 code body 包起來:
#define SAFE_BEGIN __try {
.... code body...
#define SAFE_END ;} __except (SafeException(_exception_info())) {}
SafeException( ) 的 funciton 是:
int SafeException(void* p)
{
EXCEPTION_POINTERS* Data = (EXCEPTION_POINTERS*)p;
stream* File;
tchar_t Path[MAXPATH];

if (Context())
{
GetDebugPath(Path,TSIZEOF(Path),T("crash.txt"));
File = StreamOpen(Path,1);
if (File)
{
void** Stack;
contextreg* r;
int No;
const uint8_t* ContextRecord = (const uint8_t*) Data->ContextRecord;
EXCEPTION_RECORD* Record = Data->ExceptionRecord;
tchar_t* Name;
int DllBase;
tchar_t DllName[MAXPATH];

StreamPrintf(File,T("%s %s crash report\n----------------------------\n"),
Context()->ProgramName,Context()->ProgramVersion);

switch (Record->ExceptionCode)
{
case STATUS_ACCESS_VIOLATION: Name = T("Access violation"); break;
case STATUS_BREAKPOINT: Name = T("Breakpoint"); break;
case STATUS_DATATYPE_MISALIGNMENT: Name = T("Datatype misalignment"); break;
case STATUS_ILLEGAL_INSTRUCTION: Name = T("Illegal instruction"); break;
case STATUS_INTEGER_DIVIDE_BY_ZERO: Name = T("Int divide by zero"); break;
case STATUS_INTEGER_OVERFLOW: Name = T("Int overflow"); break;
case STATUS_PRIVILEGED_INSTRUCTION: Name = T("Priv instruction"); break;
case STATUS_STACK_OVERFLOW: Name = T("Stack overflow"); break;
default: Name = T("Unknown"); break;
}

if (!NodeLocatePtr(Record->ExceptionAddress,DllName,TSIZEOF(DllName),&DllBase))
{
DllName[0] = 0;
DllBase = (int)Record->ExceptionAddress;
}
StreamPrintf(File,T("%s(%08x) at %08x (%s:%08x)"),Name,Record->ExceptionCode,Record->ExceptionAddress,DllName,DllBase);

if (Record->ExceptionCode == STATUS_ACCESS_VIOLATION)
{
if (Record->ExceptionInformation[0])
Name = T("Write to");
else
Name = T("Read from");
StreamPrintf(File,T("\n%s %08x"),Name,Record->ExceptionInformation[1]);
if (NodeLocatePtr((void*)Record->ExceptionInformation[1],DllName,TSIZEOF(DllName),&DllBase))
StreamPrintf(File,T(" (%s:%08x)"),DllName,DllBase);
}

// context

StreamPrintf(File,T("\n\ncpu dump:"));

for (r=Reg;r->Name;++r)
{
void* Ptr = *(void**)(ContextRecord+r->Ofs);

StreamPrintf(File,T("\n%-5s = %08x"),r->Name,Ptr);

if (NodeLocatePtr(Ptr,DllName,TSIZEOF(DllName),&DllBase))
StreamPrintf(File,T(" (%s:%08x)"),DllName,DllBase);
}

if (r->Ofs >= 0)
{
StreamPrintf(File,T("\n\nstack dump:"));

Stack = *(void***)(ContextRecord+r->Ofs);
for (No=0;No<256;++No,++Stack)
{
if (!IsBadReadPtr(Stack,sizeof(void*)))
{
void* Ptr = *Stack;

StreamPrintf(File,T("\n%08x %08x"),Stack,Ptr);

if (NodeLocatePtr(Ptr,DllName,TSIZEOF(DllName),&DllBase))
StreamPrintf(File,T(" (%s:%08x)"),DllName,DllBase);
}
else
StreamPrintf(File,T("\n%08x ????????"),Stack);
}
}

StreamPrintf(File,T("\n\n"));
TRY_BEGIN
{
NodeBroadcast(NODE_CRASH,NULL,0);
}
TRY_END
NodeDump(File);
StreamClose(File);
}

MessageBox(NULL,LangStr(PLATFORM_ID,PLATFORM_CRASH_MESSAGE),
LangStr(PLATFORM_ID,PLATFORM_CRASH_TITLE),MB_OK|MB_SETFOREGROUND|MB_TOPMOST|MB_ICONSTOP);
}

Mem_Done(); // use safevirtualfree (if done by OS, it could be buggy on O2 Atom)
TerminateProcess(GetCurrentProcess(),1);
return 1;
}
就是把 exception 的資料存入 crash.txt。


有關 ce 的 try except,在這一篇有說明 http://windows-ce-dox.net/MS.Press-Programming.Microsoft/html/ch087.htm

沒有留言: