1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-08 11:38:21 +02:00

Watch lock fixes, add watch pointee/pointer address

This commit is contained in:
Brian Fiete 2022-05-23 08:48:55 -07:00
parent d990e3afea
commit eccfabbad2
9 changed files with 214 additions and 55 deletions

View file

@ -4598,7 +4598,7 @@ namespace IDE
DebuggerUnpaused(); DebuggerUnpaused();
} }
else else if (sourceViewPanel != null)
{ {
var activePanel = sourceViewPanel.GetActivePanel(); var activePanel = sourceViewPanel.GetActivePanel();

View file

@ -44,6 +44,8 @@ namespace IDE.ui
public String mStackFrameId ~ delete _; public String mStackFrameId ~ delete _;
public bool mWantsStackFrameId; public bool mWantsStackFrameId;
public String mEvalStr ~ delete _; public String mEvalStr ~ delete _;
public String mAddrValueExpr ~ delete _;
public String mPointeeExpr ~ delete _;
public bool mCanEdit; public bool mCanEdit;
public String mEditInitialize ~ delete _; public String mEditInitialize ~ delete _;
public bool mHadValue; public bool mHadValue;
@ -2577,6 +2579,8 @@ namespace IDE.ui
watch.mLanguage = .NotSet; watch.mLanguage = .NotSet;
DeleteAndNullify!(watch.mEditInitialize); DeleteAndNullify!(watch.mEditInitialize);
DeleteAndNullify!(watch.mAction); DeleteAndNullify!(watch.mAction);
DeleteAndNullify!(watch.mAddrValueExpr);
DeleteAndNullify!(watch.mPointeeExpr);
watch.mCanEdit = false; watch.mCanEdit = false;
watch.mAction = null; watch.mAction = null;
@ -2764,6 +2768,14 @@ namespace IDE.ui
if (int32 stackIdx = int32.Parse(memberVals[1])) if (int32 stackIdx = int32.Parse(memberVals[1]))
watch.mCurStackIdx = stackIdx; watch.mCurStackIdx = stackIdx;
} }
else if (memberVals0 == ":addrValueExpr")
{
watch.mAddrValueExpr = new .(memberVals[1]);
}
else if (memberVals0 == ":pointeeExpr")
{
watch.mPointeeExpr = new .(memberVals[1]);
}
else else
watch.ParseCmd(memberVals); watch.ParseCmd(memberVals);
continue; continue;
@ -2808,7 +2820,7 @@ namespace IDE.ui
{ {
watch.mWantsStackFrameId = false; watch.mWantsStackFrameId = false;
watch.mStackFrameId = gApp.mDebugger.GetStackFrameId((watch.mCurStackIdx != -1) ? watch.mCurStackIdx : gApp.mDebugger.mActiveCallStackIdx, .. new .()); watch.mStackFrameId = gApp.mDebugger.GetStackFrameId((watch.mCurStackIdx != -1) ? watch.mCurStackIdx : gApp.mDebugger.mActiveCallStackIdx, .. new .());
if (gApp.mDebugger.mActiveCallStackIdx != watch.mCurStackIdx) if ((gApp.mDebugger.mActiveCallStackIdx != watch.mCurStackIdx) && (watch.mCurStackIdx != -1))
watch.mUsedLock = true; watch.mUsedLock = true;
} }
@ -3061,7 +3073,7 @@ namespace IDE.ui
return true; return true;
} }
protected static void WithSelectedWatchEntries(WatchListView listView, delegate void(WatchEntry) dlg) protected static void WithSelectedWatchEntries(WatchListView listView, delegate void(WatchEntry watchEntry) dlg)
{ {
listView.GetRoot().WithSelectedItems(scope (item) => listView.GetRoot().WithSelectedItems(scope (item) =>
{ {
@ -3082,28 +3094,12 @@ namespace IDE.ui
Menu menu = new Menu(); Menu menu = new Menu();
Menu anItem; Menu anItem;
/*if (listViewItem.mParent != mListView.GetRoot())
{
anItem = menu.AddItem("Add Watch");
}*/
if (listViewItem != null) if (listViewItem != null)
{ {
var clickedHoverItem = listViewItem.GetSubItem(0) as HoverWatch.HoverListViewItem; var clickedHoverItem = listViewItem.GetSubItem(0) as HoverWatch.HoverListViewItem;
var watchEntry = listViewItem.mWatchEntry; var watchEntry = listViewItem.mWatchEntry;
if (listViewItem.mParentItem != listView.GetRoot())
{
anItem = menu.AddItem("Add Watch");
anItem.mOnMenuItemSelected.Add(new (menu) =>
{
String compactEvalStr = scope String();
CompactChildExpression(listViewItem, compactEvalStr);
gApp.AddWatch(compactEvalStr);
});
}
AddDisplayTypeMenu("Default Display", menu, listViewItem.mWatchEntry.mResultType, null, false); AddDisplayTypeMenu("Default Display", menu, listViewItem.mWatchEntry.mResultType, null, false);
//Debug.WriteLine(String.Format("RefType: {0}", watchEntry.mReferenceId)); //Debug.WriteLine(String.Format("RefType: {0}", watchEntry.mReferenceId));
@ -3178,11 +3174,95 @@ namespace IDE.ui
} }
anItem = menu.AddItem("Add Watch"); anItem = menu.AddItem("Add Watch");
anItem.mOnMenuItemSelected.Add(new (menu) => var addWatchNew = anItem.AddItem("Duplicate");
addWatchNew.mOnMenuItemSelected.Add(new (menu) =>
{ {
IDEApp.sApp.AddWatch(watchEntry.mEvalStr); List<String> pendingEvalStrs = scope .();
listView.GetRoot().WithSelectedItems(scope (item) =>
{
var watchListViewItem = item as WatchListViewItem;
if (watchListViewItem.mWatchEntry != null)
{
if (watchListViewItem.mParentItem != listView.GetRoot())
{
String compactEvalStr = new String();
CompactChildExpression(watchListViewItem, compactEvalStr);
pendingEvalStrs.Add(compactEvalStr);
}
else
{
pendingEvalStrs.Add(new .(watchEntry.mEvalStr));
}
}
});
for (var str in pendingEvalStrs)
{
gApp.AddWatch(str);
delete str;
}
}); });
String pointeeExpr = null;
String addrValueExpr = null;
WithSelectedWatchEntries(listView, scope [&] (selectedWatchEntry) =>
{
if (selectedWatchEntry.mPointeeExpr != null)
{
if (pointeeExpr != null)
pointeeExpr = "";
else
pointeeExpr = selectedWatchEntry.mPointeeExpr;
}
if (selectedWatchEntry.mAddrValueExpr != null)
{
if (addrValueExpr != null)
addrValueExpr = "";
else
addrValueExpr = selectedWatchEntry.mAddrValueExpr;
}
});
if (pointeeExpr != null)
{
var addWatchPointee = anItem.AddItem(scope $"Pointee Address {pointeeExpr}");
addWatchPointee.mOnMenuItemSelected.Add(new (menu) =>
{
WithSelectedWatchEntries(listView, scope (selectedWatchEntry) =>
{
if (selectedWatchEntry.mPointeeExpr != null)
gApp.AddWatch(selectedWatchEntry.mPointeeExpr);
});
});
if (addrValueExpr != null)
{
var addWatchPointer = anItem.AddItem(scope $"Pointer Address {addrValueExpr}");
addWatchPointer.mOnMenuItemSelected.Add(new (menu) =>
{
WithSelectedWatchEntries(listView, scope (selectedWatchEntry) =>
{
if (selectedWatchEntry.mAddrValueExpr != null)
gApp.AddWatch(selectedWatchEntry.mAddrValueExpr);
});
});
}
}
else if (addrValueExpr != null)
{
var addValuePointer = anItem.AddItem(scope $"Value Address {addrValueExpr}");
addValuePointer.mOnMenuItemSelected.Add(new (menu) =>
{
WithSelectedWatchEntries(listView, scope (selectedWatchEntry) =>
{
if (selectedWatchEntry.mAddrValueExpr != null)
gApp.AddWatch(selectedWatchEntry.mAddrValueExpr);
});
});
}
if (!watchEntry.IsConstant) if (!watchEntry.IsConstant)
{ {
anItem = menu.AddItem("Break When Value Changes"); anItem = menu.AddItem("Break When Value Changes");
@ -3192,10 +3272,19 @@ namespace IDE.ui
{ {
String evalStr = scope String(); String evalStr = scope String();
CompactChildExpression(listViewItem, evalStr); CompactChildExpression(listViewItem, evalStr);
if (evalStr.StartsWith("*"))
evalStr.Remove(0, 1); int valStart = 0;
if (evalStr.StartsWith('{'))
{
int endPos = evalStr.IndexOf('}');
valStart = endPos + 1;
while ((valStart < evalStr.Length) && (evalStr[valStart].IsWhiteSpace))
valStart++;
}
if ((valStart < evalStr.Length) && (evalStr[valStart] == '*'))
evalStr.Remove(valStart, 1);
else else
evalStr.Insert(0, "&"); evalStr.Insert(valStart, "&");
gApp.mBreakpointPanel.CreateMemoryBreakpoint(evalStr); gApp.mBreakpointPanel.CreateMemoryBreakpoint(evalStr);
gApp.MarkDirty(); gApp.MarkDirty();
}); });

View file

@ -4137,7 +4137,7 @@ void CeDebugger::HandleCustomExpandedItems(String& retVal, DebugVisualizerEntry*
if (!valueType->IsPointer()) if (!valueType->IsPointer())
ptrType = ceModule->CreatePointerType(valueType); ptrType = ceModule->CreatePointerType(valueType);
evalStr = StrFormat("(comptype(%d)", ptrType->mTypeId); evalStr = StrFormat("(comptype(%d)", ptrType->mTypeId);
evalStr += ")0x{1}";; evalStr += ")0x{1}";
} }
else else
{ {

View file

@ -970,10 +970,20 @@ DbgType* DbgExprEvaluator::ResolveTypeRef(BfTypeReference* typeRef)
String name = typeRef->ToString(); String name = typeRef->ToString();
if (name.StartsWith("_T_")) if (name.StartsWith("_T_"))
{ {
int idx = atoi(name.c_str() + 3); auto dbgModule = mDbgModule;
if ((idx >= 0) && (idx < (int)mDbgModule->mTypes.size()))
return mDbgModule->mTypes[idx]; char* endPtr = NULL;
int typeIdx = strtol(name.c_str() + 3, &endPtr, 10);
if ((endPtr != NULL) && (*endPtr == '_'))
{
int moduleIdx = typeIdx;
typeIdx = atoi(endPtr + 1);
mDebugTarget->mDbgModuleMap.TryGetValue(moduleIdx, &dbgModule);
}
if ((dbgModule != NULL) && (typeIdx >= 0) && (typeIdx < (int)dbgModule->mTypes.size()))
return dbgModule->mTypes[typeIdx];
} }
auto entry = mDbgModule->mTypeMap.Find(name.c_str(), GetLanguage()); auto entry = mDbgModule->mTypeMap.Find(name.c_str(), GetLanguage());
@ -1023,23 +1033,33 @@ DbgType* DbgExprEvaluator::ResolveTypeRef(BfAstNode* typeRef, BfAstNode** parent
for (int i = 3; i < (int)name.length(); i++) for (int i = 3; i < (int)name.length(); i++)
{ {
char c = name[i]; char c = name[i];
if ((c < '0') || (c > '9')) if (((c < '0') || (c > '9')) && (c != '_'))
{ {
endIdx = i; endIdx = i;
break; break;
} }
} }
int idx = atoi(name.c_str() + 3); auto dbgModule = mDbgModule;
if ((idx >= 0) && (idx < (int)mDbgModule->mTypes.size()))
char* endPtr = NULL;
int typeIdx = strtol(name.c_str() + 3, &endPtr, 10);
if ((endPtr != NULL) && (*endPtr == '_'))
{
int moduleIdx = typeIdx;
typeIdx = atoi(endPtr + 1);
mDebugTarget->mDbgModuleMap.TryGetValue(moduleIdx, &dbgModule);
}
if ((dbgModule != NULL) && (typeIdx >= 0) && (typeIdx < (int)dbgModule->mTypes.size()))
{ {
if ((mExplicitThisExpr != NULL) && (parentChildRef != NULL)) if ((mExplicitThisExpr != NULL) && (parentChildRef != NULL))
mDeferredInsertExplicitThisVector.push_back(NodeReplaceRecord(typeRef, parentChildRef, true)); mDeferredInsertExplicitThisVector.push_back(NodeReplaceRecord(typeRef, parentChildRef, true));
DbgType* dbgType = mDbgModule->mTypes[idx]; DbgType* dbgType = dbgModule->mTypes[typeIdx];
for (int i = endIdx; i < (int)name.length(); i++) for (int i = endIdx; i < (int)name.length(); i++)
{ {
if (name[i] == '*') if (name[i] == '*')
dbgType = mDbgModule->GetPointerType(dbgType); dbgType = dbgModule->GetPointerType(dbgType);
} }
return dbgType; return dbgType;
} }

View file

@ -1547,7 +1547,7 @@ DbgType* DbgType::RemoveModifiers(bool* hadRef)
String DbgType::ToStringRaw(DbgLanguage language) String DbgType::ToStringRaw(DbgLanguage language)
{ {
if (mTypeIdx != -1) if (mTypeIdx != -1)
return StrFormat("_T_%d", mTypeIdx); return StrFormat("_T_%d_%d", mCompileUnit->mDbgModule->mId, mTypeIdx);
return ToString(language); return ToString(language);
} }

View file

@ -33,6 +33,7 @@ DebugTarget::DebugTarget(WinDebugger* debugger)
mLastHotHeapCleanIdx = 0; mLastHotHeapCleanIdx = 0;
mIsEmpty = false; mIsEmpty = false;
mWasLocallyBuilt = false; mWasLocallyBuilt = false;
mCurModuleId = 0;
/*dbgType = new DbgType(); /*dbgType = new DbgType();
dbgType->mName = "int"; dbgType->mName = "int";
@ -252,9 +253,12 @@ String DebugTarget::UnloadDyn(addr_target imageBase)
if (mTargetBinary == dwarf) if (mTargetBinary == dwarf)
mTargetBinary = NULL; mTargetBinary = NULL;
mDbgModules.RemoveAt(i);
bool success = mDbgModuleMap.Remove(dwarf->mId);
BF_ASSERT_REL(success);
delete dwarf; delete dwarf;
mDbgModules.erase(mDbgModules.begin() + i);
return filePath; return filePath;
} }
} }
@ -292,9 +296,11 @@ void DebugTarget::CleanupHotHeap()
{ {
DbgModule* dbgModule = mDbgModules[dwarfIdx]; DbgModule* dbgModule = mDbgModules[dwarfIdx];
if (dbgModule->mDeleting) if (dbgModule->mDeleting)
{ {
mDbgModules.RemoveAt(dwarfIdx);
bool success = mDbgModuleMap.Remove(dbgModule->mId);
BF_ASSERT_REL(success);
delete dbgModule; delete dbgModule;
mDbgModules.erase(mDbgModules.begin() + dwarfIdx);
dwarfIdx--; dwarfIdx--;
} }
} }
@ -906,10 +912,11 @@ void DebugTarget::GetCompilerSettings()
} }
void DebugTarget::AddDbgModule(DbgModule* dbgModule) void DebugTarget::AddDbgModule(DbgModule* dbgModule)
{ {
static int id = 0; dbgModule->mId = ++mCurModuleId;
dbgModule->mId = ++id;
mDbgModules.Add(dbgModule); mDbgModules.Add(dbgModule);
bool success = mDbgModuleMap.TryAdd(dbgModule->mId, dbgModule);
BF_ASSERT_REL(success);
} }
#if 1 #if 1

View file

@ -38,7 +38,8 @@ public:
String mTargetPath; String mTargetPath;
DbgModule* mLaunchBinary; DbgModule* mLaunchBinary;
DbgModule* mTargetBinary; DbgModule* mTargetBinary;
Array<DbgModule*> mDbgModules; Array<DbgModule*> mDbgModules;
Dictionary<int, DbgModule*> mDbgModuleMap;
HashSet<DbgSrcFile*> mPendingSrcFileRehup; // Waiting to remove old/invalid line info HashSet<DbgSrcFile*> mPendingSrcFileRehup; // Waiting to remove old/invalid line info
BumpAllocator mAlloc; BumpAllocator mAlloc;
@ -51,6 +52,7 @@ public:
bool mBfHasLargeCollections; bool mBfHasLargeCollections;
int mBfObjectVDataIntefaceSlotCount; int mBfObjectVDataIntefaceSlotCount;
int mBfObjectSize; int mBfObjectSize;
int mCurModuleId;
Array<DwCommonFrameDescriptor*> mCommonFrameDescriptors; Array<DwCommonFrameDescriptor*> mCommonFrameDescriptors;
std::map<addr_target, DwFrameDescriptor> mDwFrameDescriptorMap; std::map<addr_target, DwFrameDescriptor> mDwFrameDescriptorMap;

View file

@ -389,6 +389,8 @@ DbgPendingExpr::DbgPendingExpr()
mIdleTicks = 0; mIdleTicks = 0;
mExplitType = NULL; mExplitType = NULL;
mExpressionFlags = DwEvalExpressionFlag_None; mExpressionFlags = DwEvalExpressionFlag_None;
mUsedSpecifiedLock = false;
mStackIdxOverride = -1;
} }
DbgPendingExpr::~DbgPendingExpr() DbgPendingExpr::~DbgPendingExpr()
@ -8727,7 +8729,7 @@ void WinDebugger::HandleCustomExpandedItems(String& retVal, DbgCompileUnit* dbgC
} }
} }
else if (debugVis->mCollectionType == DebugVisualizerEntry::CollectionType_Dictionary) else if (debugVis->mCollectionType == DebugVisualizerEntry::CollectionType_Dictionary)
{ {
DbgTypedValue sizeValue = EvaluateInContext(dbgCompileUnit, useTypedValue, debugVisualizers->DoStringReplace(debugVis->mSize, dbgVisWildcardCaptures), &formatInfo); DbgTypedValue sizeValue = EvaluateInContext(dbgCompileUnit, useTypedValue, debugVisualizers->DoStringReplace(debugVis->mSize, dbgVisWildcardCaptures), &formatInfo);
DbgTypedValue entriesPtrValue = EvaluateInContext(dbgCompileUnit, useTypedValue, debugVisualizers->DoStringReplace(debugVis->mEntries, dbgVisWildcardCaptures), &formatInfo); DbgTypedValue entriesPtrValue = EvaluateInContext(dbgCompileUnit, useTypedValue, debugVisualizers->DoStringReplace(debugVis->mEntries, dbgVisWildcardCaptures), &formatInfo);
@ -9461,6 +9463,25 @@ String WinDebugger::EvaluateContinue(DbgPendingExpr* pendingExpr, BfPassInstance
if (exprResult.mIsReadOnly) if (exprResult.mIsReadOnly)
canEdit = false; canEdit = false;
const char* langStr = (pendingExpr->mFormatInfo.mLanguage == DbgLanguage_Beef) ? "@Beef:" : "@C:";
if (exprResult.mSrcAddress != 0)
{
val += StrFormat("\n:addrValueExpr\t%s(%s*)", langStr, exprResult.mType->ToString(pendingExpr->mFormatInfo.mLanguage).c_str());
val += EncodeDataPtr(exprResult.mSrcAddress, true);
}
if (exprResult.mType->IsPointerOrRef())
{
auto underlyingType = exprResult.mType->mTypeParam;
if (underlyingType != NULL)
{
val += StrFormat("\n:pointeeExpr\t%s(%s%s)", langStr, underlyingType->ToString(pendingExpr->mFormatInfo.mLanguage).c_str(),
underlyingType->IsBfObject() ? "" : "*");
val += EncodeDataPtr(exprResult.mPtr, true);
}
}
if (val[0] == '!') if (val[0] == '!')
{ {
// Already has an error embedded, can't edit // Already has an error embedded, can't edit
@ -9504,6 +9525,15 @@ String WinDebugger::EvaluateContinue(DbgPendingExpr* pendingExpr, BfPassInstance
if (pendingExpr->mFormatInfo.mRawString) if (pendingExpr->mFormatInfo.mRawString)
return ""; return "";
if (val[0] != '!')
{
if (pendingExpr->mUsedSpecifiedLock)
val += "\n:usedLock";
if (pendingExpr->mStackIdxOverride != -1)
val += StrFormat("\n:stackIdx\t%d", pendingExpr->mStackIdxOverride);
}
if (pendingExpr->mCursorPos != -1) if (pendingExpr->mCursorPos != -1)
val += GetAutocompleteOutput(autoComplete); val += GetAutocompleteOutput(autoComplete);
@ -9642,8 +9672,10 @@ String WinDebugger::Evaluate(const StringImpl& expr, DwFormatInfo formatInfo, in
if (terminatedExpr.StartsWith('{')) if (terminatedExpr.StartsWith('{'))
{ {
String locString;
int closeIdx = terminatedExpr.IndexOf('}'); int closeIdx = terminatedExpr.IndexOf('}');
String locString = terminatedExpr.Substring(1, closeIdx - 1); if (closeIdx != -1)
locString = terminatedExpr.Substring(1, closeIdx - 1);
for (int i = 0; i <= closeIdx; i++) for (int i = 0; i <= closeIdx; i++)
terminatedExpr[i] = ' '; terminatedExpr[i] = ' ';
@ -9728,7 +9760,7 @@ String WinDebugger::Evaluate(const StringImpl& expr, DwFormatInfo formatInfo, in
foundLockMatch = true; foundLockMatch = true;
} }
} }
} }
} }
} }
} }
@ -9995,6 +10027,8 @@ String WinDebugger::Evaluate(const StringImpl& expr, DwFormatInfo formatInfo, in
return result; return result;
} }
pendingExpr->mUsedSpecifiedLock = usedSpecifiedLock;
pendingExpr->mStackIdxOverride = stackIdxOverride;
pendingExpr->mExplitType = explicitType; pendingExpr->mExplitType = explicitType;
pendingExpr->mFormatInfo = formatInfo; pendingExpr->mFormatInfo = formatInfo;
String result = EvaluateContinue(pendingExpr, bfPassInstance); String result = EvaluateContinue(pendingExpr, bfPassInstance);
@ -10012,13 +10046,7 @@ String WinDebugger::Evaluate(const StringImpl& expr, DwFormatInfo formatInfo, in
mActiveThread->mBreakpointAddressContinuing = 0; mActiveThread->mBreakpointAddressContinuing = 0;
} }
else else
delete pendingExpr; delete pendingExpr;
if ((!formatInfo.mRawString) && (usedSpecifiedLock))
result += "\n:usedLock";
if ((!formatInfo.mRawString) && (stackIdxOverride != -1))
result += StrFormat("\n:stackIdx\t%d", stackIdxOverride);
return result; return result;
} }
@ -10579,8 +10607,17 @@ String WinDebugger::CompactChildExpression(const StringImpl& expr, const StringI
parser.SetSource(terminatedExpr.c_str(), terminatedExpr.length()); parser.SetSource(terminatedExpr.c_str(), terminatedExpr.length());
parser.Parse(&bfPassInstance); parser.Parse(&bfPassInstance);
BfParser parentParser(mBfSystem);
auto terminatedParentExpr = parentExpr + ";"; auto terminatedParentExpr = parentExpr + ";";
String parentPrefix;
if (terminatedParentExpr.StartsWith('{'))
{
int prefixEnd = terminatedParentExpr.IndexOf('}');
parentPrefix = terminatedParentExpr.Substring(0, prefixEnd + 1);
terminatedParentExpr.Remove(0, prefixEnd + 1);
}
BfParser parentParser(mBfSystem);
parentParser.mCompatMode = language != DbgLanguage_Beef; parentParser.mCompatMode = language != DbgLanguage_Beef;
parentParser.SetSource(terminatedParentExpr.c_str(), terminatedParentExpr.length()); parentParser.SetSource(terminatedParentExpr.c_str(), terminatedParentExpr.length());
parentParser.Parse(&bfPassInstance); parentParser.Parse(&bfPassInstance);
@ -10633,7 +10670,9 @@ String WinDebugger::CompactChildExpression(const StringImpl& expr, const StringI
printer.mIgnoreTrivia = true; printer.mIgnoreTrivia = true;
printer.mReformatting = true; printer.mReformatting = true;
printer.VisitChild(headNode); printer.VisitChild(headNode);
auto result = printer.mOutString; String result;
result += parentPrefix;
result += printer.mOutString;
if (formatInfo.mNoVisualizers) if (formatInfo.mNoVisualizers)
result += ", nv"; result += ", nv";
if (formatInfo.mNoMembers) if (formatInfo.mNoMembers)

View file

@ -288,6 +288,8 @@ public:
Array<DbgCallResult> mCallResults; Array<DbgCallResult> mCallResults;
int mIdleTicks; int mIdleTicks;
String mException; String mException;
bool mUsedSpecifiedLock;
int mStackIdxOverride;
DbgPendingExpr(); DbgPendingExpr();
~DbgPendingExpr(); ~DbgPendingExpr();