debugsrv/runmodedebug/rmdriver/src/d_process_tracker.cpp
author hgs
Fri, 08 Oct 2010 14:56:39 +0300
changeset 56 aa2539c91954
parent 42 0ff24a8f6ca2
permissions -rw-r--r--
201041
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
42
hgs
parents:
diff changeset
     1
// Copyright (c) 2006-2010 Nokia Corporation and/or its subsidiary(-ies).
hgs
parents:
diff changeset
     2
// All rights reserved.
hgs
parents:
diff changeset
     3
// This component and the accompanying materials are made available
56
hgs
parents: 42
diff changeset
     4
// under the terms of "Eclipse Public License v1.0"
42
hgs
parents:
diff changeset
     5
// which accompanies this distribution, and is available
hgs
parents:
diff changeset
     6
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
hgs
parents:
diff changeset
     7
//
hgs
parents:
diff changeset
     8
// Initial Contributors:
hgs
parents:
diff changeset
     9
// Nokia Corporation - initial contribution.
hgs
parents:
diff changeset
    10
//
hgs
parents:
diff changeset
    11
// Contributors:
hgs
parents:
diff changeset
    12
//
hgs
parents:
diff changeset
    13
// Description:
hgs
parents:
diff changeset
    14
// Purpose: The DProcessTracker object tracks which processes are being
hgs
parents:
diff changeset
    15
// debugged. The DProcessTracker class uses a DTargetProcess object for
hgs
parents:
diff changeset
    16
// each process being debugged.
hgs
parents:
diff changeset
    17
// Note: Although TheDProcessTracker object is a global, it will be unique
hgs
parents:
diff changeset
    18
// as only the Debug Security Server can load and use rm_debug.ldd.
hgs
parents:
diff changeset
    19
// 
hgs
parents:
diff changeset
    20
//
hgs
parents:
diff changeset
    21
hgs
parents:
diff changeset
    22
#include <e32def.h>
hgs
parents:
diff changeset
    23
#include <e32def_private.h>
hgs
parents:
diff changeset
    24
#include <e32cmn.h>
hgs
parents:
diff changeset
    25
#include <e32cmn_private.h>
hgs
parents:
diff changeset
    26
#include <kernel/kernel.h>
hgs
parents:
diff changeset
    27
#include <kernel/kern_priv.h>
hgs
parents:
diff changeset
    28
hgs
parents:
diff changeset
    29
#include <rm_debug_api.h>
hgs
parents:
diff changeset
    30
#include "debug_logging.h"
hgs
parents:
diff changeset
    31
#include "d_process_tracker.h"
hgs
parents:
diff changeset
    32
#include "debug_utils.h"
hgs
parents:
diff changeset
    33
hgs
parents:
diff changeset
    34
// Global Run-mode debugged process tracking object
hgs
parents:
diff changeset
    35
DProcessTracker TheDProcessTracker;
hgs
parents:
diff changeset
    36
hgs
parents:
diff changeset
    37
// ctor
hgs
parents:
diff changeset
    38
DProcessTracker::DProcessTracker()
hgs
parents:
diff changeset
    39
	{
hgs
parents:
diff changeset
    40
	}
hgs
parents:
diff changeset
    41
hgs
parents:
diff changeset
    42
/**
hgs
parents:
diff changeset
    43
 * dtor
hgs
parents:
diff changeset
    44
 * Go through forzen thread list and resume each one before clearing our structures
hgs
parents:
diff changeset
    45
 */
hgs
parents:
diff changeset
    46
DProcessTracker::~DProcessTracker()
hgs
parents:
diff changeset
    47
	{
hgs
parents:
diff changeset
    48
hgs
parents:
diff changeset
    49
	for(TInt i=0; i<iFrozenThreadSemaphores.Count(); i++)
hgs
parents:
diff changeset
    50
		{
hgs
parents:
diff changeset
    51
		LOG_MSG2("~DProcessTracker Resuming frozen NThread 0x%08x via FSSignal ", iFrozenThreadSemaphores[i]->iOwningThread );
hgs
parents:
diff changeset
    52
		NKern::FSSignal(iFrozenThreadSemaphores[i]);
hgs
parents:
diff changeset
    53
		}
hgs
parents:
diff changeset
    54
hgs
parents:
diff changeset
    55
	NKern::ThreadEnterCS();
hgs
parents:
diff changeset
    56
	// The ResetAndDestroy() will call the individual deletes for all objects in the containers
hgs
parents:
diff changeset
    57
	iFrozenThreadSemaphores.ResetAndDestroy();
hgs
parents:
diff changeset
    58
	iProcesses.ResetAndDestroy();
hgs
parents:
diff changeset
    59
	iAgentsAttachedToAll.ResetAndDestroy();
hgs
parents:
diff changeset
    60
	NKern::ThreadLeaveCS();
hgs
parents:
diff changeset
    61
	}
hgs
parents:
diff changeset
    62
hgs
parents:
diff changeset
    63
/**
hgs
parents:
diff changeset
    64
 *
hgs
parents:
diff changeset
    65
 * Creates and stores an internal mapping of debug agent to debugged process.
hgs
parents:
diff changeset
    66
 * Note that an individual process may be mapped to a number of debug agents.
hgs
parents:
diff changeset
    67
 *
hgs
parents:
diff changeset
    68
 * @param aProcessName - The fullly qualified path of the debugged process. E.g. z:\sys\bin\hello_world.exe
hgs
parents:
diff changeset
    69
 * @param aAgentId - The process id of the debug agent which is attaching to aProcessName, as returned by RProcess.Id()
hgs
parents:
diff changeset
    70
 * @return KErrNone if there are no errors. KErrArgument if the processname is too long/short for a valid filepath.
hgs
parents:
diff changeset
    71
 *  KErrNoMemory if there is insufficient memory.
hgs
parents:
diff changeset
    72
 */
hgs
parents:
diff changeset
    73
