[lldb/Plugins] Enrich ScriptedThreads Stop Reasons with Exceptions

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>
This commit is contained in:
Med Ismail Bennani 2022-01-18 12:46:17 +01:00
parent d3e0f7e150
commit cfa55bfe78
4 changed files with 38 additions and 12 deletions

View File

@ -357,7 +357,6 @@ bool ScriptedProcess::DoUpdateThreadList(ThreadList &old_thread_list,
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) {

View File

@ -145,6 +145,11 @@ bool ScriptedThread::CalculateStopInfo() {
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;
@ -158,12 +163,12 @@ bool ScriptedThread::CalculateStopInfo() {
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,
@ -180,6 +185,13 @@ bool ScriptedThread::CalculateStopInfo() {
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,
@ -189,6 +201,9 @@ bool ScriptedThread::CalculateStopInfo() {
error, LIBLLDB_LOG_THREAD);
}
if (!stop_info_sp)
return false;
SetStopInfo(stop_info_sp);
return true;
}

View File

@ -188,13 +188,13 @@ class ScriptedProcesTestCase(TestBase):
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)

View File

@ -117,9 +117,21 @@ class StackCoreScriptedThread(ScriptedThread):
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: