memspy/Driver/Kernel/Source/SubChannels/MemSpyDriverLogChanThreadAndProcess.cpp
changeset 0 a03f92240627
equal deleted inserted replaced
-1:000000000000 0:a03f92240627
       
     1 /*
       
     2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:
       
    15 *
       
    16 */
       
    17 
       
    18 #include "MemSpyDriverLogChanThreadAndProcess.h"
       
    19 
       
    20 // System includes
       
    21 #include <platform.h>
       
    22 #include <memspy/driver/memspydriverobjectsshared.h>
       
    23 #include <memspy/driver/memspydriverpanics.h>
       
    24 
       
    25 // Shared includes
       
    26 #include "MemSpyDriverOpCodes.h"
       
    27 #include "MemSpyDriverObjectsInternal.h"
       
    28 
       
    29 // User includes
       
    30 #include "MemSpyDriverUtils.h"
       
    31 #include "MemSpyDriverOSAdaption.h"
       
    32 #include "MemSpyDriverSuspensionManager.h"
       
    33 
       
    34 // Constants
       
    35 const TBool KMemSpyDriverAllowDeadOpenRequests = ETrue;
       
    36 const TInt KMemSpyDriverLogChanThreadAndProcessXferBufferSize = 512;
       
    37 
       
    38 
       
    39 DMemSpyDriverLogChanThreadAndProcess::DMemSpyDriverLogChanThreadAndProcess( DMemSpyDriverDevice& aDevice, DThread& aThread )
       
    40 :   DMemSpyDriverLogChanBase( aDevice, aThread )
       
    41     {
       
    42     TRACE( Kern::Printf("DMemSpyDriverLogChanThreadAndProcess::DMemSpyDriverLogChanThreadAndProcess() - this: 0x%08x", this ));
       
    43     }
       
    44 
       
    45 
       
    46 DMemSpyDriverLogChanThreadAndProcess::~DMemSpyDriverLogChanThreadAndProcess()
       
    47 	{
       
    48 	TRACE( Kern::Printf("DMemSpyDriverLogChanThreadAndProcess::~DMemSpyDriverLogChanThreadAndProcess() - START - this: 0x%08x", this ));
       
    49 
       
    50 	TRACE( Kern::Printf("DMemSpyDriverLogChanThreadAndProcess::~DMemSpyDriverLogChanThreadAndProcess() - END - this: 0x%08x", this ));
       
    51 	}
       
    52 
       
    53 
       
    54 TInt DMemSpyDriverLogChanThreadAndProcess::Construct()
       
    55 	{
       
    56 	TRACE( Kern::Printf("DMemSpyDriverLogChanThreadAndProcess::Construct() - START - this: 0x%08x", this ));
       
    57     
       
    58     const TInt ret = BaseConstruct( KMemSpyDriverLogChanThreadAndProcessXferBufferSize );
       
    59 
       
    60 	TRACE( Kern::Printf("DMemSpyDriverLogChanThreadAndProcess::Construct() - END - this: 0x%08x, err: %d", this, ret ));
       
    61     return ret;
       
    62 	}
       
    63 
       
    64 
       
    65 TInt DMemSpyDriverLogChanThreadAndProcess::Request( TInt aFunction, TAny* a1, TAny* a2 )
       
    66 	{
       
    67 	TInt r = DMemSpyDriverLogChanBase::Request( aFunction, a1, a2 );
       
    68     if  ( r == KErrNone )
       
    69         {
       
    70 	    switch( aFunction )
       
    71 		    {
       
    72 	    case EMemSpyDriverOpCodeThreadAndProcessGetInfoThread:
       
    73 		    r = GetInfoThread( (TUint)a1, (TMemSpyDriverInternalThreadInfoParams*) a2);
       
    74 		    break;
       
    75 	    case EMemSpyDriverOpCodeThreadAndProcessGetInfoProcess:
       
    76 		    r = GetInfoProcess( (TUint)a1, (TMemSpyDriverProcessInfo*) a2);
       
    77 		    break;
       
    78         case EMemSpyDriverOpCodeThreadAndProcessEndThread:
       
    79             r = EndThread( (TUint) a1, (TExitType) ((TUint) a2) );
       
    80             break;
       
    81         case EMemSpyDriverOpCodeThreadAndProcessOpenThread:
       
    82             r = OpenThread( (TUint) a1 );
       
    83             break;
       
    84         case EMemSpyDriverOpCodeThreadAndProcessOpenProcess:
       
    85             r = OpenProcess( (TUint) a1 );
       
    86             break;
       
    87         case EMemSpyDriverOpCodeThreadAndProcessSuspendAllThreads:
       
    88             r = SuspendAllThreadsInProcess( (TUint) a1 );
       
    89             break;
       
    90         case EMemSpyDriverOpCodeThreadAndProcessResumeAllThreads:
       
    91             r = ResumeAllThreadsInProcess( (TUint) a1 );
       
    92             break;
       
    93         case EMemSpyDriverOpCodeThreadAndProcessGetThreads:
       
    94             r = GetThreadsForProcess( (TUint) a1, (TDes8*) a2 );
       
    95             break;
       
    96         case EMemSpyDriverOpCodeThreadAndProcessSetPriorityThread:
       
    97             r = SetPriority( (TUint) a1, (TThreadPriority) ((TUint) a2) );
       
    98             break;
       
    99 
       
   100         default:
       
   101             r = KErrNotSupported;
       
   102 		    break;
       
   103 		    }
       
   104         }
       
   105     //
       
   106     return r;
       
   107 	}
       
   108 
       
   109 
       
   110 TBool DMemSpyDriverLogChanThreadAndProcess::IsHandler( TInt aFunction ) const
       
   111     {
       
   112     return ( aFunction > EMemSpyDriverOpCodeThreadAndProcessBase && aFunction < EMemSpyDriverOpCodeThreadAndProcessEnd );
       
   113     }
       
   114 
       
   115 
       
   116 
       
   117 
       
   118 
       
   119 
       
   120 TInt DMemSpyDriverLogChanThreadAndProcess::GetInfoThread( TUint aTid, TMemSpyDriverInternalThreadInfoParams* aParams )
       
   121 	{
       
   122     TRACE( Kern::Printf("DMemSpyDriverLogChanThreadAndProcess::GetInfoThread() - START"));
       
   123 
       
   124     TMemSpyDriverInternalThreadInfoParams params;
       
   125     TInt r = Kern::ThreadRawRead( &ClientThread(), aParams, &params, sizeof(TMemSpyDriverInternalThreadInfoParams) );
       
   126     if  ( r != KErrNone )
       
   127         {
       
   128     	TRACE( Kern::Printf("DMemSpyDriverLogChanThreadAndProcess::GetInfoThread() - END - params read error: %d", r));
       
   129         return r;
       
   130         }
       
   131 
       
   132 	r = OpenTempObject( aTid, EThread );
       
   133 	if  ( r == KErrNone )
       
   134 		{
       
   135 		DThread* dThread = (DThread*) TempObject();
       
   136   	    NKern::ThreadEnterCS();
       
   137 
       
   138         // Get DThread adaptor. This is a means of querying DThread internals
       
   139         // without accessing them directly. Takes into account possible differences
       
   140         // between compile time and run time
       
   141         DMemSpyDriverOSAdaptionDThread& dThreadAdaptor = OSAdaption().DThread();
       
   142 
       
   143         // Saved CPU registers for thread. Need to get NThread to do this.
       
   144         NThread* nThread = dThreadAdaptor.GetNThread( *dThread );
       
   145     	TRACE( Kern::Printf("DMemSpyDriverLogChanThreadAndProcess::GetInfoThread() - getting regs..." ));
       
   146         MemSpyDriverUtils::GetThreadRegisters( nThread, params.iCpu );
       
   147 		
       
   148         // Name
       
   149     	TRACE( Kern::Printf("DMemSpyDriverLogChanThreadAndProcess::GetInfoThread() - getting full name..." ));
       
   150 		dThread->FullName( params.iFullName );
       
   151 
       
   152         // User framework
       
   153     	TRACE( Kern::Printf("DMemSpyDriverLogChanThreadAndProcess::GetInfoThread() - getting allocator..." ));
       
   154         params.iAllocator = dThreadAdaptor.GetAllocator( *dThread );
       
   155 
       
   156         TRACE( Kern::Printf("DMemSpyDriverLogChanThreadAndProcess::GetInfoThread() - getting scheduler..." ));
       
   157         params.iScheduler = dThreadAdaptor.GetActiveScheduler( *dThread );
       
   158 
       
   159         // User stack information - rest comes from user side API calls
       
   160         TRACE( Kern::Printf("DMemSpyDriverLogChanThreadAndProcess::GetInfoThread() - getting user stack pointer..." ));
       
   161         params.iStackInfo.iUserStackPointer = params.iCpu.iRn[ 12 ];
       
   162 
       
   163         // Supervisor stack information
       
   164         TRACE( Kern::Printf("DMemSpyDriverLogChanThreadAndProcess::GetInfoThread() - getting supervisor stack..." ));
       
   165         params.iStackInfo.iSupervisorStackPointer = 0;
       
   166         params.iStackInfo.iSupervisorStackHighWatermark = 0;
       
   167         params.iStackInfo.iSupervisorStackBase = dThreadAdaptor.GetSupervisorStackBase( *dThread );
       
   168         params.iStackInfo.iSupervisorStackSize = dThreadAdaptor.GetSupervisorStackSize( *dThread );
       
   169  
       
   170         // Write back to user-side
       
   171         TRACE( Kern::Printf("DMemSpyDriverLogChanThreadAndProcess::GetInfoThread() - writing to user side..." ));
       
   172         r = Kern::ThreadRawWrite( &ClientThread(), aParams, &params, sizeof(TMemSpyDriverInternalThreadInfoParams) );
       
   173 	    NKern::ThreadLeaveCS();
       
   174 		CloseTempObject();
       
   175 		}
       
   176 
       
   177     TRACE( Kern::Printf("DMemSpyDriverLogChanThreadAndProcess::GetInfoThread() - END - ret: %d", r));
       
   178     return r;
       
   179 	}
       
   180 
       
   181 
       
   182 TInt DMemSpyDriverLogChanThreadAndProcess::GetInfoProcess( TUint aPid, TMemSpyDriverProcessInfo* aParams )
       
   183 	{
       
   184     TRACE( Kern::Printf("DMemSpyDriverLogChanThreadAndProcess::GetInfoProcess() - START"));
       
   185 
       
   186     TMemSpyDriverProcessInfo params;
       
   187     TInt r = Kern::ThreadRawRead( &ClientThread(), aParams, &params, sizeof(TMemSpyDriverProcessInfo) );
       
   188     if  ( r != KErrNone )
       
   189         {
       
   190     	TRACE( Kern::Printf("DMemSpyDriverLogChanThreadAndProcess::GetInfoProcess() - END - params read error: %d", r));
       
   191         return r;
       
   192         }
       
   193 
       
   194 	r = OpenTempObject( aPid, EProcess );
       
   195 	if  ( r == KErrNone )
       
   196 		{
       
   197         DMemSpyDriverOSAdaptionDProcess& processAdaptor = OSAdaption().DProcess();
       
   198   
       
   199         DProcess* process = (DProcess*) TempObject();
       
   200   	    NKern::ThreadEnterCS();
       
   201 		//
       
   202         params.iFlags = processAdaptor.GetFlags( *process );
       
   203         params.iGeneration = processAdaptor.GetGeneration( *process );
       
   204         params.iSecurityInfo = processAdaptor.GetSecurityInfo( *process );
       
   205 
       
   206         // Write back to user-side
       
   207         r = Kern::ThreadRawWrite( &ClientThread(), aParams, &params, sizeof(TMemSpyDriverProcessInfo) );
       
   208 	    NKern::ThreadLeaveCS();
       
   209 		CloseTempObject();
       
   210 		}
       
   211 
       
   212     TRACE( Kern::Printf("DMemSpyDriverLogChanThreadAndProcess::GetInfoProcess() - END - ret: %d", r));
       
   213     return r;
       
   214 	}
       
   215 
       
   216 
       
   217 
       
   218 
       
   219 
       
   220 
       
   221 
       
   222 
       
   223 
       
   224 TInt DMemSpyDriverLogChanThreadAndProcess::EndThread( TUint aId, TExitType aType )
       
   225     {
       
   226     TRACE( Kern::Printf("DMemSpyDriverLogChanThreadAndProcess::EndThread() - START - aId: %d, aType: %d", aId, aType ));
       
   227 
       
   228 	TInt r = OpenTempObject( aId, EThread );
       
   229 	if  ( r == KErrNone )
       
   230 		{
       
   231         DThread* thread = (DThread*) TempObject();
       
   232         //
       
   233         const TInt reason = MapToMemSpyExitReason( aType );
       
   234         Kern::ThreadKill( thread, aType, reason, KMemSpyClientPanic );
       
   235         //
       
   236 	    CloseTempObject();
       
   237         }
       
   238     else
       
   239         {
       
   240         r = KErrNotFound;
       
   241         }
       
   242 
       
   243 	TRACE( Kern::Printf("DMemSpyDriverLogChanThreadAndProcess::EndThread() - END - r: %d", r));
       
   244 	return r;
       
   245     }
       
   246 
       
   247 
       
   248 
       
   249 
       
   250 
       
   251 
       
   252 
       
   253 
       
   254 
       
   255 
       
   256 
       
   257 
       
   258 
       
   259 
       
   260 
       
   261 
       
   262 
       
   263 
       
   264 
       
   265 
       
   266 
       
   267 
       
   268 TInt DMemSpyDriverLogChanThreadAndProcess::OpenThread( TUint aId )
       
   269     {
       
   270 	TRACE( Kern::Printf("DMemSpyDriverLogChanThreadAndProcess::OpenThread() - START - aId: %d", aId));
       
   271 
       
   272 	TInt r = OpenTempObject( aId, EThread, KMemSpyDriverAllowDeadOpenRequests );
       
   273 	TRACE( Kern::Printf("DMemSpyDriverLogChanThreadAndProcess::OpenThread() - done open temp object, r: %d", r ));
       
   274 	if  ( r == KErrNone )
       
   275 		{
       
   276         NKern::ThreadEnterCS();
       
   277         DThread* threadToOpen = (DThread*) TempObject();
       
   278         TRACE( Kern::Printf("DMemSpyDriverLogChanThreadAndProcess::OpenThread() - thread exit type: %d", threadToOpen->iExitType ));
       
   279 
       
   280         TRACE( Kern::Printf("DMemSpyDriverLogChanThreadAndProcess::OpenThread() - making handle..." ));
       
   281         r = Kern::MakeHandleAndOpen( &ClientThread(), threadToOpen );
       
   282 	    TRACE( Kern::Printf("DMemSpyDriverLogChanThreadAndProcess::OpenThread() - handle: %d",r ));
       
   283     	NKern::ThreadLeaveCS();
       
   284 
       
   285         // Balance reference count, handle is still open and mapped into our process since we opened
       
   286         // it above via MakeHandleAndOpen
       
   287 	    TRACE( Kern::Printf("DMemSpyDriverLogChanThreadAndProcess::OpenThread() - closing temp object..." ));
       
   288 	    CloseTempObject();
       
   289 	    TRACE( Kern::Printf("DMemSpyDriverLogChanThreadAndProcess::OpenThread() - closed temp object" ));
       
   290         }
       
   291     else
       
   292         {
       
   293         r = KErrNotFound;
       
   294         }
       
   295 
       
   296 	TRACE( Kern::Printf("DMemSpyDriverLogChanThreadAndProcess::OpenThread() - END - r: %d", r));
       
   297 	return r;
       
   298     }
       
   299 
       
   300 
       
   301 TInt DMemSpyDriverLogChanThreadAndProcess::OpenProcess( TUint aId )
       
   302     {
       
   303 	TRACE( Kern::Printf("DMemSpyDriverLogChanThreadAndProcess::OpenProcess() - START - aId: %d", aId));
       
   304 
       
   305 	TInt r = OpenTempObject( aId, EProcess, KMemSpyDriverAllowDeadOpenRequests );
       
   306 	if  ( r == KErrNone )
       
   307 		{
       
   308         NKern::ThreadEnterCS();
       
   309         DProcess* processToOpen = (DProcess*) TempObject();
       
   310         r = Kern::MakeHandleAndOpen( &ClientThread(), processToOpen );
       
   311     	NKern::ThreadLeaveCS();
       
   312 
       
   313         // Balance reference count, handle is still open and mapped into our process since we opened
       
   314         // it above via MakeHandleAndOpen
       
   315 	    CloseTempObject();
       
   316         }
       
   317     else
       
   318         {
       
   319         r = KErrNotFound;
       
   320         }
       
   321 
       
   322 	TRACE( Kern::Printf("DMemSpyDriverLogChanThreadAndProcess::OpenProcess() - END - r: %d", r));
       
   323 	return r;
       
   324     }
       
   325 
       
   326 
       
   327 
       
   328 
       
   329 
       
   330 
       
   331 
       
   332 
       
   333 
       
   334 
       
   335 
       
   336 
       
   337 
       
   338 
       
   339 
       
   340 
       
   341 
       
   342 
       
   343 
       
   344 
       
   345 
       
   346 
       
   347 
       
   348 
       
   349 
       
   350 
       
   351 
       
   352 
       
   353 
       
   354 TInt DMemSpyDriverLogChanThreadAndProcess::SuspendAllThreadsInProcess( TUint aPid )
       
   355     {
       
   356 	TRACE( Kern::Printf( "DMemSpyDriverLogChanThreadAndProcess::SuspendAllThreadsInProcess() - START - aPid: %d", aPid ));
       
   357 
       
   358     DMemSpySuspensionManager& susMan = SuspensionManager();
       
   359     const TInt err = susMan.SuspendAllThreadsInProcess( aPid, ClientThread() );
       
   360 
       
   361 	TRACE( Kern::Printf( "DMemSpyDriverLogChanThreadAndProcess::SuspendAllThreadsInProcess() - END - aPid: %d, err: %d", aPid, err ));
       
   362 	return err;
       
   363     }
       
   364 
       
   365 
       
   366 TInt DMemSpyDriverLogChanThreadAndProcess::ResumeAllThreadsInProcess( TUint aPid )
       
   367     {
       
   368 	TRACE( Kern::Printf( "DMemSpyDriverLogChanThreadAndProcess::ResumeAllThreadsInProcess() - START - aPid: %d", aPid ));
       
   369 
       
   370     DMemSpySuspensionManager& susMan = SuspensionManager();
       
   371     const TInt err = susMan.ResumeAllThreadsInProcess( aPid, ClientThread() );
       
   372 
       
   373 	TRACE( Kern::Printf( "DMemSpyDriverLogChanThreadAndProcess::ResumeAllThreadsInProcess() - END - aPid: %d, err: %d", aPid, err ));
       
   374 	return err;
       
   375     }
       
   376 
       
   377 
       
   378 TInt DMemSpyDriverLogChanThreadAndProcess::GetThreadsForProcess( TUint aPid, TDes8* aBufferSink )
       
   379     {
       
   380 	TRACE( Kern::Printf( "DMemSpyDriverLogChanThreadAndProcess::GetThreadsForProcess() - START - aPid: %d", aPid ) );
       
   381 
       
   382     // We open the source thread or process, just to ensure it doesn't die underneath us...
       
   383     TInt r = OpenTempObject( aPid, EProcess );
       
   384     if  ( r == KErrNone )
       
   385 		{
       
   386 		DProcess& process = TempObjectAsProcess();
       
   387 
       
   388         // Open stream
       
   389         RMemSpyMemStreamWriter stream = OpenXferStream();
       
   390         TRACE( Kern::Printf( "DMemSpyDriverLogChanThreadAndProcess::GetThreadsForProcess() - stream remaining: %d", stream.Remaining() ) ); 
       
   391 
       
   392         // Save marker pos for the thread count - we'll update it after the loop
       
   393         TInt count = 0;
       
   394         TInt32* pCountMarkerThread = stream.WriteInt32( 0 );
       
   395 
       
   396         DMemSpyDriverOSAdaptionDProcess& processAdaptor = OSAdaption().DProcess();
       
   397         SDblQue& threadQueue = processAdaptor.GetThreadQueue( process );
       
   398         SDblQueLink* pLink = threadQueue.First();
       
   399 		while( pLink != & threadQueue.iA && !stream.IsFull() )
       
   400 			{
       
   401 			DThread* pT = processAdaptor.GetThread( pLink );
       
   402             //
       
   403             if  ( pT )
       
   404                 {
       
   405                 const TUint tid = OSAdaption().DThread().GetId( *pT );
       
   406                 TRACE( Kern::Printf( "DMemSpyDriverLogChanThreadAndProcess::GetThreadsForProcess() - id: %d (0x%04x)", tid, tid ) );
       
   407                 stream.WriteUint32( tid );
       
   408                 }
       
   409 
       
   410             pLink = pLink->iNext;
       
   411 			++count;
       
   412             }
       
   413  
       
   414         if  ( stream.IsFull() )
       
   415             {
       
   416             Kern::Printf( "DMemSpyDriverLogChanThreadAndProcess::GetThreadsForProcess() - STREAM FULL - id: %d (0x%04x), thread: %O", process.iId, process.iId, &process );
       
   417             }
       
   418 
       
   419         // Now write the count
       
   420         *pCountMarkerThread = count;
       
   421 
       
   422         // Tidy up
       
   423         r = stream.WriteAndClose( aBufferSink );
       
   424         TRACE( Kern::Printf( "DMemSpyDriverLogChanThreadAndProcess::GetThreadsForProcess() - r: %d, count: %d", r, count ));
       
   425 
       
   426         CloseTempObject();
       
   427         }
       
   428 
       
   429 	TRACE( Kern::Printf( "DMemSpyDriverLogChanThreadAndProcess::GetThreadsForProcess() - END - aPid: %d, err: %d", aPid, r ));
       
   430 	return r;
       
   431     }
       
   432 
       
   433 
       
   434 TInt DMemSpyDriverLogChanThreadAndProcess::SetPriority( TUint aId, TThreadPriority aPriority )
       
   435     {
       
   436     TRACE( Kern::Printf("DMemSpyDriverLogChanThreadAndProcess::SetPriority(T) - START - aId: %d, aPriority: %d", aId, aPriority ));
       
   437 
       
   438 	TInt r = OpenTempObject( aId, EThread );
       
   439 	TRACE( Kern::Printf("DMemSpyDriverLogChanThreadAndProcess::SetPriority(T) - done open temp object, r: %d", r ));
       
   440 	if  ( r == KErrNone )
       
   441 		{
       
   442         // Map user side thread priority to kernel-side absolute thread priority (typically 0-63)
       
   443         const TInt kernelThreadPri = MemSpyDriverUtils::MapToAbsoluteThreadPriority( aPriority );
       
   444         TRACE( Kern::Printf("DMemSpyDriverLogChanThreadAndProcess::SetPriority(T) - user: %d, kernel absolute: %d", aPriority, kernelThreadPri ));
       
   445 
       
   446         if  ( kernelThreadPri > 0 && kernelThreadPri < KNumPriorities )
       
   447             {
       
   448             NKern::ThreadEnterCS();
       
   449             DThread& thread = TempObjectAsThread();
       
   450             r = Kern::SetThreadPriority( kernelThreadPri, &thread );
       
   451             TRACE( Kern::Printf("DMemSpyDriverLogChanThreadAndProcess::SetPriority(T) - Kern::SetThreadPriority() returned: %d", r ));
       
   452     	    NKern::ThreadLeaveCS();
       
   453             }
       
   454         else
       
   455             {
       
   456             // Error
       
   457             r = kernelThreadPri;
       
   458             }
       
   459 
       
   460         CloseTempObject();
       
   461         }
       
   462 
       
   463     TRACE( Kern::Printf("DMemSpyDriverLogChanThreadAndProcess::SetPriority(T) - END - r: %d", r));
       
   464 	return r;
       
   465     }
       
   466 
       
   467 
       
   468 
       
   469 
       
   470 
       
   471 
       
   472 TInt DMemSpyDriverLogChanThreadAndProcess::MapToMemSpyExitReason( TExitType aType )
       
   473     {
       
   474     TInt ret = 0;
       
   475     //
       
   476     switch( aType )
       
   477         {
       
   478     default:
       
   479     case EExitKill:
       
   480         ret = EPanicForcedKill;
       
   481         break;
       
   482     case EExitTerminate:
       
   483         ret = EPanicForcedTerminate;
       
   484         break;
       
   485     case EExitPanic:
       
   486         ret = EPanicForcedPanic;
       
   487         break;
       
   488         }
       
   489     //
       
   490     return ret;
       
   491     }
       
   492 
       
   493 
       
   494 
       
   495 
       
   496 
       
   497 
       
   498 
       
   499 
       
   500 
       
   501 
       
   502 
       
   503 
       
   504 
       
   505 
       
   506 
       
   507 
       
   508 
       
   509 
       
   510 
       
   511