TInt DProcessTracker::AttachProcess(const TDesC8& aProcessName,TUint64 aAgentId)
hgs
parents:
diff changeset
    74
	{
hgs
parents:
diff changeset
    75
	LOG_MSG3("DProcessTracker::AttachProcess name=%S agentId=0x%lx", 
hgs
parents:
diff changeset
    76
		&aProcessName, aAgentId);
hgs
parents:
diff changeset
    77
hgs
parents:
diff changeset
    78
	// Valid ProcessName?
hgs
parents:
diff changeset
    79
	if (aProcessName.Length() < 1 || aProcessName.Length() >= KMaxPath)
hgs
parents:
diff changeset
    80
		{
hgs
parents:
diff changeset
    81
		return KErrArgument;
hgs
parents:
diff changeset
    82
		}
hgs
parents:
diff changeset
    83
hgs
parents:
diff changeset
    84
	if (aProcessName == _L8("*"))
hgs
parents:
diff changeset
    85
		{
hgs
parents:
diff changeset
    86
		DDebugAgent* agent = FindAgentForProcessAndId( aProcessName, aAgentId );
hgs
parents:
diff changeset
    87
		if(agent != NULL)
hgs
parents:
diff changeset
    88
			{
hgs
parents:
diff changeset
    89
			LOG_MSG("Found agent already attached to all");
hgs
parents:
diff changeset
    90
			return KErrAlreadyExists;
hgs
parents:
diff changeset
    91
			}
hgs
parents:
diff changeset
    92
hgs
parents:
diff changeset
    93
		agent = DDebugAgent::New(aAgentId);
hgs
parents:
diff changeset
    94
		if(agent == NULL)
hgs
parents:
diff changeset
    95
			{
hgs
parents:
diff changeset
    96
			LOG_MSG("DProcessTracker::AttachProcess() couldn't allocate memory for DDebugAgent");
hgs
parents:
diff changeset
    97
			return KErrNoMemory;
hgs
parents:
diff changeset
    98
			}
hgs
parents:
diff changeset
    99
		
hgs
parents:
diff changeset
   100
		return iAgentsAttachedToAll.Append(agent);
hgs
parents:
diff changeset
   101
hgs
parents:
diff changeset
   102
		}
hgs
parents:
diff changeset
   103
hgs
parents:
diff changeset
   104
	// Not attach all, but for a specific process/exe
hgs
parents:
diff changeset
   105
hgs
parents:
diff changeset
   106
	// Create an DTargetProcess to store
hgs
parents:
diff changeset
   107
	DTargetProcess* tmpProcess = new DTargetProcess;
hgs
parents:
diff changeset
   108
	if (tmpProcess == 0)
hgs
parents:
diff changeset
   109
		{
hgs
parents:
diff changeset
   110
		return KErrNoMemory;
hgs
parents:
diff changeset
   111
		}
hgs
parents:
diff changeset
   112
	LOG_MSG2(" AttachProcess: < new DTargetProcess=0x%08x", tmpProcess );
hgs
parents:
diff changeset
   113
	
hgs
parents:
diff changeset
   114
	// Set the name
hgs
parents:
diff changeset
   115
	TInt err = KErrNone;
hgs
parents:
diff changeset
   116
	err = tmpProcess->SetProcessName(aProcessName);
hgs
parents:
diff changeset
   117
	if (err != KErrNone)
hgs
parents:
diff changeset
   118
		{
hgs
parents:
diff changeset
   119
		LOG_MSG2(" AttachProcess: < SetProcessName returned %d", err );
hgs
parents:
diff changeset
   120
		return err;
hgs
parents:
diff changeset
   121
		}
hgs
parents:
diff changeset
   122
hgs
parents:
diff changeset
   123
	// Is this process being debugged (ie already attached?)
hgs
parents:
diff changeset
   124
	TInt found = KErrNotFound;
hgs
parents:
diff changeset
   125
	const TInt numberOfProcesses = iProcesses.Count();
hgs
parents:
diff changeset
   126
	for (TInt index = 0; index < numberOfProcesses; index++)
hgs
parents:
diff changeset
   127
		{
hgs
parents:
diff changeset
   128
		if (iProcesses[index]->ProcessName().CompareF(aProcessName) == 0)
hgs
parents:
diff changeset
   129
			{
hgs
parents:
diff changeset
   130
			LOG_MSG3(" Proc count=%d, found proc in iProcesses at %d. Count=%d",
hgs
parents:
diff changeset
   131
				index, iProcesses.Count() );
hgs
parents:
diff changeset
   132
			found = index;
hgs
parents:
diff changeset
   133
			break;
hgs
parents:
diff changeset
   134
			}
hgs
parents:
diff changeset
   135
		}
hgs
parents:
diff changeset
   136
hgs
parents:
diff changeset
   137
	if (found != KErrNotFound)
hgs
parents:
diff changeset
   138
		{
hgs
parents:
diff changeset
   139
		// Yes, it is being debugged
hgs
parents:
diff changeset
   140
hgs
parents:
diff changeset
   141
		// Add the agent to the list of agents for this process
hgs
parents:
diff changeset
   142
		LOG_MSG3(" > AddAgent(agent id %d) to existing iProcesses[%d]", I64LOW(aAgentId), found); 
hgs
parents:
diff changeset
   143
hgs
parents:
diff changeset
   144
		iProcesses[found]->AddAgent(aAgentId);
hgs
parents:
diff changeset
   145
hgs
parents:
diff changeset
   146
		return KErrNone;
hgs
parents:
diff changeset
   147
		}
hgs
parents:
diff changeset
   148
	else
hgs
parents:
diff changeset
   149
		{
hgs
parents:
diff changeset
   150
		// No, it is not being debugged
hgs
parents:
diff changeset
   151
			
hgs
parents:
diff changeset
   152
		// Add the agent to the list of agents for this process
hgs
parents:
diff changeset
   153
		LOG_MSG2(" > AddAgent(agent %d) to new proc at index 0", I64LOW(aAgentId) ); 
hgs
parents:
diff changeset
   154
hgs
parents:
diff changeset
   155
		tmpProcess->AddAgent(aAgentId);
hgs
parents:
diff changeset
   156
hgs
parents:
diff changeset
   157
		// Add the process to the list of processes being debugged
hgs
parents:
diff changeset
   158
		return iProcesses.Append(tmpProcess);
hgs
parents:
diff changeset
   159
		}
hgs
parents:
diff changeset
   160
	}
hgs
parents:
diff changeset
   161
hgs
parents:
diff changeset
   162
