NATIVE(jint, nativeGetId)(JNIEnv * env, jclass cls, jlong p) { IDebugBreakpoint2 * bp = (IDebugBreakpoint2 *)p; ULONG id; HRESULT hr = bp->GetId(&id); if (FAILED(hr)) throwHRESULT(env, hr); return id; }
NATIVE(void, nativeSetOffsetExpression)(JNIEnv * env, jclass cls, jlong p, jstring expression) { IDebugBreakpoint2 * bp = (IDebugBreakpoint2 *)p; const jchar * exprStr = env->GetStringChars(expression, NULL); HRESULT hr = bp->SetOffsetExpressionWide((const wchar_t *)exprStr); if (FAILED(hr)) throwHRESULT(env, hr); env->ReleaseStringChars(expression, exprStr); }
bool CDBBreakPoint::add(CIDebugControl* debugControl, QString *errorMessage, unsigned long *id, quint64 *address) const { IDebugBreakpoint2* ibp = 0; if (address) *address = 0; if (id) *id = 0; HRESULT hr = debugControl->AddBreakpoint2(DEBUG_BREAKPOINT_CODE, DEBUG_ANY_ID, &ibp); if (FAILED(hr)) { *errorMessage = msgCannotAddBreakPoint(msgComFailed("AddBreakpoint2", hr)); return false; } if (!ibp) { *errorMessage = msgCannotAddBreakPoint(QLatin1String("<Unknown error>")); return false; } if (!apply(ibp, errorMessage)) return false; // GetOffset can fail when attaching to remote processes, ignore return if (address) { hr = ibp->GetOffset(address); if (FAILED(hr)) *address = 0; } if (id) { hr = ibp->GetId(id); if (FAILED(hr)) { *errorMessage = msgCannotAddBreakPoint(msgComFailed("GetId", hr)); return false; } } return true; }
NATIVE(void, nativeAddFlags)(JNIEnv * env, jclass cls, jlong p, jint flags) { IDebugBreakpoint2 * bp = (IDebugBreakpoint2 *)p; HRESULT hr = bp->AddFlags(flags); if (FAILED(hr)) throwHRESULT(env, hr); }
// Synchronize (halted) engine breakpoints with those of the BreakHandler. bool CDBBreakPoint::synchronizeBreakPoints(IDebugControl4* debugControl, BreakHandler *handler, QString *errorMessage) { typedef QMap<CDBBreakPoint, int> BreakPointIndexMap; BreakPointIndexMap breakPointIndexMap; // convert BreakHandler's bps into a map of BreakPoint->BreakHandler->Index if (debugCDB) qDebug() << Q_FUNC_INFO; const int handlerCount = handler->size(); for (int i=0; i < handlerCount; ++i) breakPointIndexMap.insert(CDBBreakPoint(*handler->at(i)), i); // get number of engine breakpoints ULONG engineCount; if (!getBreakPointCount(debugControl, &engineCount, errorMessage)) return false; // Starting from end, check if engine breakpoints are still in handler. // If not->remove if (engineCount) { for (ULONG eb = engineCount - 1u; ; eb--) { // get engine breakpoint. IDebugBreakpoint2 *ibp = 0; HRESULT hr = debugControl->GetBreakpointByIndex2(eb, &ibp); if (FAILED(hr)) { *errorMessage = QString::fromLatin1("Cannot retrieve breakpoint %1: %2"). arg(eb).arg(msgComFailed("GetBreakpointByIndex2", hr)); return false; } // Ignore one shot break points set by "Step out" ULONG flags = 0; hr = ibp->GetFlags(&flags); if (!(flags & DEBUG_BREAKPOINT_ONE_SHOT)) { CDBBreakPoint engineBreakPoint; if (!engineBreakPoint.retrieve(ibp, errorMessage)) return false; // Still in handler? if (!breakPointIndexMap.contains(engineBreakPoint)) { if (debugCDB) qDebug() << " Removing" << engineBreakPoint; hr = debugControl->RemoveBreakpoint2(ibp); if (FAILED(hr)) { *errorMessage = QString::fromLatin1("Cannot remove breakpoint %1: %2"). arg(engineBreakPoint.expression(), msgComFailed("RemoveBreakpoint2", hr)); return false; } } // not in handler } // one shot if (!eb) break; } } // Add pending breakpoints const BreakPointIndexMap::const_iterator pcend = breakPointIndexMap.constEnd(); for (BreakPointIndexMap::const_iterator it = breakPointIndexMap.constBegin(); it != pcend; ++it) { const int index = it.value(); if (handler->at(index)->pending) { if (debugCDB) qDebug() << " Adding " << it.key(); if (it.key().add(debugControl, errorMessage)) { handler->at(index)->pending = false; } else { const QString msg = QString::fromLatin1("Failed to add breakpoint '%1': %2").arg(it.key().expression(), *errorMessage); qWarning("%s\n", qPrintable(msg)); } } } if (debugCDB > 1) { QList<CDBBreakPoint> bps; CDBBreakPoint::getBreakPoints(debugControl, &bps, errorMessage); qDebug().nospace() << "### Breakpoints in engine: " << bps; } return true; }