blob: fe082def1635a2fc67e7b4c37aaf6c9fb1480393 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2009, 2011 Nokia and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Nokia - Initial API and implementation
*******************************************************************************/
#include "StdAfx.h"
#include "WinProcess.h"
#include "WinThread.h"
#include "EventClientNotifier.h"
#include "AgentUtils.h"
#include "Psapi.h"
#include "assert.h"
#include "WinDebugMonitor.h"
#include "TerminateProcessAction.h"
#include "ProtocolConstants.h"
#include "RunControlService.h"
#include "ContextManager.h"
#include "BreakpointsService.h"
std::map<int, WinProcess*> WinProcess::processIDMap;
WinProcess::WinProcess(WinDebugMonitor* monitor, DEBUG_EVENT& debugEvent)
: ProcessContext(debugEvent.dwProcessId, ROOT_CONTEXT_ID, CreateInternalID(debugEvent.dwProcessId)),
processHandle_(debugEvent.u.CreateProcessInfo.hProcess),
monitor_(monitor)
{
isRoot_ = true;
processIDMap[debugEvent.dwProcessId] = this;
// Get the name for the new process
std::string moduleFileName = "unknown";
int bufferSize = 32768;
{
LPTSTR processNameBuffer = new TCHAR[bufferSize];
int nameLength = GetProcessImageFileName((HMODULE) processHandle_,
processNameBuffer, bufferSize);
if (nameLength > 0)
moduleFileName = AgentUtils::makeString(processNameBuffer);
delete[] processNameBuffer;
}
int lastSlash = moduleFileName.find_last_of("\\");
if (lastSlash > 0)
moduleFileName = moduleFileName.substr(lastSlash + 1);
processName_ = moduleFileName;
Initialize();
}
WinProcess::WinProcess(DWORD procID, std::string procName)
: ProcessContext(procID, ROOT_CONTEXT_ID, CreateInternalID(procID)),
processHandle_(NULL),
monitor_(NULL)
{
processName_ = procName;
Initialize();
}
// Initialize process specific properties.
void WinProcess::Initialize() {
SetProperty(PROP_NAME, PropertyValue(processName_));
// do not support process stepping yet
int supportedResumeModes = (1 << RM_RESUME);
SetProperty(PROP_CAN_RESUME, PropertyValue(supportedResumeModes));
SetProperty(PROP_CAN_TERMINATE, PropertyValue(true));
SetProperty(PROP_CAN_SUSPEND, PropertyValue(true));
}
WinProcess::~WinProcess(void) {
processIDMap.erase(GetOSID());
GetMonitor()->ProcessDied(GetOSID());
// Destructor of parent classes will be called which will
// delete all children contexts (threads, registers, etc).
}
const HANDLE& WinProcess::GetProcessHandle() const {
return processHandle_;
}
WinProcess* WinProcess::GetProcessByID(int processID) {
std::map<int, WinProcess*>::iterator iter = processIDMap.find(processID);
if (iter == processIDMap.end())
return NULL;
return iter->second;
}
int WinProcess::ReadMemory(const ReadWriteMemoryParams& params) throw (AgentException) {
int result = 0;
BOOL success
= ::ReadProcessMemory(processHandle_, (LPCVOID) params.address,
params.memBuffer, params.size, params.sizeTransferred);
if (!success)
result = ::GetLastError();
else
BreakpointsService::RemoveBreakpointsFromMemoryRead(processHandle_, params.address, params.memBuffer, params.size);
return result;
}
int WinProcess::WriteMemory(const ReadWriteMemoryParams& params) throw (AgentException) {
int result = 0;
BOOL success
= ::WriteProcessMemory(processHandle_, (LPVOID) params.address,
params.memBuffer, params.size, params.sizeTransferred);
if (!success)
result = ::GetLastError();
else {
BreakpointsService::ReInsertBreakpointsAfterMemoryWrite(processHandle_, params.address, params.memBuffer, params.size);
}
return result;
}
void WinProcess::Terminate(const AgentActionParams& params) throw (AgentException) {
if (monitor_)
monitor_->PostAction(new TerminateProcessAction(params, GetOSID()));
}
// TODO: if we report an error, DSF gets confused...
// just report success even though it's not implemented
void WinProcess::SingleStep(const AgentActionParams& params) throw (AgentException) {
AgentActionReply::postReply(params.channel, params.token, 0);
//AgentActionReply::postReply(params.channel, params.token, ERR_UNSUPPORTED);
};
WinDebugMonitor* WinProcess::GetMonitor() const {
return monitor_;
}
std::map<int, Properties>& WinProcess::GetExecutablesByAddress() {
return executablesByAddress_;
}
void WinProcess::SetDebugRegister(WinHWBkptMgr::DRMask drMask, ContextAddress addr, WinHWBkptMgr::DRFlags flags) {
const std::list<Context*>& children = GetChildren();
std::list<Context*>::const_iterator c;
for (c = children.begin(); c != children.end(); c++) {
WinThread* winThread = dynamic_cast<WinThread*>(*c);
if (winThread != NULL)
winThread->SetDebugRegister(drMask, addr, flags);
}
}
void WinProcess::ClearDebugRegister(WinHWBkptMgr::DRMask drMask) {
const std::list<Context*>& children = GetChildren();
std::list<Context*>::const_iterator c;
for (c = children.begin(); c != children.end(); c++) {
WinThread* winThread = dynamic_cast<WinThread*>(*c);
if (winThread != NULL)
winThread->ClearDebugRegister(drMask);
}
}