/**
hgs
parents:
diff changeset
   163
 * 
hgs
parents:
diff changeset
   164
 * Removes a previously created mapping between a debug agent and a debugged process,
hgs
parents:
diff changeset
   165
 * as created by AttachProcess.
hgs
parents:
diff changeset
   166
 *
hgs
parents:
diff changeset
   167
 * @param aProcessName - The fully qualified path of the debugged process. E.g. z:\sys\bin\hello_world.exe
hgs
parents:
diff changeset
   168
 * @param aAgentId - The process id of the debug agent which is attaching to aProcessName, as returned by RProcess.Id()
hgs
parents:
diff changeset
   169
 * @return KErrNone if there are no problems. KErrArgument if the processname is too long/short for a valid filepath.
hgs
parents:
diff changeset
   170
 * KErrNotFound if the mapping does not exist (and therefore cannot be removed).
hgs
parents:
diff changeset
   171
 */
hgs
parents:
diff changeset
   172
TInt DProcessTracker::DetachProcess(const TDesC8& aProcessName, TUint64 aAgentId)
hgs
parents:
diff changeset
   173
	{
hgs
parents:
diff changeset
   174
	LOG_MSG3("DProcessTracker::DetachProcess name=%S agentId=0x%lx", 
hgs
parents:
diff changeset
   175
		&aProcessName, aAgentId);
hgs
parents:
diff changeset
   176
hgs
parents:
diff changeset
   177
	// Valid ProcessName?
hgs
parents:
diff changeset
   178
	if (aProcessName.Length() < 1 || aProcessName.Length() >= KMaxPath)
hgs
parents:
diff changeset
   179
		{
hgs
parents:
diff changeset
   180
		return KErrArgument;
hgs
parents:
diff changeset
   181
		}
hgs
parents:
diff changeset
   182
hgs
parents:
diff changeset
   183
	if (aProcessName == _L8("*"))
hgs
parents:
diff changeset
   184
		{
hgs
parents:
diff changeset
   185
		TInt const agentCount = iAgentsAttachedToAll.Count();
hgs
parents:
diff changeset
   186
		LOG_MSG2(" iAgentsAttachedToAll size=%d", agentCount );
hgs
parents:
diff changeset
   187
hgs
parents:
diff changeset
   188
		for (TInt i = 0; i < agentCount; i++)
hgs
parents:
diff changeset
   189
			{
hgs
parents:
diff changeset
   190
			if (iAgentsAttachedToAll[i]->Id() == aAgentId)
hgs
parents:
diff changeset
   191
				{
hgs
parents:
diff changeset
   192
				LOG_MSG2(" Agent id found at index %d, deleting it", i);
hgs
parents:
diff changeset
   193
				delete iAgentsAttachedToAll[i];
hgs
parents:
diff changeset
   194
				iAgentsAttachedToAll.Remove(i);
hgs
parents:
diff changeset
   195
				return KErrNone;
hgs
parents:
diff changeset
   196
				}
hgs
parents:
diff changeset
   197
			}
hgs
parents:
diff changeset
   198
hgs
parents:
diff changeset
   199
		//Not found, so error condition
hgs
parents:
diff changeset
   200
		return KErrNotFound;
hgs
parents:
diff changeset
   201
		}
hgs
parents:
diff changeset
   202
hgs
parents:
diff changeset
   203
	// Are we debugging this process?
hgs
parents:
diff changeset
   204
	const TInt numberOfProcesses = iProcesses.Count();
hgs
parents:
diff changeset
   205
	TInt foundIdx = KErrNotFound;
hgs
parents:
diff changeset
   206
	for(TInt i = 0; i < numberOfProcesses; i++)
hgs
parents:
diff changeset
   207
		{
hgs
parents:
diff changeset
   208
		if (iProcesses[i]->ProcessName().CompareF(aProcessName) == 0)
hgs
parents:
diff changeset
   209
			{
hgs
parents:
diff changeset
   210
			foundIdx = i;
hgs
parents:
diff changeset
   211
			break;
hgs
parents:
diff changeset
   212
			}
hgs
parents:
diff changeset
   213
		}
hgs
parents:
diff changeset
   214
hgs
parents:
diff changeset
   215
	if (foundIdx == KErrNotFound)
hgs
parents:
diff changeset
   216
		{
hgs
parents:
diff changeset
   217
		return KErrNotFound;
hgs
parents:
diff changeset
   218
		}
hgs
parents:
diff changeset
   219
hgs
parents:
diff changeset
   220
	// remove the agent from the process
hgs
parents:
diff changeset
   221
	iProcesses[foundIdx]->RemoveAgent(aAgentId);
hgs
parents:
diff changeset
   222
hgs
parents:
diff changeset
   223
	// Found it, are there any more attached agents, or suspended threads in the process?
hgs
parents:
diff changeset
   224
hgs
parents:
diff changeset
   225
	
hgs
parents:
diff changeset
   226
	if (iProcesses[foundIdx]->AgentCount() == 0)
hgs
parents:
diff changeset
   227
		{
hgs
parents:
diff changeset
   228
		// Delete the process as no more agents are still attached
hgs
parents:
diff changeset
   229
		delete iProcesses[foundIdx];
hgs
parents:
diff changeset
   230
hgs
parents:
diff changeset
   231
		// Remove the now obsolete pointer from our array.
hgs
parents:
diff changeset
   232
		iProcesses.Remove(foundIdx);
hgs
parents:
diff changeset
   233
		}
hgs
parents:
diff changeset
   234
hgs
parents:
diff changeset
   235
	return KErrNone;
hgs
parents:
diff changeset
   236
	}
hgs
parents:
diff changeset
   237
hgs
parents:
diff changeset
   238
/**
hgs
parents:
diff changeset
   239
 *
hgs
parents:
diff changeset
   240
 * Detachs a debug agent from every process being debugged. Used when a debug agent is being detached
hgs
parents:
diff changeset
   241
 * from the debug security server and has not supplied a specific process name from which to detach.
hgs
parents:
diff changeset
   242
 */
hgs
parents:
diff changeset
   243
