kerneltest/e32test/rm_debug/basic_tests/t_rmdebug2.cpp
branchRCL_3
changeset 89 1df514389a47
parent 87 2f92ad2dc5db
child 258 880ff05ad710
equal deleted inserted replaced
87:2f92ad2dc5db 89:1df514389a47
   398 	test(ListingSupported(EThreads, EScopeThreadSpecific));
   398 	test(ListingSupported(EThreads, EScopeThreadSpecific));
   399 
   399 
   400 	test(KErrNone == iServSession.AttachExecutable(iFileName, EFalse));
   400 	test(KErrNone == iServSession.AttachExecutable(iFileName, EFalse));
   401 	test(KErrNone == iServSession.SuspendThread(iThreadID));
   401 	test(KErrNone == iServSession.SuspendThread(iThreadID));
   402 
   402 
   403 	//test getting the global list, ETrue as should find the target debug thread
   403 	TBool found = EFalse;
   404 	DoTestGetThreadList(ETrue, EScopeGlobal);
   404 	
   405 
   405 	/* We need these loops because on some system the kernel run mode debugger does not 
   406 	//test getting this thread's thread list, ETrue as should find the target debug thread
   406 	 immediately present the thread in the thread list. 
   407 	DoTestGetThreadList(ETrue, EScopeThreadSpecific, RThread().Id().Id());
   407 	 */
   408 
   408 	
   409 	//test getting this process's thread list, ETrue as should find the target debug thread
   409 	for(TInt retryCount = 0; retryCount < 10 && !found; retryCount++ )
   410 	DoTestGetThreadList(ETrue, EScopeProcessSpecific, RProcess().Id().Id());
   410 		{
       
   411 		//test getting this process's thread list, ETrue as should find the target debug thread
       
   412 		User::After(50000);
       
   413 		found = DoTestGetThreadList(ETrue, EScopeProcessSpecific, RProcess().Id().Id());
       
   414 		}
       
   415 	test( found );
       
   416 	found = EFalse;
       
   417 
       
   418 	for(TInt retryCount = 0; retryCount < 10 && !found; retryCount++ )
       
   419 		{
       
   420 		//test getting the global list, ETrue as should find the target debug thread
       
   421 		User::After(50000);
       
   422 		found = DoTestGetThreadList(ETrue, EScopeGlobal);
       
   423 		}
       
   424 	test( found );
       
   425 
       
   426 	found = EFalse;
       
   427 	for(TInt retryCount = 0; retryCount < 10 && !found; retryCount++ )
       
   428 		{
       
   429 		//test getting this thread's thread list, ETrue as should find the target debug thread
       
   430 		User::After(50000);
       
   431 		found = DoTestGetThreadList(ETrue, EScopeThreadSpecific, RThread().Id().Id());
       
   432 		}
       
   433 	test( found );
   411 
   434 
   412 	test(KErrNone == iServSession.ResumeThread(iThreadID));
   435 	test(KErrNone == iServSession.ResumeThread(iThreadID));
   413 	test(KErrNone == iServSession.DetachExecutable(iFileName));
   436 	test(KErrNone == iServSession.DetachExecutable(iFileName));
   414 	}
   437 	}
   415 
   438 			
   416 void CRunModeAgent::DoTestGetThreadList(const TBool aShouldPass, const TListScope aListScope, const TUint64 aTargetId)
   439 TBool CRunModeAgent::DoTestGetThreadList(const TBool aShouldPass, const TListScope aListScope, const TUint64 aTargetId)
   417 	{
   440 	{
   418 	test.Next(_L("DoTestGetThreadList\n"));
       
   419 
       
   420 	//create data to pass
   441 	//create data to pass
   421 	RBuf8 buffer;
   442 	RBuf8 buffer;
   422 	TUint32 size = 0;
   443 	TUint32 size = 0;
   423 
   444 
   424 	//perform the call to get the Code segs
   445 	//perform the call to get the thread list
   425 	DoGetList(EThreads, aListScope, buffer, size, aTargetId);
   446 	DoGetList(EThreads, aListScope, buffer, size, aTargetId);
   426 
   447 
   427 	//initialise data about the target debug thread to compare the kernel's data against
   448 	//initialise data about the target debug thread to compare the kernel's data against
   428 	TFileName name = iDebugThread.FullName();
   449 	TFileName name = iDebugThread.FullName();
   429 	RProcess thisProcess;
   450 	RProcess thisProcess;
   436 	const TUint8* ptrEnd = ptr + size;
   457 	const TUint8* ptrEnd = ptr + size;
   437 	while(ptr < ptrEnd)
   458 	while(ptr < ptrEnd)
   438 		{
   459 		{
   439 		TThreadListEntry* entry = (TThreadListEntry*)ptr;
   460 		TThreadListEntry* entry = (TThreadListEntry*)ptr;
   440 		TPtr entryName(&(entry->iName[0]), entry->iNameLength, entry->iNameLength);
   461 		TPtr entryName(&(entry->iName[0]), entry->iNameLength, entry->iNameLength);
       
   462 
   441 		if( (threadId == entry->iThreadId) && (processId == entry->iProcessId) && (0 == name.CompareF(entryName)) )
   463 		if( (threadId == entry->iThreadId) && (processId == entry->iProcessId) && (0 == name.CompareF(entryName)) )
   442 			{
   464 			{
   443 			test(entry->iSupervisorStackBaseValid);
   465 			test(entry->iSupervisorStackBaseValid);
   444 			test(entry->iSupervisorStackSizeValid);
   466 			test(entry->iSupervisorStackSizeValid);
   445 			//if all match then we've found it
   467 			//if all match then we've found it
   446 			found = ETrue;
   468 			found = ETrue;
       
   469 			break;
   447 			}
   470 			}
   448 
   471 
   449 		ptr += Align4(entry->GetSize());
   472 		ptr += Align4(entry->GetSize());
   450 		}
   473 		}
   451 
       
   452 	//check whether the expected result happened
       
   453 	test(found == aShouldPass);
       
   454 
   474 
   455 	//clean up
   475 	//clean up
   456 	buffer.Close();
   476 	buffer.Close();
       
   477 	return found;
   457 
   478 
   458 	}
   479 	}
   459 
   480 
   460 //---------------------------------------------
   481 //---------------------------------------------
   461 //! @SYMTestCaseID KBase-T-RMDEBUG2-0431
   482 //! @SYMTestCaseID KBase-T-RMDEBUG2-0431
   580 	//clean up
   601 	//clean up
   581 	buffer.Close();
   602 	buffer.Close();
   582 
   603 
   583 	}
   604 	}
   584 
   605 
       
   606 
       
   607 /**
       
   608  * Get a list from the run mode debug system. Most list calls will initially return KErrTooBig, 
       
   609  * since the initial size of the buffer is 0. However it is sometimes valid for a list to be empty
       
   610  * given its filtering and scope. These calls should return KErrNone.
       
   611  */
   585 void CRunModeAgent::DoGetList(const TListId aListId, const TListScope aListScope, RBuf8& aBuffer, TUint32& aSize, const TUint64 aTargetId)
   612 void CRunModeAgent::DoGetList(const TListId aListId, const TListScope aListScope, RBuf8& aBuffer, TUint32& aSize, const TUint64 aTargetId)
   586 	{
   613 	{
   587 	//close the buffer in case there's stuff allocated in it
   614 	//close the buffer in case there's stuff allocated in it
   588 	aBuffer.Close();
   615 	aBuffer.Close();
   589 	//initialise it to be one byte big, which will guarantee data won't fit in it
   616 	//initialise it to be one byte big, which will guarantee data won't fit in it
   590 	test(KErrNone == aBuffer.Create(1));
   617 	test(KErrNone == aBuffer.Create(1));
   591 	aSize = 0;
   618 	aSize = 0;
   592 
   619 	
       
   620 	TInt ret = KErrNone;
   593 	//should pass this test (assuming we've passed in sensible arguments above...)
   621 	//should pass this test (assuming we've passed in sensible arguments above...)
   594 	if(EScopeGlobal == aListScope)
   622 	if(EScopeGlobal == aListScope)
   595 		{
   623 		{
   596 		test(KErrTooBig == iServSession.GetList(aListId, aBuffer, aSize));
   624 		ret = iServSession.GetList(aListId, aBuffer, aSize);
   597 		}
   625 		}
   598 	else if(EScopeThreadSpecific == aListScope)
   626 	else if(EScopeThreadSpecific == aListScope)
   599 		{
   627 		{
   600 		test(KErrTooBig == iServSession.GetList((TThreadId)aTargetId, aListId, aBuffer, aSize));
   628 		ret = iServSession.GetList((TThreadId)aTargetId, aListId, aBuffer, aSize);
   601 		}
   629 		}
   602 	else if(EScopeProcessSpecific == aListScope)
   630 	else if(EScopeProcessSpecific == aListScope)
   603 		{
   631 		{
   604 		test(KErrTooBig == iServSession.GetList((TProcessId)aTargetId, aListId, aBuffer, aSize));
   632 		ret = iServSession.GetList((TProcessId)aTargetId, aListId, aBuffer, aSize);
   605 		}
   633 		}
   606 	else
   634 	else
   607 		{
   635 		{
   608 		// unknown list scope
   636 		// unknown list scope
   609 		test(0);
   637 		test(0);
   610 		}
   638 		}
       
   639 
       
   640 	if( KErrNone == ret )
       
   641 		{
       
   642 		/* In the case that there is no data, just return and let the caller check
       
   643 		the buffer. It is valid for a caller to not expect any data to be returned.
       
   644 		*/
       
   645 		return;
       
   646 		}
       
   647 	
       
   648 	// The only other allowed return is KErrTooBig
       
   649 	test( ret == KErrTooBig );
   611 
   650 
   612 	//keep allocating larger buffers, beginning with the aSize returned by the above call,
   651 	//keep allocating larger buffers, beginning with the aSize returned by the above call,
   613 	//and hopefully we'll eventually make a large enough one
   652 	//and hopefully we'll eventually make a large enough one
   614 	test(KErrNone == aBuffer.ReAlloc(aSize));
   653 	test(KErrNone == aBuffer.ReAlloc(aSize));
   615 
   654 
  2725 		while((waitCount-- > 0) && ProcessExists(processId))
  2764 		while((waitCount-- > 0) && ProcessExists(processId))
  2726 			{
  2765 			{
  2727 			/* Wait a little while and try again, just in case the process is still being removed.
  2766 			/* Wait a little while and try again, just in case the process is still being removed.
  2728 			This can happen on a very busy system or when a popup for the events is still active
  2767 			This can happen on a very busy system or when a popup for the events is still active
  2729 			*/
  2768 			*/
  2730 			RDebug::Printf("CRunModeAgent::TestEventsWithExtraThreads. ProcessExists(id=%d), waiting for it to exit %d", 
  2769 			RDebug::Printf("CRunModeAgent::TestEventsWithExtraThreads. ProcessExists(id=%d), waiting count exit=%d", 
  2731 				I64LOW(processId), waitCount);
  2770 				I64LOW(processId), waitCount);
  2732 			User::After(500);
  2771 			User::After(50000);
  2733 			}
  2772 			}
  2734 		test(!ProcessExists(processId));
  2773 		test(!ProcessExists(processId));
  2735 		}
  2774 		}
  2736 	}
  2775 	}
  2737 
  2776 
  2738 // helper function to check whether a thread with id aThreadId exists in the process with id aProcessId
  2777 // helper function to check whether a thread with id aThreadId exists in the process with id aProcessId
  2739 TBool CRunModeAgent::ThreadExistsForProcess(const TThreadId aThreadId, const TProcessId aProcessId)
  2778 TBool CRunModeAgent::ThreadExistsForProcess(const TThreadId aThreadId, const TProcessId aProcessId)
  2740 	{
  2779 	{
  2741 	TUint32 size;
  2780 	RThread lThread;
  2742 	RBuf8 buffer;
  2781 	TInt ret = lThread.Open( aThreadId.Id() );
  2743 	test(KErrNone == buffer.Create(1024));
  2782 
  2744 	TInt err = iServSession.GetList(aProcessId, EThreads, buffer, size);
  2783 	if( ret != KErrNone )
  2745 	while(KErrTooBig == err)
  2784 		{
  2746 		{
  2785 		RDebug::Printf("ThreadExistsForProcess: thread id=%d opening returned %d",
  2747 		size*=2;
  2786 			I64LOW( aThreadId.Id() ), ret );
  2748 		test(size<=16*1024);
  2787 		lThread.Close();
  2749 		test(KErrNone == buffer.ReAlloc(size));
  2788 		return EFalse;
  2750 		err = iServSession.GetList(aProcessId, EThreads, buffer, size);
  2789 		}
  2751 		}
  2790 
  2752 	test(KErrNone == err);
  2791 	RProcess lProcess;
  2753 
  2792 	ret = lThread.Process( lProcess );
  2754 	//look through the buffer and check if the target debug thread is there
  2793 
  2755 	TUint8* ptr = (TUint8*)buffer.Ptr();
  2794 	lThread.Close();
  2756 	const TUint8* ptrEnd = ptr + size;
  2795 
  2757 	while(ptr < ptrEnd)
  2796 	if( ret != KErrNone )
  2758 		{
  2797 		{
  2759 		TThreadListEntry& entry = *(TThreadListEntry*)ptr;
  2798 		RDebug::Printf("ThreadExistsForProcess: proc opening returned %d", ret );
  2760 		if(aThreadId.Id() == entry.iThreadId)
  2799 		ret = KErrNotFound;
  2761 			{
  2800 		}
  2762 			buffer.Close();
  2801 	else if( lProcess.Id() != aProcessId )
  2763 			return ETrue;
  2802 		{
  2764 			}
  2803 		RDebug::Printf("ThreadExistsForProcess: lProcess.Id()(%d)!= aProcessId(%d)",
  2765 		ptr += Align4(entry.GetSize());
  2804 				I64LOW(lProcess.Id().Id()), I64LOW(aProcessId.Id()));
  2766 		}
  2805 		ret = KErrNotFound;
  2767 	buffer.Close();
  2806 		}
  2768 	return EFalse;
  2807 
       
  2808 	lProcess.Close();
       
  2809 	
       
  2810 	return ( ret == KErrNone );
  2769 	}
  2811 	}
  2770 
  2812 
  2771 // helper function to check whether a process with id aProcessId exists
  2813 // helper function to check whether a process with id aProcessId exists
  2772 TBool CRunModeAgent::ProcessExists(const TProcessId aProcessId)
  2814 TBool CRunModeAgent::ProcessExists(const TProcessId aProcessId)
  2773 	{
  2815 	{