有沒有辦法讓任何恐慌發生,如有斷點一樣掉進調試器?使用Carbide.c調試Symbian OS中的恐慌使用Carbide.C++
我正在使用Carbide.C++ 2.3.0。我瞭解「調試配置」>「x86異常」,但它僅涵蓋實際應用程序中實際發生的一小部分內容。例如,它不會陷入用戶恐慌,或者當應用程序退出時發生內存泄漏,ALLOC恐慌。
有沒有辦法讓任何恐慌發生,如有斷點一樣掉進調試器?使用Carbide.c調試Symbian OS中的恐慌使用Carbide.C++
我正在使用Carbide.C++ 2.3.0。我瞭解「調試配置」>「x86異常」,但它僅涵蓋實際應用程序中實際發生的一小部分內容。例如,它不會陷入用戶恐慌,或者當應用程序退出時發生內存泄漏,ALLOC恐慌。
如果您使用模擬器,您可以通過啓用「即時調試」來調試恐慌。這是通過添加以下行epoc32\data\epoc.ini
完成:
JustInTime debug
有關詳細信息,請參閱epoc.ini reference in the SDK documentation。
據我所知,無法完成。
我所做的就是使用簡單的函數跟蹤邏輯,所以當發生恐慌時,我在恐慌處理代碼(我註銷)的恐慌點處有一個堆棧跟蹤。除了你必須記住在每個函數的開始處添加你的宏之外,這很好。
例如
#ifndef NDEBUG
class __FTrace
{
__FTrace(const char* function)
{
TraceManager::GetInstance().EnterFunction(function);
}
~__FTrace()
{
TraceManager::GetInstance().LeaveFunction(function);
}
};
#define FTRACE() __FTrace(__PRETTY_FUNCTION__)
#else
#define FTRACE()
#endif
void Func()
{
FTRACE();
...
}
對於ALLOC,我在模擬器下的Hook Logger獲得了很多成功。這是一個真正的痛苦設置和使用,但它會使真正容易追蹤ALLOC內存泄漏。
更新:根據要求,這是我的恐慌處理代碼的樣子。請注意,我的應用程序必須始終在後臺運行,所以它設置爲在發生問題時重新啓動應用程序。此代碼適用於第三版SDK,我沒有在SDK的更高版本上嘗試過。
重點是在另一個線程中運行主應用程序,然後等待它退出。然後檢查線程退出的原因,爲未知原因退出線程,記錄類似於我自己的堆棧跟蹤的內容並重新啓動應用程序。
TInt StartMainThread(TAny*)
{
FTRACE();
__LOGSTR_TOFILE("Main Thread Start");
TInt result(KErrNone);
TRAPD(err, result = EikStart::RunApplication(NewApplication));
if(KErrNone != err || KErrNone != result)
{
__LOGSTR_TOFILE("EikStart::RunApplication error: trap(%d), %d", err, result);
}
__LOGSTR_TOFILE("Main Thread End");
return result;
}
const TInt KMainThreadToLiveInSeconds = 10;
} // namespace *unnamed*
LOCAL_C CApaApplication* NewApplication()
{
FTRACE();
return new CMainApplication;
}
GLDEF_C TInt E32Main()
{
#ifdef NDEBUG
__LOGSTR_TOFILE("Application Start (release)");
#else
__LOGSTR_TOFILE("Application Start (debug)");
#endif
#ifndef NO_TRACING
__TraceManager::NewL();
#endif // !NO_TRACING
RHeap& heap(User::Heap());
TInt heapsize=heap.MaxLength();
TInt exitReason(KErrNone);
TTime timeToLive;
timeToLive.UniversalTime();
timeToLive += TTimeIntervalSeconds(KMainThreadToLiveInSeconds);
LManagedHandle<RThread> mainThread;
TInt err = mainThread->Create(_L("Main Thread"), StartMainThread, KDefaultStackSize, KMinHeapSize, heapsize, NULL);
if (KErrNone != err)
{
__LOGSTR_TOFILE("MainThread failed : %d", err);
return err;
}
mainThread->SetPriority(EPriorityNormal);
TRequestStatus status;
mainThread->Logon(status);
mainThread->Resume();
User::WaitForRequest(status);
exitReason = mainThread->ExitReason();
TExitCategoryName category(mainThread->ExitCategory());
switch(mainThread->ExitType())
{
case EExitKill:
__LOGSTR_TOFILE("ExitKill : (%S) : %d", &category, exitReason);
break;
case EExitTerminate:
__LOGSTR_TOFILE("ExitTerminate : (%S) : %d", &category, exitReason);
break;
case EExitPanic:
__LOGSTR_TOFILE("ExitPanic : (%S) : %d", &category, exitReason);
break;
default:
__LOGSTR_TOFILE("ExitUnknown : (%S) : %d", &category, exitReason);
break;
}
#ifndef NO_TRACING
__TraceManager::GetInstance().LogStackTrace();
#endif // NO_TRACING
if(KErrNone != status.Int())
{
TTime now;
now.UniversalTime();
if (timeToLive > now)
{
TTimeIntervalMicroSeconds diff = timeToLive.MicroSecondsFrom(now);
__LOGSTR_TOFILE("Exiting due to TTL : (%Lu)", diff.Int64());
}
else
{
RProcess current;
RProcess restart;
err = restart.Create(current.FileName(), _L(""));
if(KErrNone == err)
{
__LOGSTR_TOFILE("Restarting...");
restart.Resume();
return KErrNone;
}
else
{
__LOGSTR_TOFILE("Failed to start app: %d", err);
}
}
}
__LOGSTR_TOFILE("Application End");
return exitReason;
}
令人驚歎的,它真的有用! 我一直在想,Symbian工具和文檔是多麼模糊。確定恐慌發生的位置是非常重要的任務,但沒有人知道如何去做!即使現在當你指向我的文檔時,也沒有任何跡象表明JustInTime選項與恐慌誘捕有關。 非常感謝! – SnakE 2010-09-01 12:59:05
@SnakE:真的,該epoc.ini關鍵字的文檔不是很清楚。那些實際上由於'JustInTime debug','User :: SetJustInTime(TBool)'而被調用的用戶庫函數會更好一些。 – 2010-09-01 15:24:16