TInt DProcessTracker::DetachAgent(const TUint64 aAgentId)
hgs
parents:
diff changeset
   244
	{
hgs
parents:
diff changeset
   245
	
hgs
parents:
diff changeset
   246
	LOG_MSG2("DProcessTracker::DetachAgent 0x%lx", aAgentId);
hgs
parents:
diff changeset
   247
	
hgs
parents:
diff changeset
   248
	// Remove this agent from all the processes being tracked.
hgs
parents:
diff changeset
   249
	TInt numberOfProcesses = iProcesses.Count();
hgs
parents:
diff changeset
   250
	for(TInt i=0; i<numberOfProcesses; i++)
hgs
parents:
diff changeset
   251
		{
hgs
parents:
diff changeset
   252
		// remove the agent from the process (we don't care about the return code)
hgs
parents:
diff changeset
   253
		iProcesses[i]->RemoveAgent(aAgentId);
hgs
parents:
diff changeset
   254
		}
hgs
parents:
diff changeset
   255
hgs
parents:
diff changeset
   256
	// Increment down through the array as we then don't have to worry about
hgs
parents:
diff changeset
   257
	// missing entries which have been shifted after deletes.
hgs
parents:
diff changeset
   258
	// The initial value of i correspnds to the index of the final element 
hgs
parents:
diff changeset
   259
	// in the array.
hgs
parents:
diff changeset
   260
	for(TInt i = iProcesses.Count()-1; i>=0; i--)
hgs
parents:
diff changeset
   261
		{
hgs
parents:
diff changeset
   262
		if (iProcesses[i]->AgentCount() == 0)
hgs
parents:
diff changeset
   263
			{
hgs
parents:
diff changeset
   264
			// No agents remain for this process. Delete the
hgs
parents:
diff changeset
   265
			// process object and remove the pointer from the array
hgs
parents:
diff changeset
   266
			delete iProcesses[i];
hgs
parents:
diff changeset
   267
			iProcesses.Remove(i);
hgs
parents:
diff changeset
   268
			}
hgs
parents:
diff changeset
   269
		}
hgs
parents:
diff changeset
   270
hgs
parents:
diff changeset
   271
	TInt const agentCount = iAgentsAttachedToAll.Count();
hgs
parents:
diff changeset
   272
	for (TInt i = 0; i < agentCount; i++)
hgs
parents:
diff changeset
   273
		{
hgs
parents:
diff changeset
   274
		if (iAgentsAttachedToAll[i]->Id() == aAgentId)
hgs
parents:
diff changeset
   275
			{
hgs
parents:
diff changeset
   276
			LOG_MSG2(" Agent id found at index %d, deleting it", i);
hgs
parents:
diff changeset
   277
			delete iAgentsAttachedToAll[i];
hgs
parents:
diff changeset
   278
			iAgentsAttachedToAll.Remove(i);
hgs
parents:
diff changeset
   279
			}
hgs
parents:
diff changeset
   280
		}
hgs
parents:
diff changeset
   281
		
hgs
parents:
diff changeset
   282
	return KErrNone;
hgs
parents:
diff changeset
   283
	}
hgs
parents:
diff changeset
   284
hgs
parents:
diff changeset
   285
/**
hgs
parents:
diff changeset
   286
 *
hgs
parents:
diff changeset
   287
 * Returns a pointer to a DTargetProcess object representing the mapping of a debugged process
hgs
parents:
diff changeset
   288
 * with all the relevant debug agents interested in that process, as determined
hgs
parents:
diff changeset
   289
 * by AttachProcess.
hgs
parents:
diff changeset
   290
 *
hgs
parents:
diff changeset
   291
 * @param aProcessName - The fully qualified path of the debugged process. E.g. z:\sys\bin\hello_world.exe
hgs
parents:
diff changeset
   292
 * @return DTargetProcess* pointer to an object representing the internal mapping of a process to all associated
hgs
parents:
diff changeset
   293
 * debug agents. Returns 0 if the mapping cannot be found or the aProcessName is invalid.
hgs
parents:
diff changeset
   294
 */
hgs
parents:
diff changeset
   295
DTargetProcess* DProcessTracker::FindProcess(const TDesC8& aProcessName) const
hgs
parents:
diff changeset
   296
	{
hgs
parents:
diff changeset
   297
	// Valid ProcessName?
hgs
parents:
diff changeset
   298
	if (aProcessName.Length() < 1 || aProcessName.Length() >= KMaxPath)
hgs
parents:
diff changeset
   299
		{
hgs
parents:
diff changeset
   300
		return NULL;
hgs
parents:
diff changeset
   301
		}
hgs
parents:
diff changeset
   302
hgs
parents:
diff changeset
   303
	// Can we find this in the array?
hgs
parents:
diff changeset
   304
hgs
parents:
diff changeset
   305
	// Are we debugging this process?
hgs
parents:
diff changeset
   306
	const TInt numberOfProcesses = iProcesses.Count();
hgs
parents:
diff changeset
   307
	DTargetProcess* found = NULL;
hgs
parents:
diff changeset
   308
	for(TInt i = 0; i < numberOfProcesses; i++)
hgs
parents:
diff changeset
   309
		{
hgs
parents:
diff changeset
   310
		if (iProcesses[i]->ProcessName().CompareF(aProcessName) == 0)
hgs
parents:
diff changeset
   311
			{
hgs
parents:
diff changeset
   312
			found = iProcesses[i];
hgs
parents:
diff changeset
   313
			LOG_EVENT_MSG3("DProcessTracker::FindProcess(%S) found at list pos %i", 
hgs
parents:
diff changeset
   314
				&aProcessName, i);
hgs
parents:
diff changeset
   315
			break;
hgs
parents:
diff changeset
   316
			}
hgs
parents:
diff changeset
   317
		}
hgs
parents:
diff changeset
   318
hgs
parents:
diff changeset
   319
	if (found == NULL)
hgs
parents:
diff changeset
   320
		{
hgs
parents:
diff changeset
   321
		LOG_EVENT_MSG2("DProcessTracker::FindProcess(%S), not found", &aProcessName);
hgs
parents:
diff changeset
   322
		}
hgs
parents:
diff changeset
   323
hgs
parents:
diff changeset
   324
	return found;
hgs
parents:
diff changeset
   325
	}
hgs
parents:
diff changeset
   326
hgs
parents:
diff changeset
   327
/**
hgs
parents:
diff changeset
   328
 *
hgs
parents:
diff changeset
   329
 * Returns a pointer to a DTargetProcess object representing the mapping of a debugged process
hgs
parents:
diff changeset
   330
 * with all the relevant debug agents interested in that process, as determined
hgs
parents:
diff changeset
   331
 * by AttachProcess.
hgs
parents:
diff changeset
   332
 *
hgs
parents:
diff changeset
   333
 * Note: This does not attempt an exact match, because the AddProcess event does not provide
hgs
parents:
diff changeset
   334
 * a fully-qualified path, it provides something like [t_rmdebug_security0.exe].
hgs
parents:
diff changeset
   335
 *
hgs
parents:
diff changeset
   336
 * So for the purposes of dealing with this event, we need a "fuzzier" match which does not use the complete
hgs
parents:
diff changeset
   337
 * path.
hgs
parents:
diff changeset
   338
 *
hgs
parents:
diff changeset
   339
 * @param aProcessName - The fully qualified path of the debugged process. E.g. z:\sys\bin\hello_world.exe
hgs
parents:
diff changeset
   340
 * @return DTargetProcess* pointer to an object representing the internal mapping of a process to all associated
hgs
parents:
diff changeset
   341
 * debug agents. Returns 0 if the mapping cannot be found or the aProcessName is invalid.
hgs
parents:
diff changeset
   342
 */
hgs
parents:
diff changeset
   343
DTargetProcess*	DProcessTracker::FuzzyFindProcess(const TDesC8& aProcessName)
hgs
parents:
diff changeset
   344
	{
hgs
parents:
diff changeset
   345
	// Valid ProcessName?
hgs
parents:
diff changeset
   346
	if (aProcessName.Length() < 1 || aProcessName.Length() >= KMaxPath)
hgs
parents:
diff changeset
   347
		{
hgs
parents:
diff changeset
   348
		return 0;	// not found
hgs
parents:
diff changeset
   349
		}
hgs
parents:
diff changeset
   350
hgs
parents:
diff changeset
   351
	// Can we find this in the array?
hgs
parents:
diff changeset
   352
	TBool found = EFalse;
hgs
parents:
diff changeset
   353
	DTargetProcess* foundProcess = 0;
hgs
parents:
diff changeset
   354
	const TChar KBackSlash('\\');
hgs
parents:
diff changeset
   355
hgs
parents:
diff changeset
   356
	TInt numberOfProcesses = iProcesses.Count();
hgs
parents:
diff changeset
   357
	for(TInt i=0; i < numberOfProcesses; i++)
hgs
parents:
diff changeset
   358
		{
hgs
parents:
diff changeset
   359
		foundProcess = iProcesses[i];
hgs
parents:
diff changeset
   360
hgs
parents:
diff changeset
   361
		TInt procListBackSlash = foundProcess->ProcessName().LocateReverse( KBackSlash );
hgs
parents:
diff changeset
   362
		if( procListBackSlash == KErrNotFound )
hgs
parents:
diff changeset
   363
			{
hgs
parents:
diff changeset
   364
			procListBackSlash = 0;
hgs
parents:
diff changeset
   365
			}
hgs
parents:
diff changeset
   366
		else
hgs
parents:
diff changeset
   367
			{
hgs
parents:
diff changeset
   368
			//Now move to the char after the backlash
hgs
parents:
diff changeset
   369
			procListBackSlash++;
hgs
parents:
diff changeset
   370
			}
hgs
parents:
diff changeset
   371
hgs
parents:
diff changeset
   372
		TInt eventBackSlash = aProcessName.LocateReverse( KBackSlash );
hgs
parents:
diff changeset
   373
		if( eventBackSlash == KErrNotFound )
hgs
parents:
diff changeset
   374
			{
hgs
parents:
diff changeset
   375
			eventBackSlash = 0;
hgs
parents:
diff changeset
   376
			}
hgs
parents:
diff changeset
   377
		else
hgs
parents:
diff changeset
   378
			{
hgs
parents:
diff changeset
   379
			//Now move to the char after the backlash
hgs
parents:
diff changeset
   380
			eventBackSlash++;
hgs
parents:
diff changeset
   381
			}
hgs
parents:
diff changeset
   382
hgs
parents:
diff changeset
   383
		if( ( procListBackSlash == 0 ) && ( eventBackSlash == 0 ) )
hgs
parents:
diff changeset
   384
			{
hgs
parents:
diff changeset
   385
			//There were no backslashes on either name, so no point in continuing
hgs
parents:
diff changeset
   386
			break;
hgs
parents:
diff changeset
   387
			}
hgs
parents:
diff changeset
   388
hgs
parents:
diff changeset
   389
		TPtrC8 eventCleanName( aProcessName.Mid( eventBackSlash ) );		
hgs
parents:
diff changeset
   390
		TPtrC8 procListCleanName( foundProcess->ProcessName().Mid( procListBackSlash ) );
hgs
parents:
diff changeset
   391
hgs
parents:
diff changeset
   392
		if ( eventCleanName.CompareF( procListCleanName ) == 0 )
hgs
parents:
diff changeset
   393
			{
hgs
parents:
diff changeset
   394
			LOG_MSG2("DProcessTracker::FuzzyFindProcess() found a match : process list[%d]", i );
hgs
parents:
diff changeset
   395
			found = ETrue;
hgs
parents:
diff changeset
   396
			break;
hgs
parents:
diff changeset
   397
			}
hgs
parents:
diff changeset
   398
		}
hgs
parents:
diff changeset
   399
hgs
parents:
diff changeset
   400
	if (found == EFalse)
hgs
parents:
diff changeset
   401
		{
hgs
parents:
diff changeset
   402
		return 0;	// not found
hgs
parents:
diff changeset
   403
		}
hgs
parents:
diff changeset
   404
hgs
parents:
diff changeset
   405
	return foundProcess;
hgs
parents:
diff changeset
   406
	}
hgs
parents:
diff changeset
   407
hgs
parents:
diff changeset
   408
/**
hgs
parents:
diff changeset
   409
  Freeze the current thread
hgs
parents:
diff changeset
   410
hgs
parents:
diff changeset
   411
  @return KErrNone if the thread is successfully suspended,
hgs
parents:
diff changeset
   412
  KErrAlreadyExists if the agent has already suspended the thread,
hgs
parents:
diff changeset
   413
  or one of the other system wide error codes
hgs
parents:
diff changeset
   414
hgs
parents:
diff changeset
   415
  This marks the current thread for waiting on a Fast Semaphore
hgs
parents:
diff changeset
   416
  when exception handling for this thread has completed - see
hgs
parents:
diff changeset
   417
  rm_debug_eventhandler.cpp for details.
hgs
parents:
diff changeset
   418
  */
