This patch adds Exceptions to the list of supported stop reasons for
Scripted Threads.
The main motivation for this is that breakpoints are triggered as a
special exception class on ARM platforms, so adding it as a stop reason
allows the ScriptedProcess to selected the ScriptedThread that stopped at
a breakpoint (or crashed :p).
rdar://
87430376
Differential Revision: https://reviews.llvm.org/D117074
Signed-off-by: Med Ismail Bennani <medismail.bennani@gmail.com>
void ScriptedProcess::RefreshStateAfterStop() {
// Let all threads recover from stopping and do any clean up based on the
// previous thread state (if any).
- m_thread_list.RefreshStateAfterStop();
}
bool ScriptedProcess::GetProcessInfo(ProcessInstanceInfo &info) {
StructuredData::DictionarySP dict_sp = GetInterface()->GetStopReason();
Status error;
+ if (!dict_sp)
+ return GetInterface()->ErrorWithMessage<bool>(
+ LLVM_PRETTY_FUNCTION, "Failed to get scripted thread stop info.", error,
+ LIBLLDB_LOG_THREAD);
+
lldb::StopInfoSP stop_info_sp;
lldb::StopReason stop_reason_type;
if (!dict_sp->GetValueForKeyAsDictionary("data", data_dict))
return GetInterface()->ErrorWithMessage<bool>(
LLVM_PRETTY_FUNCTION,
- "Couldn't find value for key 'type' in stop reason dictionary.", error,
+ "Couldn't find value for key 'data' in stop reason dictionary.", error,
LIBLLDB_LOG_THREAD);
switch (stop_reason_type) {
case lldb::eStopReasonNone:
- break;
+ return true;
case lldb::eStopReasonBreakpoint: {
lldb::break_id_t break_id;
data_dict->GetValueForKeyAsInteger("break_id", break_id,
stop_info_sp =
StopInfo::CreateStopReasonWithSignal(*this, signal, description.data());
} break;
+ case lldb::eStopReasonException: {
+ llvm::StringRef description;
+ data_dict->GetValueForKeyAsString("desc", description);
+
+ stop_info_sp =
+ StopInfo::CreateStopReasonWithException(*this, description.data());
+ } break;
default:
return GetInterface()->ErrorWithMessage<bool>(
LLVM_PRETTY_FUNCTION,
error, LIBLLDB_LOG_THREAD);
}
+ if (!stop_info_sp)
+ return false;
+
SetStopInfo(stop_info_sp);
return true;
}
self.assertEqual(process.GetProcessID(), 42)
self.assertEqual(process.GetNumThreads(), 3)
- thread = process.GetSelectedThread()
+ thread = process.GetThreadAtIndex(2)
self.assertTrue(thread, "Invalid thread.")
- self.assertEqual(thread.GetName(), "StackCoreScriptedThread.thread-0")
+ self.assertEqual(thread.GetName(), "StackCoreScriptedThread.thread-2")
- self.assertEqual(thread.GetNumFrames(), 2)
+ self.assertEqual(thread.GetNumFrames(), 6)
frame = thread.GetSelectedFrame()
self.assertTrue(frame, "Invalid frame.")
- # self.assertEqual(frame.GetFunctionName(), "bar")
- # self.assertEqual(int(frame.FindValue("i", lldb.eValueTypeVariableArgument).GetValue()), 42)
- # self.assertEqual(int(frame.FindValue("j", lldb.eValueTypeVariableLocal).GetValue()), 42 * 42)
+ self.assertIn("bar", frame.GetFunctionName())
+ self.assertEqual(int(frame.FindValue("i", lldb.eValueTypeVariableArgument).GetValue()), 42)
+ self.assertEqual(int(frame.FindValue("j", lldb.eValueTypeVariableLocal).GetValue()), 42 * 42)
return StackCoreScriptedThread.__name__ + ".thread-" + str(self.id)
def get_stop_reason(self) -> Dict[str, Any]:
- return { "type": lldb.eStopReasonSignal, "data": {
- "signal": signal.SIGINT
- } }
+ stop_reason = { "type": lldb.eStopReasonInvalid, "data": { }}
+
+ if self.corefile_thread and self.corefile_thread.IsValid:
+ stop_reason["type"] = self.corefile_thread.GetStopReason()
+
+ if self.corefile_thread.GetStopReasonDataCount() > 0:
+ if stop_reason["type"] == lldb.eStopReasonBreakpoint:
+ stop_reason["data"]["break_id"] = self.corefile_thread.GetStopReasonDataAtIndex(0)
+ stop_reason["data"]["break_loc_id"] = self.corefile_thread.GetStopReasonDataAtIndex(1)
+ elif stop_reason["type"] == lldb.eStopReasonSignal:
+ stop_reason["data"]["signal"] = signal.SIGINT
+ elif stop_reason["type"] == lldb.eStopReasonException:
+ stop_reason["data"]["desc"] = self.corefile_thread.GetStopDescription(100)
+
+ return stop_reason
def get_stackframes(self):
class ScriptedStackFrame: