Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkryall2011-10-27 16:14:51 +0000
committerkryall2011-10-27 16:14:51 +0000
commite6b773386677eaa6b3b2553b9a3b19d1b4a3f1cd (patch)
treec71b0eef1602becc42ff6b88c3a40d9dc0835448
parentc7361be627bbe4d9a15c3c8449e9c1705da591c9 (diff)
downloadorg.eclipse.cdt.edc-e6b773386677eaa6b3b2553b9a3b19d1b4a3f1cd.tar.gz
org.eclipse.cdt.edc-e6b773386677eaa6b3b2553b9a3b19d1b4a3f1cd.tar.xz
org.eclipse.cdt.edc-e6b773386677eaa6b3b2553b9a3b19d1b4a3f1cd.zip
Update the Windows debug agent: hardware watchpoint support, better
thread management, better exception handling.
-rw-r--r--org.eclipse.cdt.debug.edc.windows.agent/src/common_agent/EventClientNotifier.cpp6
-rw-r--r--org.eclipse.cdt.debug.edc.windows.agent/src/tcf_agent/framework/errors.c6
-rw-r--r--org.eclipse.cdt.debug.edc.windows.agent/src/win_agent/SettingsService.cpp4
-rw-r--r--org.eclipse.cdt.debug.edc.windows.agent/src/win_agent/WinDebugMonitor.cpp26
-rw-r--r--org.eclipse.cdt.debug.edc.windows.agent/src/win_agent/WinHWBkptMgr.cpp31
-rw-r--r--org.eclipse.cdt.debug.edc.windows.agent/src/win_agent/WinHWBkptMgr.h9
-rw-r--r--org.eclipse.cdt.debug.edc.windows.agent/src/win_agent/WinProcess.cpp8
-rw-r--r--org.eclipse.cdt.debug.edc.windows.agent/src/win_agent/WinProcess.h5
-rw-r--r--org.eclipse.cdt.debug.edc.windows.agent/src/win_agent/WinThread.cpp88
-rw-r--r--org.eclipse.cdt.debug.edc.windows.agent/src/win_agent/WinThread.h8
-rw-r--r--org.eclipse.cdt.debug.edc.windows/os/win32/x86/EDCWindowsDebugAgent.exebin4543532 -> 4546210 bytes
-rw-r--r--org.eclipse.cdt.debug.edc.windows/src/org/eclipse/cdt/debug/edc/windows/IWindowsAgentSettings.java133
12 files changed, 253 insertions, 71 deletions
diff --git a/org.eclipse.cdt.debug.edc.windows.agent/src/common_agent/EventClientNotifier.cpp b/org.eclipse.cdt.debug.edc.windows.agent/src/common_agent/EventClientNotifier.cpp
index 9aa44a7..bddea0b 100644
--- a/org.eclipse.cdt.debug.edc.windows.agent/src/common_agent/EventClientNotifier.cpp
+++ b/org.eclipse.cdt.debug.edc.windows.agent/src/common_agent/EventClientNotifier.cpp
@@ -131,7 +131,8 @@ void EventClientNotifier::SendExecutableEventCallback(void* params) {
out.writeString(eventParams->context->GetID());
out.writeZero();
- out.writeLong(eventParams->pcAddress);
+ // writeULong instead of writeLong so we won't send a negative address.
+ out.writeULong(eventParams->pcAddress);
out.writeZero();
out.writeString(REASON_SHAREDLIB);
@@ -175,7 +176,8 @@ void EventClientNotifier::SendContextSuspendedCallback(void* params_) {
out.writeString(params->context->GetID().c_str());
out.writeZero();
- out.writeLong(params->pcAddress);
+ // writeULong instead of writeLong so we won't send a negative address.
+ out.writeULong(params->pcAddress);
out.writeZero();
out.writeString(params->reason);
diff --git a/org.eclipse.cdt.debug.edc.windows.agent/src/tcf_agent/framework/errors.c b/org.eclipse.cdt.debug.edc.windows.agent/src/tcf_agent/framework/errors.c
index 1eb6066..2015d41 100644
--- a/org.eclipse.cdt.debug.edc.windows.agent/src/tcf_agent/framework/errors.c
+++ b/org.eclipse.cdt.debug.edc.windows.agent/src/tcf_agent/framework/errors.c
@@ -347,9 +347,9 @@ const char * errno_to_str(int err) {
case ERR_CACHE_MISS: return "Invalid data cache state";
case ERR_NOT_ACTIVE: return "Context is not active";
case ERR_HWBRK_NOT_SET: return "Cannot set hardware breakpoint";
- case ERR_HWBRK_INVALID_SIZE: return "Invalid size";
- case ERR_HWBRK_NO_RESOURCES: return "No resources available";
- case ERR_HWBRK_NOT_ALIGNED: return "Invalid address alignment";
+ case ERR_HWBRK_INVALID_SIZE: return "Invalid hardware breakpoint size";
+ case ERR_HWBRK_NO_RESOURCES: return "No hardware breakpoint resources available";
+ case ERR_HWBRK_NOT_ALIGNED: return "Invalid hardware breakpoint address alignment";
case ERR_HWBRK_INVALID_MODE: return "Invalid hardware breakpoint mode";
case ERR_PGPRO_UNSET: return "Cannot set page protection";
case ERR_PGPRO_UNRESET: return "Cannot reset page protection";
diff --git a/org.eclipse.cdt.debug.edc.windows.agent/src/win_agent/SettingsService.cpp b/org.eclipse.cdt.debug.edc.windows.agent/src/win_agent/SettingsService.cpp
index 0a682ad..c4a4c9a 100644
--- a/org.eclipse.cdt.debug.edc.windows.agent/src/win_agent/SettingsService.cpp
+++ b/org.eclipse.cdt.debug.edc.windows.agent/src/win_agent/SettingsService.cpp
@@ -59,7 +59,7 @@ SettingsService::SettingsService(Protocol * proto) :
TCFService(proto) {
allowFilenameMatch = false;
enableDebugStringLogging = true;
- exceptionsBitmask = 0x00000000L; // no exceptions reported by default
+ exceptionsBitmask = 0xffffffffL; // report all exception by default
AddCommand("get", command_get_settings); // compatibility -- not used
AddCommand("getIds", command_get_settings);
@@ -168,7 +168,9 @@ std::string getFilenameFromPath(std::string path)
*/
void SettingsService::debugSessionEnds()
{
+ // reset to default.
modulesToDebug.clear();
+ exceptionsBitmask = 0xffffffffL; // report all exception by default
}
bool SettingsService::reportDebugEventForModule(std::string module)
diff --git a/org.eclipse.cdt.debug.edc.windows.agent/src/win_agent/WinDebugMonitor.cpp b/org.eclipse.cdt.debug.edc.windows.agent/src/win_agent/WinDebugMonitor.cpp
index 32c63d3..e75a192 100644
--- a/org.eclipse.cdt.debug.edc.windows.agent/src/win_agent/WinDebugMonitor.cpp
+++ b/org.eclipse.cdt.debug.edc.windows.agent/src/win_agent/WinDebugMonitor.cpp
@@ -628,13 +628,14 @@ void WinDebugMonitor::HandleThreadCreatedEvent(DEBUG_EVENT& debugEvent)
if (process) {
WinThread* thread = new WinThread(*process, debugEvent);
thread->SetDebugging(true);
+ thread->DuplicateDebugRegisters();
ContextManager::addContext(thread);
EventClientNotifier::SendContextAdded(thread);
} else {
assert(false);
}
- ContinueDebugEvent(debugEvent.dwProcessId, debugEvent.dwThreadId, DBG_CONTINUE);
+ ::ContinueDebugEvent(debugEvent.dwProcessId, debugEvent.dwThreadId, DBG_CONTINUE);
}
void WinDebugMonitor::HandleProcessExitedEvent(DEBUG_EVENT& debugEvent)
@@ -680,25 +681,19 @@ void WinDebugMonitor::HandleDLLLoadedEvent(DEBUG_EVENT& debugEvent)
unsigned long baseOfCode = 0;
std::string moduleName = GetExecutableInfo(debugEvent.u.LoadDll.hFile, baseOfCode, codeSize);
- if (SettingsService::reportDebugEventForModule(moduleName))
- {
- LogTrace("DebugProcessMonitor::HandleDLLLoadedEvent", "Base address: %8.8x %s", debugEvent.u.LoadDll.lpBaseOfDll, moduleName.c_str());
- WinThread* thread = WinThread::GetThreadByID(debugEvent.dwProcessId, debugEvent.dwThreadId);
- if (thread) {
- thread->HandleExecutableEvent(true, moduleName, (unsigned long)debugEvent.u.LoadDll.lpBaseOfDll, codeSize);
- }
- }
- else
- {
+ CloseHandle(debugEvent.u.LoadDll.hFile);
+
+ LogTrace("DebugProcessMonitor::HandleDLLLoadedEvent", "Base address: %8.8x %s", debugEvent.u.LoadDll.lpBaseOfDll, moduleName.c_str());
+ WinThread* thread = WinThread::GetThreadByID(debugEvent.dwProcessId, debugEvent.dwThreadId);
+ if (thread) {
+ thread->HandleExecutableEvent(true, moduleName, (unsigned long)debugEvent.u.LoadDll.lpBaseOfDll, codeSize);
+ } else {
ContinueDebugEvent(debugEvent.dwProcessId, debugEvent.dwThreadId, DBG_CONTINUE);
}
-
- CloseHandle(debugEvent.u.LoadDll.hFile);
}
void WinDebugMonitor::HandleDLLUnloadedEvent(DEBUG_EVENT& debugEvent)
{
- // if our process knows about this dll then it must be in the list of modules to debug
WinProcess* process = WinProcess::GetProcessByID(debugEvent.dwProcessId);
if (process)
{
@@ -708,10 +703,13 @@ void WinDebugMonitor::HandleDLLUnloadedEvent(DEBUG_EVENT& debugEvent)
WinThread* thread = WinThread::GetThreadByID(debugEvent.dwProcessId, debugEvent.dwThreadId);
if (thread) {
thread->HandleExecutableEvent(false, "", (unsigned long)debugEvent.u.UnloadDll.lpBaseOfDll, 0);
+ // HandleExecutableEvent will decide if we need to continue the debug event or not, so return
+ return;
}
}
}
+ // we get here if the event wasn't passed onto the thread to handle
ContinueDebugEvent(debugEvent.dwProcessId, debugEvent.dwThreadId, DBG_CONTINUE);
}
diff --git a/org.eclipse.cdt.debug.edc.windows.agent/src/win_agent/WinHWBkptMgr.cpp b/org.eclipse.cdt.debug.edc.windows.agent/src/win_agent/WinHWBkptMgr.cpp
index 3c3e7b1..04e5705 100644
--- a/org.eclipse.cdt.debug.edc.windows.agent/src/win_agent/WinHWBkptMgr.cpp
+++ b/org.eclipse.cdt.debug.edc.windows.agent/src/win_agent/WinHWBkptMgr.cpp
@@ -172,11 +172,11 @@ unsigned char WinHWBkptMgr::UnusedCount() {
return MAX_HWBP - InUseCount();
}
-WinHWBkptMgr::DRMask WinHWBkptMgr::UseUnusedRegister() {
- if (!(DR0 & inUse)) { inUse |= DR0; return DR0; }
- if (!(DR1 & inUse)) { inUse |= DR1; return DR1; }
- if (!(DR2 & inUse)) { inUse |= DR2; return DR2; }
- if (!(DR3 & inUse)) { inUse |= DR3; return DR3; }
+WinHWBkptMgr::DRNum WinHWBkptMgr::UseUnusedRegister() {
+ if (!(DR0 & inUse)) { inUse |= DR0; return 0; }
+ if (!(DR1 & inUse)) { inUse |= DR1; return 1; }
+ if (!(DR2 & inUse)) { inUse |= DR2; return 2; }
+ if (!(DR3 & inUse)) { inUse |= DR3; return 3; }
return 0;
}
@@ -223,8 +223,8 @@ int WinHWBkptMgr::SetHardwareBreak(TBreakpoint* bp) {
hwBkpt[wp].tcfBp = bp;
hwBkpt[wp].accessMode = hwMode;
for (;reqdRegs > 0;--reqdRegs) {
- DRMask dr = UseUnusedRegister();
- hwBkpt[wp].inUse |= dr;
+ DRNum dr = UseUnusedRegister();
+ hwBkpt[wp].inUse |= 1 << dr;
unsigned char drSz; // size to set in DR register
switch (locAddr & 7) {
@@ -240,7 +240,9 @@ int WinHWBkptMgr::SetHardwareBreak(TBreakpoint* bp) {
// these are shifted inside based on the reg used
DRFlags dr7bits = sDR7SizeBitsMap(drSz) | hwBkpt[wp].accessMode;
- bp->process->SetDebugRegister(dr, locAddr, dr7bits);
+ hwBkpt[wp].dbgReg[dr].address = locAddr;
+ hwBkpt[wp].dbgReg[dr].flags = dr7bits;
+ bp->process->SetDebugRegister(dr, hwBkpt[wp].dbgReg[dr]);
locAddr += drSz;
locSize -= drSz;
@@ -256,16 +258,13 @@ int WinHWBkptMgr::ClearHardwareBreak(TBreakpoint* bp) {
AgentBreakID& wp = bp->agentBreakID;
if (wp == AGENT_BREAK_UNSET)
return ERR_HWBRK_NOT_SET;
- for (int i = 0; i < MAX_HWBP; ++i) {
- DRMask dr = 1 << i;
- if (hwBkpt[wp].inUse & dr) {
- inUse &= ~dr;
- bp->process->ClearDebugRegister(dr);
- }
- }
+
+ DRMask& wpInUse = hwBkpt[wp].inUse;
+ bp->process->ClearDebugRegisters(wpInUse);
+ inUse &= ~wpInUse;
+ wpInUse = 0;
hwBkpt[wp].tcfBp = NULL;
- hwBkpt[wp].inUse = 0;
bp->process = NULL;
wp = AGENT_BREAK_UNSET;
return 0;
diff --git a/org.eclipse.cdt.debug.edc.windows.agent/src/win_agent/WinHWBkptMgr.h b/org.eclipse.cdt.debug.edc.windows.agent/src/win_agent/WinHWBkptMgr.h
index 930f303..8cd1bf0 100644
--- a/org.eclipse.cdt.debug.edc.windows.agent/src/win_agent/WinHWBkptMgr.h
+++ b/org.eclipse.cdt.debug.edc.windows.agent/src/win_agent/WinHWBkptMgr.h
@@ -71,8 +71,9 @@ class WinHWBkptMgr {
WinHWBkptMgr();
- typedef unsigned char DRMask;
typedef unsigned char DRFlags;
+ typedef unsigned char DRMask;
+ typedef unsigned char DRNum;
int SetHardwareBreak(TBreakpoint*);
int ClearHardwareBreak(TBreakpoint*);
@@ -86,10 +87,16 @@ class WinHWBkptMgr {
static const Mode readwrite = 0x03;
static const Mode invalid = 0x04;
+ struct DbgRegInfo {
+ ContextAddress address;
+ DRFlags flags;
+ };
+
struct HWBreakInfo {
TBreakpoint* tcfBp;
DRMask inUse; // mask of the regs used for this hw-break
Mode accessMode; // accessMode to use for all regs used
+ DbgRegInfo dbgReg[MAX_HWBP];
HWBreakInfo() : tcfBp(NULL), inUse(0) {}
};
diff --git a/org.eclipse.cdt.debug.edc.windows.agent/src/win_agent/WinProcess.cpp b/org.eclipse.cdt.debug.edc.windows.agent/src/win_agent/WinProcess.cpp
index feeae09..8d98d14 100644
--- a/org.eclipse.cdt.debug.edc.windows.agent/src/win_agent/WinProcess.cpp
+++ b/org.eclipse.cdt.debug.edc.windows.agent/src/win_agent/WinProcess.cpp
@@ -192,22 +192,22 @@ size_t WinProcess::SoftwareWatchpointCount() const {
return hwPageProtMgr.watchpoints.size();
}
-void WinProcess::SetDebugRegister(WinHWBkptMgr::DRMask drMask, ContextAddress addr, WinHWBkptMgr::DRFlags flags) {
+void WinProcess::SetDebugRegister(WinHWBkptMgr::DRNum drNum, const WinHWBkptMgr::DbgRegInfo& info) {
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);
+ winThread->SetDebugRegister(drNum, info);
}
}
-void WinProcess::ClearDebugRegister(WinHWBkptMgr::DRMask drMask) {
+void WinProcess::ClearDebugRegisters(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);
+ winThread->ClearDebugRegisters(drMask);
}
}
diff --git a/org.eclipse.cdt.debug.edc.windows.agent/src/win_agent/WinProcess.h b/org.eclipse.cdt.debug.edc.windows.agent/src/win_agent/WinProcess.h
index 49423a3..ac0f4a5 100644
--- a/org.eclipse.cdt.debug.edc.windows.agent/src/win_agent/WinProcess.h
+++ b/org.eclipse.cdt.debug.edc.windows.agent/src/win_agent/WinProcess.h
@@ -55,9 +55,9 @@ public:
void Initialize();
friend int WinHWBkptMgr::SetHardwareBreak(TBreakpoint*);
- void SetDebugRegister(WinHWBkptMgr::DRMask, ContextAddress, WinHWBkptMgr::DRFlags);
+ void SetDebugRegister(WinHWBkptMgr::DRMask, const WinHWBkptMgr::DbgRegInfo&);
friend int WinHWBkptMgr::ClearHardwareBreak(TBreakpoint*);
- void ClearDebugRegister(WinHWBkptMgr::DRMask);
+ void ClearDebugRegisters(WinHWBkptMgr::DRMask);
bool isRoot_;
HANDLE processHandle_;
@@ -67,6 +67,7 @@ public:
static std::map<int, WinProcess*> processIDMap;
+ friend void WinThread::DuplicateDebugRegisters();
WinHWBkptMgr hwBkptMgr;
friend bool WinThread::HandlePotentialProtctedPage(const DEBUG_EVENT&);
diff --git a/org.eclipse.cdt.debug.edc.windows.agent/src/win_agent/WinThread.cpp b/org.eclipse.cdt.debug.edc.windows.agent/src/win_agent/WinThread.cpp
index f4ce51b..fee79ef 100644
--- a/org.eclipse.cdt.debug.edc.windows.agent/src/win_agent/WinThread.cpp
+++ b/org.eclipse.cdt.debug.edc.windows.agent/src/win_agent/WinThread.cpp
@@ -23,6 +23,7 @@
#include "ProtocolConstants.h"
#include "RunControlService.h"
#include "BreakpointsService.h"
+#include "SettingsService.h"
std::map<std::pair<int, int>, WinThread*> WinThread::threadIDMap_;
@@ -283,8 +284,8 @@ void WinThread::AdjustPC() {
void WinThread::HandleExecutableEvent(bool isLoaded, const std::string& exePath,
unsigned long baseAddress, unsigned long codeSize) {
- MarkSuspended();
- EnsureValidContextInfo();
+
+ std::string module = exePath;
Properties props;
if (isLoaded)
@@ -303,12 +304,31 @@ void WinThread::HandleExecutableEvent(bool isLoaded, const std::string& exePath,
assert(!props.empty());
props[PROP_MODULE_LOADED] = PropertyValue(false);
+ // we don't get the module name for unloaded events, so get it from the properties
+ module = props[PROP_FILE].getStringValue();
+
// the executable is unloaded so remove it from our list of executables
// otherwise if another executable is later loaded into the same address
// and later unloaded, we'll send a bogus unloaded event
parentProcess_.GetExecutablesByAddress().erase(baseAddress);
}
+ if (SettingsService::reportDebugEventForModule(module)) {
+ // report the event. we'll wait for the debugger to resume the thread
+ // once it's done what it needs to do (set breakpoints, etc)
+ props[PROP_REQUIRED_RESUME] = PropertyValue(true);
+ MarkSuspended();
+ EnsureValidContextInfo();
+ } else {
+ // not in the list of modules we're debugging. we send the event
+ // so the debugger knows what modules live where, but we're not
+ // debugging it so we don't expect breakpoints to be set. just
+ // continue the event. note that sending the event without waiting
+ // for the round trip to get the resume event won't slow us down.
+ props[PROP_REQUIRED_RESUME] = PropertyValue(false);
+ ContinueDebugEvent(parentProcess_.GetOSID(), GetOSID(), DBG_CONTINUE);
+ }
+
EventClientNotifier::SendExecutableEvent(this,
threadContextInfo_.Eip, props);
}
@@ -609,27 +629,27 @@ void WinThread::PrepareForTermination(const AgentActionParams& params) throw (Ag
}
}
-void WinThread::SetDebugRegister(WinHWBkptMgr::DRMask dRegs, ContextAddress addr, WinHWBkptMgr::DRFlags dr7bits) {
+void WinThread::SetDebugRegister(WinHWBkptMgr::DRNum drNum, const WinHWBkptMgr::DbgRegInfo& info) {
bool suspended = isSuspended_;
if (!suspended)
Suspend();
DWORD& DR7 = threadContextInfo_.Dr7;
- switch (dRegs) {
- case DR0:
- threadContextInfo_.Dr0 = addr;
- DR7 = (DR7 & ~0x000F0003) | (dr7bits<<16) | 0x01;
+ switch (drNum) {
+ case 0:
+ threadContextInfo_.Dr0 = info.address;
+ DR7 = (DR7 & ~0x000F0003) | (info.flags<<16) | 0x01;
break;
- case DR1:
- threadContextInfo_.Dr1 = addr;
- DR7 = (DR7 & ~0x00F0000C) | (dr7bits<<20) | 0x04;
+ case 1:
+ threadContextInfo_.Dr1 = info.address;
+ DR7 = (DR7 & ~0x00F0000C) | (info.flags<<20) | 0x04;
break;
- case DR2:
- threadContextInfo_.Dr2 = addr;
- DR7 = (DR7 & ~0x0F000030) | (dr7bits<<24) | 0x10;
+ case 2:
+ threadContextInfo_.Dr2 = info.address;
+ DR7 = (DR7 & ~0x0F000030) | (info.flags<<24) | 0x10;
break;
- case DR3:
- threadContextInfo_.Dr3 = addr;
- DR7 = (DR7 & ~0xF00000C0) | (dr7bits<<28) | 0x40;
+ case 3:
+ threadContextInfo_.Dr3 = info.address;
+ DR7 = (DR7 & ~0xF00000C0) | (info.flags<<28) | 0x40;
break;
default:
return;
@@ -639,20 +659,38 @@ void WinThread::SetDebugRegister(WinHWBkptMgr::DRMask dRegs, ContextAddress addr
Resume();
}
-void WinThread::ClearDebugRegister(WinHWBkptMgr::DRMask singleDReg) {
+void WinThread::ClearDebugRegisters(WinHWBkptMgr::DRMask mask) {
bool suspended = isSuspended_;
if (!suspended)
Suspend();
DWORD& DR7 = threadContextInfo_.Dr7;
- switch (singleDReg) {
- case DR0: DR7 &= ~0x000F0003; break;
- case DR1: DR7 &= ~0x00F0000C; break;
- case DR2: DR7 &= ~0x0F000030; break;
- case DR3: DR7 &= ~0xF00000C0; break;
- default:
- return;
- }
+ if (mask & DR0) DR7 &= ~0x000F0003;
+ if (mask & DR1) DR7 &= ~0x00F0000C;
+ if (mask & DR2) DR7 &= ~0x0F000030;
+ if (mask & DR3) DR7 &= ~0xF00000C0;
+
::SetThreadContext(handle_, &threadContextInfo_);
if (!suspended)
Resume();
}
+
+void WinThread::DuplicateDebugRegisters() {
+ WinHWBkptMgr& mgr = parentProcess_.hwBkptMgr;
+ if (mgr.inUse
+ && SUCCEEDED(::GetThreadContext(handle_, &threadContextInfo_))) {
+ int count = 0;
+ for (int i = 0; i < MAX_HWBP && count < MAX_HWBP; ++i) {
+ WinHWBkptMgr::HWBreakInfo& hwbp = mgr.hwBkpt[i];
+ if (hwbp.inUse) {
+ for (int j = 0; j < MAX_HWBP && count < MAX_HWBP; ++j) {
+ WinHWBkptMgr::DRMask drMask = 1 << j;
+ if (hwbp.inUse & drMask) {
+ SetDebugRegister(j, hwbp.dbgReg[j]);
+ ++count;
+ }
+ }
+ }
+ }
+ ::SetThreadContext(handle_, &threadContextInfo_);
+ }
+}
diff --git a/org.eclipse.cdt.debug.edc.windows.agent/src/win_agent/WinThread.h b/org.eclipse.cdt.debug.edc.windows.agent/src/win_agent/WinThread.h
index ff96362..c01c18f 100644
--- a/org.eclipse.cdt.debug.edc.windows.agent/src/win_agent/WinThread.h
+++ b/org.eclipse.cdt.debug.edc.windows.agent/src/win_agent/WinThread.h
@@ -12,7 +12,7 @@
#include "stdafx.h"
#include "ThreadContext.h"
-#include "WinHWBkptMgr.h" // for DRMask, DRFlags on SetDebugRegister/ClearDebugRegister
+#include "WinHWBkptMgr.h" // for DRMask, DRFlags on SetDebugRegister/ClearDebugRegisters
#define DR0 0x01
#define DR1 0x02
@@ -74,8 +74,10 @@ public:
DWORD GetContinueStatus() const;
- void SetDebugRegister(WinHWBkptMgr::DRMask, ContextAddress, WinHWBkptMgr::DRFlags);
- void ClearDebugRegister(WinHWBkptMgr::DRMask);
+ void SetDebugRegister(WinHWBkptMgr::DRNum, const WinHWBkptMgr::DbgRegInfo&);
+ void ClearDebugRegisters(WinHWBkptMgr::DRMask);
+
+ void DuplicateDebugRegisters();
private:
void Resume();
diff --git a/org.eclipse.cdt.debug.edc.windows/os/win32/x86/EDCWindowsDebugAgent.exe b/org.eclipse.cdt.debug.edc.windows/os/win32/x86/EDCWindowsDebugAgent.exe
index 94c8fca..546f519 100644
--- a/org.eclipse.cdt.debug.edc.windows/os/win32/x86/EDCWindowsDebugAgent.exe
+++ b/org.eclipse.cdt.debug.edc.windows/os/win32/x86/EDCWindowsDebugAgent.exe
Binary files differ
diff --git a/org.eclipse.cdt.debug.edc.windows/src/org/eclipse/cdt/debug/edc/windows/IWindowsAgentSettings.java b/org.eclipse.cdt.debug.edc.windows/src/org/eclipse/cdt/debug/edc/windows/IWindowsAgentSettings.java
new file mode 100644
index 0000000..7bfc833
--- /dev/null
+++ b/org.eclipse.cdt.debug.edc.windows/src/org/eclipse/cdt/debug/edc/windows/IWindowsAgentSettings.java
@@ -0,0 +1,133 @@
+package org.eclipse.cdt.debug.edc.windows;
+
+/**
+ * @since 2.1
+ */
+public interface IWindowsAgentSettings {
+
+ /**
+ * Allows the client to filter module events (loaded/unloaded).
+ *
+ * By default all module events are reported. Use this setting if you're
+ * only interested in events for specific modules.
+ *
+ * Accepts an array of strings containing full paths to the modules
+ * for which to report events. Any events for modules not exactly matching
+ * a path in the module filter list will not be reported to the client.
+ *
+ * The agent maintains a set of modules for its life cycle. This can be passed
+ * multiple times if needed. Each time it will simply append any new modules to
+ * the list.
+ */
+ public static final String ADD_MODULES = "addModules";
+
+ /**
+ * Allows the client to better control the module filter matching.
+ *
+ * The filtering mechanism above requires an exact match of full paths. If the
+ * client only requires that the module filename matches, this setting should be
+ * set to true. The default value is false.
+ */
+ public static final String ALLOW_FILENAME_MATCH = "allowFilenameMatch";
+
+
+ /**
+ * Allows the client to enable/disable logging of debug string messages.
+ *
+ * Processes under debug can use the Windows API OutputDebugString to print debug
+ * messages. When set to true, this setting will send these messages to the client
+ * through the Logging service. This is on by default. Send this setting with a
+ * value of false to disable.
+ */
+ public static final String ENABLE_DEBUG_STRING_LOGGING = "enableDebugStringLogging";
+
+ /**
+ * Allows the client to control which exceptions should be reported by the agent.
+ *
+ * The bit mask is a 32-bit integer value with each bit representing the enabled
+ * state of a specific exception. Set the bit to be notified of the exception.
+ * Clear the bit to disable notification.
+ *
+ * The constants below can be OR'ed together to form the bit mask to be sent to the agent.
+ *
+ * The list of exceptions and other events is taken from winnt.h and winbase.h and
+ * documented with the Windows EXCEPTION_RECORD structure here:
+ * http://msdn.microsoft.com/en-us/library/aa363082%28v=vs.85%29.aspx
+ *
+ * EXCEPTION_BREAKPOINT and EXCEPTION_SINGLE_STEP are intentionally omitted as they're
+ * required for debug functionality.
+ *
+ * More detail on individual events can be found here:
+ * http://msdn.microsoft.com/en-us/library/cc704588%28v=prot.10%29.aspx
+ */
+ public static final String EXCEPTIONS_BITMASK = "exceptionsBitmask";
+
+ public static final int EXCEPTION_ACCESS_VIOLATION = 1 << 0;
+
+ public static final int EXCEPTION_ARRAY_BOUNDS_EXCEEDED = 1 << 1;
+
+ public static final int EXCEPTION_DATATYPE_MISALIGNMENT = 1 << 2;
+
+ public static final int EXCEPTION_FLT_DENORMAL_OPERAND = 1 << 3;
+
+ public static final int EXCEPTION_FLT_DIVIDE_BY_ZERO = 1 << 4;
+
+ public static final int EXCEPTION_FLT_INEXACT_RESULT = 1 << 5;
+
+ public static final int EXCEPTION_FLT_INVALID_OPERATION = 1 << 6;
+
+ public static final int EXCEPTION_FLT_OVERFLOW = 1 << 7;
+
+ public static final int EXCEPTION_FLT_STACK_CHECK = 1 << 8;
+
+ public static final int EXCEPTION_FLT_UNDERFLOW = 1 << 9;
+
+ public static final int EXCEPTION_ILLEGAL_INSTRUCTION = 1 << 10;
+
+ public static final int EXCEPTION_IN_PAGE_ERROR = 1 << 11;
+
+ public static final int EXCEPTION_INT_DIVIDE_BY_ZERO = 1 << 12;
+
+ public static final int EXCEPTION_INT_OVERFLOW = 1 << 13;
+
+ public static final int EXCEPTION_INVALID_DISPOSITION = 1 << 14;
+
+ public static final int EXCEPTION_NONCONTINUABLE_EXCEPTION = 1 << 15;
+
+ public static final int EXCEPTION_PRIV_INSTRUCTION = 1 << 16;
+
+ public static final int EXCEPTION_STACK_OVERFLOW = 1 << 17;
+
+ /*
+ * The following are listed in more recent versions of winbase.h but not well documented.
+ */
+ public static final int EXCEPTION_GUARD_PAGE = 1 << 18;
+
+ public static final int EXCEPTION_INVALID_HANDLE = 1 << 19;
+
+ /*
+ * The following are more debug events then exceptions.
+ */
+ public static final int DBG_CONTROL_C = 1 << 20;
+
+ public static final int DBG_CONTROL_BREAK = 1 << 21;
+
+ /*
+ * The following are listed in recent versions of winbase.h (but not as exceptions). They can
+ * be reported by Windows in the same fashion as exceptions though.
+ */
+ public static final int STATUS_NO_MEMORY = 1 << 22;
+
+ public static final int STATUS_DLL_INIT_FAILED = 1 << 23;
+
+ /*
+ * The following are not listed in Windows headers but do get reported in the same fashion
+ * and the debugger may want to break on them like exceptions.
+ */
+ public static final int STATUS_DLL_NOT_FOUND = 1 << 24;
+
+ public static final int STATUS_ENTRYPOINT_NOT_FOUND = 1 << 25;
+
+ public static final int MS_CPLUS_EXCEPTION = 1 << 26;
+
+}

Back to the top