hgs
parents:
diff changeset
   419
TInt DProcessTracker::FreezeThread()
hgs
parents:
diff changeset
   420
	{
hgs
parents:
diff changeset
   421
	// create and store a fast semaphore to stop the thread on
hgs
parents:
diff changeset
   422
	TInt err = KErrGeneral;
hgs
parents:
diff changeset
   423
	NKern::ThreadEnterCS();
hgs
parents:
diff changeset
   424
	NFastSemaphore* sem = new NFastSemaphore( &(Kern::CurrentThread().iNThread) );
hgs
parents:
diff changeset
   425
	if( sem != NULL )
hgs
parents:
diff changeset
   426
		{
hgs
parents:
diff changeset
   427
		LOG_MSG3("DProcessTracker::FreezeThread(): new NFastSemaphore(curr NThread=0x%08x), DThread=0x%08x", 
hgs
parents:
diff changeset
   428
			sem->iOwningThread, &(Kern::CurrentThread()) );
hgs
parents:
diff changeset
   429
		err = iFrozenThreadSemaphores.Append(sem); 
hgs
parents:
diff changeset
   430
		}
hgs
parents:
diff changeset
   431
	else
hgs
parents:
diff changeset
   432
		{
hgs
parents:
diff changeset
   433
		LOG_MSG("DProcessTracker::FreezeThread(): Error : could not allocate NFastSemaphore"); 
hgs
parents:
diff changeset
   434
		err = KErrNoMemory;
hgs
parents:
diff changeset
   435
		}
hgs
parents:
diff changeset
   436
hgs
parents:
diff changeset
   437
	NKern::ThreadLeaveCS();
hgs
parents:
diff changeset
   438
	return err;
hgs
parents:
diff changeset
   439
	}
hgs
parents:
diff changeset
   440
hgs
parents:
diff changeset
   441
/**
hgs
parents:
diff changeset
   442
 Waits the current thread on a Fast Semaphore.
hgs
parents:
diff changeset
   443
hgs
parents:
diff changeset
   444
 This is useful for situations where the current thread
hgs
parents:
diff changeset
   445
 has hit a breakpoint within a critical section, and
hgs
parents:
diff changeset
   446
 otherwise could not be suspended at this point.
hgs
parents:
diff changeset
   447
hgs
parents:
diff changeset
   448
 Note that the Fast Semaphore structure on which the thread
hgs
parents:
diff changeset
   449
 waits must be a member data item of this class instance,
hgs
parents:
diff changeset
   450
 as it needs to be FSSignal()'d by another thread to resume
hgs
parents:
diff changeset
   451
 again.
hgs
parents:
diff changeset
   452
 */
hgs
parents:
diff changeset
   453
void DProcessTracker::FSWait()
hgs
parents:
diff changeset
   454
	{
hgs
parents:
diff changeset
   455
	NThread* currentNThread = &(Kern::CurrentThread().iNThread);	
hgs
parents:
diff changeset
   456
	for(TInt i=0; i<iFrozenThreadSemaphores.Count(); i++)
hgs
parents:
diff changeset
   457
		{
hgs
parents:
diff changeset
   458
		if(iFrozenThreadSemaphores[i]->iOwningThread == currentNThread)
hgs
parents:
diff changeset
   459
			{
hgs
parents:
diff changeset
   460
			LOG_MSG4("DProcessTracker::FSWait(): > FSWait frozen sem %d, currentNThread=0x%08x, id=0x%x", 
hgs
parents:
diff changeset
   461
				i, currentNThread, Kern::CurrentThread().iId );
hgs
parents:
diff changeset
   462
			NKern::FSWait(iFrozenThreadSemaphores[i]);
hgs
parents:
diff changeset
   463
			return;
hgs
parents:
diff changeset
   464
			}
hgs
parents:
diff changeset
   465
		}
hgs
parents:
diff changeset
   466
	}
hgs
parents:
diff changeset
   467
	
hgs
parents:
diff changeset
   468
/**
hgs
parents:
diff changeset
   469
  Resume the specified frozen thread
hgs
parents:
diff changeset
   470
hgs
parents:
diff changeset
   471
  @param aThread thread to resume
hgs
parents:
diff changeset
   472
hgs
parents:
diff changeset
   473
  @return KErrNone if the thread has previously been suspended and is resumed,
hgs
parents:
diff changeset
   474
  KErrNotFound if the thread has not previously been suspended
hgs
parents:
diff changeset
   475
  */
hgs
parents:
diff changeset
   476
TInt DProcessTracker::ResumeFrozenThread(DThread* aThread)
hgs
parents:
diff changeset
   477
	{
hgs
parents:
diff changeset
   478
	for(TInt i=0; i<iFrozenThreadSemaphores.Count(); i++)
hgs
parents:
diff changeset
   479
		{
hgs
parents:
diff changeset
   480
		if(iFrozenThreadSemaphores[i]->iOwningThread == &(aThread->iNThread))
hgs
parents:
diff changeset
   481
			{
hgs
parents:
diff changeset
   482
			LOG_MSG2("DProcessTracker::ResumeFrozenThread 0x%08x, signalling then deleting this FastSem", aThread->iId );
hgs
parents:
diff changeset
   483
			NKern::FSSignal(iFrozenThreadSemaphores[i]);
hgs
parents:
diff changeset
   484
			NKern::ThreadEnterCS();
hgs
parents:
diff changeset
   485
			delete iFrozenThreadSemaphores[i];
hgs
parents:
diff changeset
   486
			NKern::ThreadLeaveCS();
hgs
parents:
diff changeset
   487
			iFrozenThreadSemaphores.Remove(i);
hgs
parents:
diff changeset
   488
			return KErrNone;
hgs
parents:
diff changeset
   489
			}
hgs
parents:
diff changeset
   490
		}
hgs
parents:
diff changeset
   491
	return KErrNotFound;
hgs
parents:
diff changeset
   492
	}
