سؤال

هل هناك طريقة لإسقاط الأخطاء عندما أي يحدث الذعر كما لو كان هناك نقطة توقف؟

أنا أستخدم carbide.c ++ 2.3.0. أعرف استثناءات تصحيح التصحيح> x86 ، لكنها تغطي جزءًا صغيرًا فقط مما يمكن أن يحدث بالفعل في تطبيق حقيقي. على سبيل المثال ، لا يرتدي ذعر المستخدم ، أو تخصيص الذعر عندما يخرج التطبيق مع تسرب الذاكرة.

هل كانت مفيدة؟

المحلول

إذا كنت تستخدم المحاكي ، فيمكنك تصحيح الذعر من خلال تمكين "تصحيح الأخطاء في الوقت المناسب. يتم ذلك عن طريق إضافة السطر التالي إلى epoc32\data\epoc.ini:

JustInTime debug

لمزيد من التفاصيل ، راجع مرجع epoc.ini في وثائق SDK.

نصائح أخرى

على حد علمي لا يمكن القيام به.

ما قمت به هو استخدام منطق تتبع الوظائف البسيط ، لذا عندما يحدث الذعر ، يكون لدي تتبع مكدس عند نقطة الذعر في رمز معالجة الذعر (الذي أسجله). هذا يعمل بشكل جيد باستثناء حقيقة أنه عليك أن تتذكر إضافة ماكروك في بداية كل وظيفة.

على سبيل المثال

#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();
    ...
}

من أجل alyoc ، لقد حققت نجاحًا كبيرًا مع خطاف المسجل تحت المحاكي. إنه ألم حقيقي لإعداده واستخدامه ، لكنه سيجعل من السهل تعقب تسريبات الذاكرة المخصصة لأسفل.

تحديث: كما هو مطلوب ، إليك ما يبدو عليه رمز معالجة الذعر. لاحظ أن طلبي يجب أن يعمل في الخلفية طوال الوقت ، لذلك يتم إعداده لإعادة تشغيل التطبيق عندما يحدث شيء سيء. كما يعمل هذا الرمز في الإصدار الثالث من SDK ، لم أجربه في الإصدارات اللاحقة من SDK's.

النقطة المهمة هي تشغيل التطبيق الرئيسي في موضوع آخر ثم انتظر حتى الخروج. ثم تحقق لمعرفة سبب خروج مؤشر الترابط ، فإن الخيط كما تم الخروج منه لأسباب غير معروفة ، وتسجيل أشياء مثل تتبع المكدس الخاص بي وإعادة تشغيل التطبيق.

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;
    }
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top