HRESULT HitBreakpoint(ICorDebugThread *pThread, ULONG32 &id, ULONG32 ×)
{
HRESULT Status;
+
ULONG32 ilOffset;
+ Modules::SequencePoint sp;
mdMethodDef methodToken;
- std::string fullname;
- ULONG linenum;
ToRelease<ICorDebugFrame> pFrame;
IfFailRet(pThread->GetActiveFrame(&pFrame));
- IfFailRet(Modules::GetFrameLocation(pFrame, ilOffset, methodToken, fullname, linenum));
+ IfFailRet(pFrame->GetFunctionToken(&methodToken));
+
+ IfFailRet(Modules::GetFrameLocation(pFrame, ilOffset, sp));
std::lock_guard<std::mutex> lock(g_breakMutex);
{
Breakpoint &b = it.second;
- if (b.fullname == fullname &&
+ if (b.fullname == sp.document &&
b.ilOffset == ilOffset &&
b.methodToken == methodToken &&
- b.linenum == linenum &&
+ b.linenum == sp.startLine &&
b.enabled)
{
id = b.id;
HRESULT PrintFrameLocation(ICorDebugFrame *pFrame, std::string &output)
{
HRESULT Status;
+
ULONG32 ilOffset;
- mdMethodDef methodToken;
- std::string fullname;
- ULONG linenum;
+ Modules::SequencePoint sp;
bool has_source = false;
std::stringstream ss;
- if (SUCCEEDED(Modules::GetFrameLocation(pFrame, ilOffset, methodToken, fullname, linenum)))
+ if (SUCCEEDED(Modules::GetFrameLocation(pFrame, ilOffset, sp)))
{
- ss << "line=\"" << linenum << "\","
- << "fullname=\"" << Debugger::EscapeMIValue(fullname) << "\","
- <<"file=\"" << GetFileName(fullname) << "\",";
+ ss << "line=\"" << sp.startLine << "\","
+ << "fullname=\"" << Debugger::EscapeMIValue(sp.document) << "\","
+ << "file=\"" << GetFileName(sp.document) << "\",";
has_source = true;
}
+ mdMethodDef methodToken;
IfFailRet(pFrame->GetFunctionToken(&methodToken));
ToRelease<ICorDebugFunction> pFunc;
HRESULT GetFrameLocation(ICorDebugFrame *pFrame,
ULONG32 &ilOffset,
- mdMethodDef &methodToken,
- std::string &fullname,
- ULONG &linenum)
+ Modules::SequencePoint &sequencePoint)
{
HRESULT Status;
+ mdMethodDef methodToken;
IfFailRet(pFrame->GetFunctionToken(&methodToken));
ToRelease<ICorDebugFunction> pFunc;
WCHAR name[MAX_LONGPATH];
+ std::vector<SymbolReader::SequencePoint> points;
+ ULONG linenum;
+
{
std::lock_guard<std::mutex> lock(g_modulesInfoMutex);
auto info_pair = g_modulesInfo.find(modAddress);
}
IfFailRet(info_pair->second.symbols->GetLineByILOffset(methodToken, ilOffset, &linenum, name, _countof(name)));
+ IfFailRet(info_pair->second.symbols->GetSequencePoints(methodToken, points));
}
- fullname = to_utf8(name);
+ if (points.empty())
+ return E_FAIL;
- return S_OK;
+ // TODO: Merge with similar code in SymbolReader.cs
+
+ SymbolReader::SequencePoint &nearestPoint = points.front();
+
+ for (auto &p : points)
+ {
+ if (p.offset < ilOffset)
+ {
+ nearestPoint = p;
+ continue;
+ }
+ if (p.offset == ilOffset)
+ nearestPoint = p;
+
+ sequencePoint.startLine = nearestPoint.startLine;
+ sequencePoint.endLine = nearestPoint.endLine;
+ sequencePoint.startColumn = nearestPoint.startColumn;
+ sequencePoint.endColumn = nearestPoint.endColumn;
+ sequencePoint.offset = nearestPoint.offset;
+ sequencePoint.document = to_utf8(name);
+ return S_OK;
+ }
+
+ return E_FAIL;
}
HRESULT GetStepRangeFromCurrentIP(ICorDebugThread *pThread, COR_DEBUG_STEP_RANGE *range)
namespace Modules
{
+struct SequencePoint {
+ int32_t startLine;
+ int32_t startColumn;
+ int32_t endLine;
+ int32_t endColumn;
+ int32_t offset;
+ std::string document;
+};
+
HRESULT GetModuleId(ICorDebugModule *pModule, std::string &id);
HRESULT GetModuleWithName(const std::string &name, ICorDebugModule **ppModule);
HRESULT GetFrameLocation(ICorDebugFrame *pFrame,
ULONG32 &ilOffset,
- mdMethodDef &methodToken,
- std::string &fullname,
- ULONG &linenum);
+ Modules::SequencePoint &sequencePoint);
HRESULT GetLocationInModule(ICorDebugModule *pModule,
std::string filename,