hgs
parents:
diff changeset
   493
	
hgs
parents:
diff changeset
   494
TInt DProcessTracker::SuspendThread(DThread* aTargetThread, TBool aFreezeThread)
hgs
parents:
diff changeset
   495
	{
hgs
parents:
diff changeset
   496
	LOG_MSG5("DProcessTracker::SuspendThread() id 0x%08x, iCsCount=%d, , iCsFunction=%d, iSuspendCount=%d ", 
hgs
parents:
diff changeset
   497
			aTargetThread->iId, aTargetThread->iNThread.iCsCount, aTargetThread->iNThread.iCsFunction, aTargetThread->iNThread.iSuspendCount );
hgs
parents:
diff changeset
   498
	if( !aFreezeThread )
hgs
parents:
diff changeset
   499
		{		
hgs
parents:
diff changeset
   500
		if(!aTargetThread)
hgs
parents:
diff changeset
   501
			{
hgs
parents:
diff changeset
   502
			LOG_MSG("DProcessTracker::SuspendThread()  > Kern::ThreadSuspend NullThrd Ptr!!");
hgs
parents:
diff changeset
   503
			return KErrBadHandle;
hgs
parents:
diff changeset
   504
			}
hgs
parents:
diff changeset
   505
		
hgs
parents:
diff changeset
   506
		Kern::ThreadSuspend(*aTargetThread, 1);
hgs
parents:
diff changeset
   507
		return KErrNone;
hgs
parents:
diff changeset
   508
		}
hgs
parents:
diff changeset
   509
hgs
parents:
diff changeset
   510
	if( Kern::CurrentThread().iId != aTargetThread->iId )
hgs
parents:
diff changeset
   511
		{
hgs
parents:
diff changeset
   512
		LOG_MSG2("DProcessTracker::SuspendThread() Error: Freeze for thread 0x%08x, but different from current thread", 
hgs
parents:
diff changeset
   513
				aTargetThread->iId);
hgs
parents:
diff changeset
   514
		return KErrBadHandle;
hgs
parents:
diff changeset
   515
		}
hgs
parents:
diff changeset
   516
hgs
parents:
diff changeset
   517
	return FreezeThread();
hgs
parents:
diff changeset
   518
	}
hgs
parents:
diff changeset
   519
hgs
parents:
diff changeset
   520
hgs
parents:
diff changeset
   521
TInt DProcessTracker::ResumeThread(DThread* aTargetThread)
hgs
parents:
diff changeset
   522
	{
hgs
parents:
diff changeset
   523
	LOG_MSG5("DProcessTracker::ResumeThread() id 0x%08x, iCsCount=%d, , iCsFunction=%d, iSuspendCount=%d ", 
hgs
parents:
diff changeset
   524
			aTargetThread->iId, aTargetThread->iNThread.iCsCount, aTargetThread->iNThread.iCsFunction, aTargetThread->iNThread.iSuspendCount );
hgs
parents:
diff changeset
   525
hgs
parents:
diff changeset
   526
	TInt err = ResumeFrozenThread( aTargetThread );
hgs
parents:
diff changeset
   527
	if( err == KErrNotFound ) 
hgs
parents:
diff changeset
   528
		{
hgs
parents:
diff changeset
   529
		LOG_MSG(" ResumeThread() : not found in frozen list. Using Kern::ThreadResume" );
hgs
parents:
diff changeset
   530
		Kern::ThreadResume(*aTargetThread);
hgs
parents:
diff changeset
   531
		return KErrNone;
hgs
parents:
diff changeset
   532
		}
hgs
parents:
diff changeset
   533
hgs
parents:
diff changeset
   534
	return err;
hgs
parents:
diff changeset
   535
	}
hgs
parents:
diff changeset
   536
hgs
parents:
diff changeset
   537
/**
hgs
parents:
diff changeset
   538
  Get a thread's originating file name
hgs
parents:
diff changeset
   539
hgs
parents:
diff changeset
   540
  @param aThread the thread to get the file name for
hgs
parents:
diff changeset
   541
hgs
parents:
diff changeset
   542
  @return a pointer to the thread's file name, if there are problems accessing
hgs
parents:
diff changeset
   543
  the file name then NULL will be returned
hgs
parents:
diff changeset
   544
  */
hgs
parents:
diff changeset
   545
const TDesC* DProcessTracker::GetFileName(DThread* aThread) const
hgs
parents:
diff changeset
   546
	{
hgs
parents:
diff changeset
   547
	//check if the thread is NULL and return if so
hgs
parents:
diff changeset
   548
	if(!aThread)
hgs
parents:
diff changeset
   549
		{
hgs
parents:
diff changeset
   550
		return NULL;
hgs
parents:
diff changeset
   551
		}
hgs
parents:
diff changeset
   552
hgs
parents:
diff changeset
   553
	//get the owning process and return if it is NULL
hgs
parents:
diff changeset
   554
	DProcess* process = aThread->iOwningProcess;
hgs
parents:
diff changeset
   555
	if(!process)
hgs
parents:
diff changeset
   556
		{
hgs
parents:
diff changeset
   557
		return NULL;
hgs
parents:
diff changeset
   558
		}
hgs
parents:
diff changeset
   559
hgs
parents:
diff changeset
   560
	//get the process' code seg and return if it is NULL
hgs
parents:
diff changeset
   561
	DCodeSeg* codeSeg = process->iCodeSeg;
hgs
parents:
diff changeset
   562
	if(!codeSeg)
hgs
parents:
diff changeset
   563
		{
hgs
parents:
diff changeset
   564
		return NULL;
hgs
parents:
diff changeset
   565
		}
hgs
parents:
diff changeset
   566
hgs
parents:
diff changeset
   567
	//return the code seg's stored file name (which could theoretically be NULL)
hgs
parents:
diff changeset
   568
	return codeSeg->iFileName;
hgs
parents:
diff changeset
   569
	}
hgs
parents:
diff changeset
   570
hgs
parents:
diff changeset
   571
/**
hgs
parents:
diff changeset
   572
If any agent has called AttachToAll, return the most recently attached one.
hgs
parents:
diff changeset
   573
*/
hgs
parents:
diff changeset
   574
