Debugging 使用Carbide.c++;

Debugging 使用Carbide.c++;,debugging,symbian,carbide,panic,Debugging,Symbian,Carbide,Panic,有没有一种方法可以在出现任何死机(如有断点)时进入调试器 我使用的是碳化物.C++ +2.3.0。我知道Debug Configurations>x86异常,但它只涵盖了实际应用程序中实际发生的一小部分。例如,当应用程序因内存泄漏而退出时,它不会捕获用户恐慌或ALLOC恐慌。据我所知,这是不可能做到的 我所做的是使用简单的函数跟踪逻辑,所以当发生恐慌时,我在恐慌处理代码(我注销)中的恐慌点有一个堆栈跟踪。这很有效,只是您必须记住在每个函数的开头添加宏 e、 g 对于ALLOC,我已经在emula

有没有一种方法可以在出现任何死机(如有断点)时进入调试器


我使用的是碳化物.C++ +2.3.0。我知道Debug Configurations>x86异常,但它只涵盖了实际应用程序中实际发生的一小部分。例如,当应用程序因内存泄漏而退出时,它不会捕获用户恐慌或ALLOC恐慌。

据我所知,这是不可能做到的

我所做的是使用简单的函数跟踪逻辑,所以当发生恐慌时,我在恐慌处理代码(我注销)中的恐慌点有一个堆栈跟踪。这很有效,只是您必须记住在每个函数的开头添加宏

e、 g

对于ALLOC,我已经在emulator下成功使用了很多。设置和使用它确实很痛苦,但它将使跟踪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;
    }
TInt StartMainThread(TAny*)
{
FTRACE();
__LOGSTR_-TOFILE(“主线程启动”);
着色结果(无);
TRAPD(err,result=EikStart::RunApplication(NewApplication));
如果(KErrNone!=错误| | KErrNone!=结果)
{
__日志文件(“EikStart::RunApplication错误:陷阱(%d),%d”,错误,结果);
}
__LOGSTR_-TOFILE(“主螺纹端”);
返回结果;
}
const TInt KMainThreadToLiveInSeconds=10;
}//名称空间*未命名*
本地应用程序*NewApplication()
{
FTRACE();
退回新申请;
}
GLDEF_C色调E32Main()
{
#ifdef-NDEBUG
__LOGSTR_-TOFILE(“应用程序启动(发布)”);
#否则
__LOGSTR_-TOFILE(“应用程序启动(调试)”);
#恩迪夫
#ifndef无跟踪
__TraceManager::NewL();
#endif/!无跟踪
RHeap&heap(User::heap());
TInt heapsize=heap.MaxLength();
着色exitReason(KErrNone);
时间生命;
timeToLive.UniversalTime();
timeToLive+=TTimeIntervalSeconds(kmainthreadtoliveinsonds);
LManagedHandle主线程;
TInt err=mainThread->Create(_L(“主线程”)、StartMainThread、KDefaultStackSize、KMinHeapSize、heapsize、NULL);
如果(无!=错误)
{
__日志文件(“主线程失败:%d”,错误);
返回错误;
}
主线程->设置优先级(EPriorityNormal);
TRequestStatus状态;
主线程->登录(状态);
主线程->恢复();
用户::WaitForRequest(状态);
exitReason=main线程->exitReason();
TExitCategoryName类别(主线程->ExitCategory());
开关(mainThread->ExitType())
{
案例EExitKill:
__日志文件(“ExitKill:(%S):%d”,&category,exitReason);
打破
案例E终止:
__日志文件(“出口:(%S):%d”和类别,出口);
打破
案例1:
__日志文件(“ExitPanic:(%S):%d”和类别,exitReason);
打破
违约:
__日志文件(“ExitUnknown:(%S):%d”和类别,exitReason);
打破
}
#ifndef无跟踪
__TraceManager::GetInstance().LogStackTrace();
#endif//NO\u跟踪
if(KErrNone!=status.Int())
{
此时此刻;
现在。UniversalTime();
如果(时间生活>现在)
{
TTimeIntervalMicroSeconds diff=时间间隔微秒(现在);
__LOGSTR_-TOFILE(“由于TTL而退出:(%Lu)”,diff.Int64();
}
其他的
{
r过程电流;
r进程重启;
err=restart.Create(当前.FileName(),_L(“”);
if(KErrNone==err)
{
__日志文件(“重新启动…”);
restart.Resume();
返回无;
}
其他的
{
__日志文件(“无法启动应用程序:%d”,错误);
}
}
}
__日志文件(“应用程序端”);
退出境;
}

如果您使用的是emulator,您可以通过启用“即时调试”来调试恐慌。通过将以下行添加到
epoc32\data\epoc.ini

JustInTime debug

有关更多详细信息,请参阅。

这里最有趣的部分是您似乎忽略的“紧急处理代码”。)如果它真的能在代码中出现恐慌时做一些有用的事情。谢谢你的钩子记录器指针。这可能真的很方便。恐慌处理代码没有什么特别之处。我会用我的紧急处理代码更新答案。谢谢你的更新。分离线程的技巧非常好。我认为您的解决方案在生产环境中是不可或缺的,您希望在生产环境中防止严重的bug。令人惊讶的是,它确实有效!我一直想知道Symbian工具和文档有多晦涩。确定恐慌发生在哪里是一项非常重要的任务,但是没有人知道怎么做!即使是现在,当你指给我看文档时,也没有迹象表明JustInTime选项与恐慌陷阱有关。多谢各位@没错,epoc.ini关键字的文档不是很清楚。由于
JustInTime调试
user::SetJustInTime(TBool)
的结果而实际被调用的用户库函数的性能要好一些。
JustInTime debug