#include <memory>
#include <unordered_map>
#include <vector>
+#include <map>
#include "torelease.h"
std::string &fullname);
-std::mutex g_breakMutex;
-ULONG32 g_breakIndex = 1;
+static std::mutex g_breakMutex;
+static ULONG32 g_breakIndex = 1;
struct Breakpoint {
ULONG32 id;
ULONG32 ilOffset;
std::string fullname;
int linenum;
- ICorDebugBreakpoint *breakpoint;
+ ToRelease<ICorDebugBreakpoint> breakpoint;
bool IsResolved() const
{
}
Breakpoint() : id(0), modAddress(0), methodToken(0), ilOffset(0), linenum(0), breakpoint(nullptr) {}
+
+ ~Breakpoint()
+ {
+ if (breakpoint)
+ breakpoint->Activate(0);
+ }
+
+ Breakpoint(Breakpoint &&that) = default;
+
+ Breakpoint(const Breakpoint &that) = delete;
};
-std::vector<Breakpoint> g_breaks;
+static std::map<ULONG32, Breakpoint> g_breaks;
HRESULT PrintBreakpoint(ULONG32 id, std::string &output)
{
std::lock_guard<std::mutex> lock(g_breakMutex);
- for (Breakpoint &b : g_breaks)
- {
- if (b.id != id)
- continue;
+ auto it = g_breaks.find(id);
- std::stringstream ss;
+ if (it == g_breaks.end())
+ return E_FAIL;
- HRESULT Status;
- if (b.IsResolved())
- {
- ss << "bkpt={number=\"" << id << "\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\","
- "func=\"\",fullname=\"" << b.fullname << "\",line=\"" << b.linenum << "\"}";
- Status = S_OK;
- }
- else
- {
- ss << "bkpt={number=\"" << id << "\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\","
- "warning=\"No executable code of the debugger's target code type is associated with this line.\"}";
- Status = S_FALSE;
- }
- output = ss.str();
- return Status;
- }
+ Breakpoint &b = it->second;
- return E_FAIL;
+ std::stringstream ss;
+
+ HRESULT Status;
+ if (b.IsResolved())
+ {
+ ss << "bkpt={number=\"" << id << "\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\","
+ "func=\"\",fullname=\"" << b.fullname << "\",line=\"" << b.linenum << "\"}";
+ Status = S_OK;
+ }
+ else
+ {
+ ss << "bkpt={number=\"" << id << "\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\","
+ "warning=\"No executable code of the debugger's target code type is associated with this line.\"}";
+ Status = S_FALSE;
+ }
+ output = ss.str();
+ return S_OK;
}
HRESULT FindCurrentBreakpointId(ICorDebugThread *pThread, ULONG32 &id)
std::lock_guard<std::mutex> lock(g_breakMutex);
- for (Breakpoint &b : g_breaks)
+ for (auto &it : g_breaks)
{
+ Breakpoint &b = it.second;
+
if (b.fullname == fullname &&
b.ilOffset == ilOffset &&
b.methodToken == methodToken &&
{
std::lock_guard<std::mutex> lock(g_breakMutex);
- auto bpit = g_breaks.begin();
-
- while(bpit != g_breaks.end())
- {
- if (bpit->id == id)
- {
- if (bpit->breakpoint)
- {
- bpit->breakpoint->Activate(0);
- bpit->breakpoint->Release();
- }
- bpit = g_breaks.erase(bpit);
- return S_OK;
- }
- else
- {
- ++bpit;
- }
- }
+ g_breaks.erase(id);
- return E_FAIL;
+ return S_OK;
}
void DeleteAllBreakpoints()
{
std::lock_guard<std::mutex> lock(g_breakMutex);
- for (Breakpoint &b : g_breaks)
- {
- if (b.breakpoint)
- {
- b.breakpoint->Activate(0);
- b.breakpoint->Release();
- }
- }
-
g_breaks.clear();
}
{
std::lock_guard<std::mutex> lock(g_breakMutex);
- for (Breakpoint &b : g_breaks)
+ for (auto &it : g_breaks)
{
+ Breakpoint &b = it.second;
+
if (b.IsResolved())
continue;
std::lock_guard<std::mutex> lock(g_breakMutex);
id = g_breakIndex++;
bp.id = id;
- g_breaks.push_back(bp);
+ g_breaks.insert(std::make_pair(id, std::move(bp)));
return S_OK;
}
}
std::lock_guard<std::mutex> lock(g_breakMutex);
id = g_breakIndex++;
bp.id = id;
- g_breaks.push_back(bp);
+ g_breaks.insert(std::make_pair(id, std::move(bp)));
return S_FALSE;
}
\ No newline at end of file