DDebugAgent* DProcessTracker::GetCurrentAgentAttachedToAll() const
hgs
parents:
diff changeset
   575
	{
hgs
parents:
diff changeset
   576
	if (iAgentsAttachedToAll.Count() > 0)
hgs
parents:
diff changeset
   577
		{
hgs
parents:
diff changeset
   578
		return iAgentsAttachedToAll[iAgentsAttachedToAll.Count()-1];
hgs
parents:
diff changeset
   579
		}
hgs
parents:
diff changeset
   580
	else
hgs
parents:
diff changeset
   581
		{
hgs
parents:
diff changeset
   582
		return NULL;
hgs
parents:
diff changeset
   583
		}
hgs
parents:
diff changeset
   584
	}
hgs
parents:
diff changeset
   585
hgs
parents:
diff changeset
   586
/**
hgs
parents:
diff changeset
   587
Returns ETrue if at least one agent was found for this process (either a specifically-attached 
hgs
parents:
diff changeset
   588
one or a current attached to all). Search specifically attached first, since these have 
hgs
parents:
diff changeset
   589
priority over attach all.
hgs
parents:
diff changeset
   590
*/
hgs
parents:
diff changeset
   591
TBool DProcessTracker::NotifyAgentsForProcessEvent(const TDesC8& aProcessName, const TDriverEventInfo& aEvent, TBool aAllowFuzzy)
hgs
parents:
diff changeset
   592
	{
hgs
parents:
diff changeset
   593
	TBool foundAgent = EFalse;
hgs
parents:
diff changeset
   594
hgs
parents:
diff changeset
   595
	DTargetProcess* process = FindProcess(aProcessName);
hgs
parents:
diff changeset
   596
	if (process == NULL && aAllowFuzzy)
hgs
parents:
diff changeset
   597
		{
hgs
parents:
diff changeset
   598
		process = FuzzyFindProcess(aProcessName);
hgs
parents:
diff changeset
   599
		}
hgs
parents:
diff changeset
   600
hgs
parents:
diff changeset
   601
	if (process)
hgs
parents:
diff changeset
   602
		{
hgs
parents:
diff changeset
   603
		LOG_MSG3("DProcessTracker::NotifyAgentsForProcessEvent name=%S eventtype=%d", 
hgs
parents:
diff changeset
   604
			&aProcessName, aEvent.iEventType);
hgs
parents:
diff changeset
   605
		process->NotifyEvent(aEvent);
hgs
parents:
diff changeset
   606
		return ETrue;
hgs
parents:
diff changeset
   607
		}
hgs
parents:
diff changeset
   608
hgs
parents:
diff changeset
   609
	// Since no specifically attached agents were found, try the attach all
hgs
parents:
diff changeset
   610
hgs
parents:
diff changeset
   611
	DDebugAgent* currentAll = GetCurrentAgentAttachedToAll();
hgs
parents:
diff changeset
   612
	if (currentAll)
hgs
parents:
diff changeset
   613
		{
hgs
parents:
diff changeset
   614
		foundAgent = ETrue;
hgs
parents:
diff changeset
   615
		LOG_MSG4("DProcessTracker::NotifyAgentsForProcessEvent via AttachAll name=%S eventtype=%d, agent 0x%lx", 
hgs
parents:
diff changeset
   616
			&aProcessName, aEvent.iEventType, currentAll->Id());
hgs
parents:
diff changeset
   617
		currentAll->NotifyEvent(aEvent);
hgs
parents:
diff changeset
   618
		}
hgs
parents:
diff changeset
   619
hgs
parents:
diff changeset
   620
	return foundAgent;
hgs
parents:
diff changeset
   621
	}
hgs
parents:
diff changeset
   622
hgs
parents:
diff changeset
   623
/**
hgs
parents:
diff changeset
   624
 * Find the agent that matches this exe/proc name. Name could be the attachall indicator "*", 
hgs
parents:
diff changeset
   625
 * in which case it returns the agent that matched the pid from the attach all list
hgs
parents:
diff changeset
   626
 */
hgs
parents:
diff changeset
   627
DDebugAgent* DProcessTracker::FindAgentForProcessAndId(const TDesC8& aProcessName, TUint64 aAgentId) const
hgs
parents:
diff changeset
   628
	{
hgs
parents:
diff changeset
   629
hgs
parents:
diff changeset
   630
	if (aProcessName == _L8("*"))
hgs
parents:
diff changeset
   631
		{
hgs
parents:
diff changeset
   632
		TInt const agentCount = iAgentsAttachedToAll.Count();
hgs
parents:
diff changeset
   633
		
hgs
parents:
diff changeset
   634
		LOG_MSG3("FindAgentForProcessAndId : Searching for agent id 0x%lx, iAgentsAttachedToAll size=%d", 
hgs
parents:
diff changeset
   635
			aAgentId, agentCount );
hgs
parents:
diff changeset
   636
		
hgs
parents:
diff changeset
   637
		// Then check the attached to all list. Should not have more than one entry
hgs
parents:
diff changeset
   638
		// for each agent, but just in case we search backwards to match the append
hgs
parents:
diff changeset
   639
		//
hgs
parents:
diff changeset
   640
		for (TInt i = agentCount - 1 ; i >= 0; i--)
hgs
parents:
diff changeset
   641
			{
hgs
parents:
diff changeset
   642
			DDebugAgent* agent = iAgentsAttachedToAll[i];
hgs
parents:
diff changeset
   643
			if (agent->Id() == aAgentId)
hgs
parents:
diff changeset
   644
				{
hgs
parents:
diff changeset
   645
				return agent;
hgs
parents:
diff changeset
   646
				}
hgs
parents:
diff changeset
   647
			}
hgs
parents:
diff changeset
   648
		}
hgs
parents:
diff changeset
   649
	else
hgs
parents:
diff changeset
   650
		{
hgs
parents:
diff changeset
   651
		DTargetProcess* process = FindProcess(aProcessName);
hgs
parents:
diff changeset
   652
		if (process)
hgs
parents:
diff changeset
   653
			{
hgs
parents:
diff changeset
   654
			return process->Agent(aAgentId);
hgs
parents:
diff changeset
   655
			}
hgs
parents:
diff changeset
   656
		}
hgs
parents:
diff changeset
   657
	return NULL;
hgs
parents:
diff changeset
   658
	}