180814287SRaphael Isemann //===-- InstrumentationRuntimeUBSan.cpp -----------------------------------===// 2623c3c4cSJonas Devlieghere // 3623c3c4cSJonas Devlieghere // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4623c3c4cSJonas Devlieghere // See https://llvm.org/LICENSE.txt for license information. 5623c3c4cSJonas Devlieghere // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6623c3c4cSJonas Devlieghere // 7623c3c4cSJonas Devlieghere //===----------------------------------------------------------------------===// 8623c3c4cSJonas Devlieghere 9623c3c4cSJonas Devlieghere #include "InstrumentationRuntimeUBSan.h" 10623c3c4cSJonas Devlieghere 11623c3c4cSJonas Devlieghere #include "Plugins/Process/Utility/HistoryThread.h" 12623c3c4cSJonas Devlieghere #include "lldb/Breakpoint/StoppointCallbackContext.h" 13623c3c4cSJonas Devlieghere #include "lldb/Core/Debugger.h" 14623c3c4cSJonas Devlieghere #include "lldb/Core/Module.h" 15623c3c4cSJonas Devlieghere #include "lldb/Core/PluginInterface.h" 16623c3c4cSJonas Devlieghere #include "lldb/Core/PluginManager.h" 17623c3c4cSJonas Devlieghere #include "lldb/Expression/UserExpression.h" 18f2d32ddcSAlex Langford #include "lldb/Host/StreamFile.h" 19623c3c4cSJonas Devlieghere #include "lldb/Interpreter/CommandReturnObject.h" 20623c3c4cSJonas Devlieghere #include "lldb/Symbol/Symbol.h" 21623c3c4cSJonas Devlieghere #include "lldb/Symbol/SymbolContext.h" 22623c3c4cSJonas Devlieghere #include "lldb/Symbol/Variable.h" 23623c3c4cSJonas Devlieghere #include "lldb/Symbol/VariableList.h" 24623c3c4cSJonas Devlieghere #include "lldb/Target/InstrumentationRuntimeStopInfo.h" 25623c3c4cSJonas Devlieghere #include "lldb/Target/SectionLoadList.h" 26623c3c4cSJonas Devlieghere #include "lldb/Target/StopInfo.h" 27623c3c4cSJonas Devlieghere #include "lldb/Target/Target.h" 28623c3c4cSJonas Devlieghere #include "lldb/Target/Thread.h" 29623c3c4cSJonas Devlieghere #include "lldb/Utility/RegularExpression.h" 30623c3c4cSJonas Devlieghere #include "lldb/Utility/Stream.h" 31b852fb1eSJonas Devlieghere #include "lldb/ValueObject/ValueObject.h" 3276e47d48SRaphael Isemann #include <cctype> 33623c3c4cSJonas Devlieghere 34623c3c4cSJonas Devlieghere #include <memory> 35623c3c4cSJonas Devlieghere 36623c3c4cSJonas Devlieghere using namespace lldb; 37623c3c4cSJonas Devlieghere using namespace lldb_private; 38623c3c4cSJonas Devlieghere 39bba9ba8dSJonas Devlieghere LLDB_PLUGIN_DEFINE(InstrumentationRuntimeUBSan) 40fbb4d1e4SJonas Devlieghere 41623c3c4cSJonas Devlieghere InstrumentationRuntimeUBSan::~InstrumentationRuntimeUBSan() { Deactivate(); } 42623c3c4cSJonas Devlieghere 43623c3c4cSJonas Devlieghere lldb::InstrumentationRuntimeSP 44623c3c4cSJonas Devlieghere InstrumentationRuntimeUBSan::CreateInstance(const lldb::ProcessSP &process_sp) { 45623c3c4cSJonas Devlieghere return InstrumentationRuntimeSP(new InstrumentationRuntimeUBSan(process_sp)); 46623c3c4cSJonas Devlieghere } 47623c3c4cSJonas Devlieghere 48623c3c4cSJonas Devlieghere void InstrumentationRuntimeUBSan::Initialize() { 49623c3c4cSJonas Devlieghere PluginManager::RegisterPlugin( 50623c3c4cSJonas Devlieghere GetPluginNameStatic(), 51623c3c4cSJonas Devlieghere "UndefinedBehaviorSanitizer instrumentation runtime plugin.", 52623c3c4cSJonas Devlieghere CreateInstance, GetTypeStatic); 53623c3c4cSJonas Devlieghere } 54623c3c4cSJonas Devlieghere 55623c3c4cSJonas Devlieghere void InstrumentationRuntimeUBSan::Terminate() { 56623c3c4cSJonas Devlieghere PluginManager::UnregisterPlugin(CreateInstance); 57623c3c4cSJonas Devlieghere } 58623c3c4cSJonas Devlieghere 59623c3c4cSJonas Devlieghere lldb::InstrumentationRuntimeType InstrumentationRuntimeUBSan::GetTypeStatic() { 60623c3c4cSJonas Devlieghere return eInstrumentationRuntimeTypeUndefinedBehaviorSanitizer; 61623c3c4cSJonas Devlieghere } 62623c3c4cSJonas Devlieghere 63623c3c4cSJonas Devlieghere static const char *ub_sanitizer_retrieve_report_data_prefix = R"( 64623c3c4cSJonas Devlieghere extern "C" { 65623c3c4cSJonas Devlieghere void 66623c3c4cSJonas Devlieghere __ubsan_get_current_report_data(const char **OutIssueKind, 67623c3c4cSJonas Devlieghere const char **OutMessage, const char **OutFilename, unsigned *OutLine, 68623c3c4cSJonas Devlieghere unsigned *OutCol, char **OutMemoryAddr); 69623c3c4cSJonas Devlieghere } 70adc5168dSMichael Buch )"; 71623c3c4cSJonas Devlieghere 72adc5168dSMichael Buch static const char *ub_sanitizer_retrieve_report_data_command = R"( 73adc5168dSMichael Buch struct { 74623c3c4cSJonas Devlieghere const char *issue_kind; 75623c3c4cSJonas Devlieghere const char *message; 76623c3c4cSJonas Devlieghere const char *filename; 77623c3c4cSJonas Devlieghere unsigned line; 78623c3c4cSJonas Devlieghere unsigned col; 79623c3c4cSJonas Devlieghere char *memory_addr; 80adc5168dSMichael Buch } t; 81623c3c4cSJonas Devlieghere 82623c3c4cSJonas Devlieghere __ubsan_get_current_report_data(&t.issue_kind, &t.message, &t.filename, &t.line, 83623c3c4cSJonas Devlieghere &t.col, &t.memory_addr); 84623c3c4cSJonas Devlieghere t; 85623c3c4cSJonas Devlieghere )"; 86623c3c4cSJonas Devlieghere 87623c3c4cSJonas Devlieghere static addr_t RetrieveUnsigned(ValueObjectSP return_value_sp, 88623c3c4cSJonas Devlieghere ProcessSP process_sp, 89623c3c4cSJonas Devlieghere const std::string &expression_path) { 9058e9cc13SMuhammad Omair Javaid return return_value_sp->GetValueForExpressionPath(expression_path.c_str()) 91623c3c4cSJonas Devlieghere ->GetValueAsUnsigned(0); 92623c3c4cSJonas Devlieghere } 93623c3c4cSJonas Devlieghere 94623c3c4cSJonas Devlieghere static std::string RetrieveString(ValueObjectSP return_value_sp, 95623c3c4cSJonas Devlieghere ProcessSP process_sp, 96623c3c4cSJonas Devlieghere const std::string &expression_path) { 97623c3c4cSJonas Devlieghere addr_t ptr = RetrieveUnsigned(return_value_sp, process_sp, expression_path); 98623c3c4cSJonas Devlieghere std::string str; 99623c3c4cSJonas Devlieghere Status error; 100623c3c4cSJonas Devlieghere process_sp->ReadCStringFromMemory(ptr, str, error); 101623c3c4cSJonas Devlieghere return str; 102623c3c4cSJonas Devlieghere } 103623c3c4cSJonas Devlieghere 104623c3c4cSJonas Devlieghere StructuredData::ObjectSP InstrumentationRuntimeUBSan::RetrieveReportData( 105623c3c4cSJonas Devlieghere ExecutionContextRef exe_ctx_ref) { 106623c3c4cSJonas Devlieghere ProcessSP process_sp = GetProcessSP(); 107623c3c4cSJonas Devlieghere if (!process_sp) 108623c3c4cSJonas Devlieghere return StructuredData::ObjectSP(); 109623c3c4cSJonas Devlieghere 110623c3c4cSJonas Devlieghere ThreadSP thread_sp = exe_ctx_ref.GetThreadSP(); 111076341d1SJim Ingham StackFrameSP frame_sp = 112076341d1SJim Ingham thread_sp->GetSelectedFrame(DoNoSelectMostRelevantFrame); 113623c3c4cSJonas Devlieghere ModuleSP runtime_module_sp = GetRuntimeModuleSP(); 114623c3c4cSJonas Devlieghere Target &target = process_sp->GetTarget(); 115623c3c4cSJonas Devlieghere 116623c3c4cSJonas Devlieghere if (!frame_sp) 117623c3c4cSJonas Devlieghere return StructuredData::ObjectSP(); 118623c3c4cSJonas Devlieghere 119623c3c4cSJonas Devlieghere StreamFileSP Stream = target.GetDebugger().GetOutputStreamSP(); 120623c3c4cSJonas Devlieghere 121623c3c4cSJonas Devlieghere EvaluateExpressionOptions options; 122623c3c4cSJonas Devlieghere options.SetUnwindOnError(true); 123623c3c4cSJonas Devlieghere options.SetTryAllThreads(true); 124623c3c4cSJonas Devlieghere options.SetStopOthers(true); 125623c3c4cSJonas Devlieghere options.SetIgnoreBreakpoints(true); 126623c3c4cSJonas Devlieghere options.SetTimeout(process_sp->GetUtilityExpressionTimeout()); 127623c3c4cSJonas Devlieghere options.SetPrefix(ub_sanitizer_retrieve_report_data_prefix); 128623c3c4cSJonas Devlieghere options.SetAutoApplyFixIts(false); 129623c3c4cSJonas Devlieghere options.SetLanguage(eLanguageTypeObjC_plus_plus); 130623c3c4cSJonas Devlieghere 131623c3c4cSJonas Devlieghere ValueObjectSP main_value; 132623c3c4cSJonas Devlieghere ExecutionContext exe_ctx; 133623c3c4cSJonas Devlieghere frame_sp->CalculateExecutionContext(exe_ctx); 134623c3c4cSJonas Devlieghere ExpressionResults result = UserExpression::Evaluate( 135623c3c4cSJonas Devlieghere exe_ctx, options, ub_sanitizer_retrieve_report_data_command, "", 136*6a8a4d51SAdrian Prantl main_value); 137623c3c4cSJonas Devlieghere if (result != eExpressionCompleted) { 138cae735f7SJonas Devlieghere StreamString ss; 139cae735f7SJonas Devlieghere ss << "cannot evaluate UndefinedBehaviorSanitizer expression:\n"; 140*6a8a4d51SAdrian Prantl if (main_value) 141*6a8a4d51SAdrian Prantl ss << main_value->GetError().AsCString(); 142cae735f7SJonas Devlieghere Debugger::ReportWarning(ss.GetString().str(), 143cae735f7SJonas Devlieghere process_sp->GetTarget().GetDebugger().GetID()); 144623c3c4cSJonas Devlieghere return StructuredData::ObjectSP(); 145623c3c4cSJonas Devlieghere } 146623c3c4cSJonas Devlieghere 147623c3c4cSJonas Devlieghere // Gather the PCs of the user frames in the backtrace. 148623c3c4cSJonas Devlieghere StructuredData::Array *trace = new StructuredData::Array(); 149623c3c4cSJonas Devlieghere auto trace_sp = StructuredData::ObjectSP(trace); 150623c3c4cSJonas Devlieghere for (unsigned I = 0; I < thread_sp->GetStackFrameCount(); ++I) { 15191e90cf6SFred Riss const Address FCA = thread_sp->GetStackFrameAtIndex(I) 15291e90cf6SFred Riss ->GetFrameCodeAddressForSymbolication(); 153623c3c4cSJonas Devlieghere if (FCA.GetModule() == runtime_module_sp) // Skip PCs from the runtime. 154623c3c4cSJonas Devlieghere continue; 155623c3c4cSJonas Devlieghere 156623c3c4cSJonas Devlieghere lldb::addr_t PC = FCA.GetLoadAddress(&target); 1571370a1cbSMed Ismail Bennani trace->AddIntegerItem(PC); 158623c3c4cSJonas Devlieghere } 159623c3c4cSJonas Devlieghere 160623c3c4cSJonas Devlieghere std::string IssueKind = RetrieveString(main_value, process_sp, ".issue_kind"); 161623c3c4cSJonas Devlieghere std::string ErrMessage = RetrieveString(main_value, process_sp, ".message"); 162623c3c4cSJonas Devlieghere std::string Filename = RetrieveString(main_value, process_sp, ".filename"); 163623c3c4cSJonas Devlieghere unsigned Line = RetrieveUnsigned(main_value, process_sp, ".line"); 164623c3c4cSJonas Devlieghere unsigned Col = RetrieveUnsigned(main_value, process_sp, ".col"); 165623c3c4cSJonas Devlieghere uintptr_t MemoryAddr = 166623c3c4cSJonas Devlieghere RetrieveUnsigned(main_value, process_sp, ".memory_addr"); 167623c3c4cSJonas Devlieghere 168623c3c4cSJonas Devlieghere auto *d = new StructuredData::Dictionary(); 169623c3c4cSJonas Devlieghere auto dict_sp = StructuredData::ObjectSP(d); 170623c3c4cSJonas Devlieghere d->AddStringItem("instrumentation_class", "UndefinedBehaviorSanitizer"); 171623c3c4cSJonas Devlieghere d->AddStringItem("description", IssueKind); 172623c3c4cSJonas Devlieghere d->AddStringItem("summary", ErrMessage); 173623c3c4cSJonas Devlieghere d->AddStringItem("filename", Filename); 174623c3c4cSJonas Devlieghere d->AddIntegerItem("line", Line); 175623c3c4cSJonas Devlieghere d->AddIntegerItem("col", Col); 176623c3c4cSJonas Devlieghere d->AddIntegerItem("memory_address", MemoryAddr); 177623c3c4cSJonas Devlieghere d->AddIntegerItem("tid", thread_sp->GetID()); 178623c3c4cSJonas Devlieghere d->AddItem("trace", trace_sp); 179623c3c4cSJonas Devlieghere return dict_sp; 180623c3c4cSJonas Devlieghere } 181623c3c4cSJonas Devlieghere 182623c3c4cSJonas Devlieghere static std::string GetStopReasonDescription(StructuredData::ObjectSP report) { 183623c3c4cSJonas Devlieghere llvm::StringRef stop_reason_description_ref; 184623c3c4cSJonas Devlieghere report->GetAsDictionary()->GetValueForKeyAsString( 185623c3c4cSJonas Devlieghere "description", stop_reason_description_ref); 186adcd0268SBenjamin Kramer std::string stop_reason_description = 187adcd0268SBenjamin Kramer std::string(stop_reason_description_ref); 188623c3c4cSJonas Devlieghere 189623c3c4cSJonas Devlieghere if (!stop_reason_description.size()) { 190623c3c4cSJonas Devlieghere stop_reason_description = "Undefined behavior detected"; 191623c3c4cSJonas Devlieghere } else { 192623c3c4cSJonas Devlieghere stop_reason_description[0] = toupper(stop_reason_description[0]); 193623c3c4cSJonas Devlieghere for (unsigned I = 1; I < stop_reason_description.size(); ++I) 194623c3c4cSJonas Devlieghere if (stop_reason_description[I] == '-') 195623c3c4cSJonas Devlieghere stop_reason_description[I] = ' '; 196623c3c4cSJonas Devlieghere } 197623c3c4cSJonas Devlieghere return stop_reason_description; 198623c3c4cSJonas Devlieghere } 199623c3c4cSJonas Devlieghere 200623c3c4cSJonas Devlieghere bool InstrumentationRuntimeUBSan::NotifyBreakpointHit( 201623c3c4cSJonas Devlieghere void *baton, StoppointCallbackContext *context, user_id_t break_id, 202623c3c4cSJonas Devlieghere user_id_t break_loc_id) { 203623c3c4cSJonas Devlieghere assert(baton && "null baton"); 204623c3c4cSJonas Devlieghere if (!baton) 205623c3c4cSJonas Devlieghere return false; ///< false => resume execution. 206623c3c4cSJonas Devlieghere 207623c3c4cSJonas Devlieghere InstrumentationRuntimeUBSan *const instance = 208623c3c4cSJonas Devlieghere static_cast<InstrumentationRuntimeUBSan *>(baton); 209623c3c4cSJonas Devlieghere 210623c3c4cSJonas Devlieghere ProcessSP process_sp = instance->GetProcessSP(); 211623c3c4cSJonas Devlieghere ThreadSP thread_sp = context->exe_ctx_ref.GetThreadSP(); 212623c3c4cSJonas Devlieghere if (!process_sp || !thread_sp || 213623c3c4cSJonas Devlieghere process_sp != context->exe_ctx_ref.GetProcessSP()) 214623c3c4cSJonas Devlieghere return false; 215623c3c4cSJonas Devlieghere 216623c3c4cSJonas Devlieghere if (process_sp->GetModIDRef().IsLastResumeForUserExpression()) 217623c3c4cSJonas Devlieghere return false; 218623c3c4cSJonas Devlieghere 219623c3c4cSJonas Devlieghere StructuredData::ObjectSP report = 220623c3c4cSJonas Devlieghere instance->RetrieveReportData(context->exe_ctx_ref); 221623c3c4cSJonas Devlieghere 222623c3c4cSJonas Devlieghere if (report) { 223623c3c4cSJonas Devlieghere thread_sp->SetStopInfo( 224623c3c4cSJonas Devlieghere InstrumentationRuntimeStopInfo::CreateStopReasonWithInstrumentationData( 225623c3c4cSJonas Devlieghere *thread_sp, GetStopReasonDescription(report), report)); 226623c3c4cSJonas Devlieghere return true; 227623c3c4cSJonas Devlieghere } 228623c3c4cSJonas Devlieghere 229623c3c4cSJonas Devlieghere return false; 230623c3c4cSJonas Devlieghere } 231623c3c4cSJonas Devlieghere 232623c3c4cSJonas Devlieghere const RegularExpression & 233623c3c4cSJonas Devlieghere InstrumentationRuntimeUBSan::GetPatternForRuntimeLibrary() { 234623c3c4cSJonas Devlieghere static RegularExpression regex(llvm::StringRef("libclang_rt\\.(a|t|ub)san_")); 235623c3c4cSJonas Devlieghere return regex; 236623c3c4cSJonas Devlieghere } 237623c3c4cSJonas Devlieghere 238623c3c4cSJonas Devlieghere bool InstrumentationRuntimeUBSan::CheckIfRuntimeIsValid( 239623c3c4cSJonas Devlieghere const lldb::ModuleSP module_sp) { 240623c3c4cSJonas Devlieghere static ConstString ubsan_test_sym("__ubsan_on_report"); 241623c3c4cSJonas Devlieghere const Symbol *symbol = module_sp->FindFirstSymbolWithNameAndType( 242623c3c4cSJonas Devlieghere ubsan_test_sym, lldb::eSymbolTypeAny); 243623c3c4cSJonas Devlieghere return symbol != nullptr; 244623c3c4cSJonas Devlieghere } 245623c3c4cSJonas Devlieghere 246623c3c4cSJonas Devlieghere // FIXME: Factor out all the logic we have in common with the {a,t}san plugins. 247623c3c4cSJonas Devlieghere void InstrumentationRuntimeUBSan::Activate() { 248623c3c4cSJonas Devlieghere if (IsActive()) 249623c3c4cSJonas Devlieghere return; 250623c3c4cSJonas Devlieghere 251623c3c4cSJonas Devlieghere ProcessSP process_sp = GetProcessSP(); 252623c3c4cSJonas Devlieghere if (!process_sp) 253623c3c4cSJonas Devlieghere return; 254623c3c4cSJonas Devlieghere 255623c3c4cSJonas Devlieghere ModuleSP runtime_module_sp = GetRuntimeModuleSP(); 256623c3c4cSJonas Devlieghere 257623c3c4cSJonas Devlieghere ConstString symbol_name("__ubsan_on_report"); 258623c3c4cSJonas Devlieghere const Symbol *symbol = runtime_module_sp->FindFirstSymbolWithNameAndType( 259623c3c4cSJonas Devlieghere symbol_name, eSymbolTypeCode); 260623c3c4cSJonas Devlieghere 261623c3c4cSJonas Devlieghere if (symbol == nullptr) 262623c3c4cSJonas Devlieghere return; 263623c3c4cSJonas Devlieghere 264623c3c4cSJonas Devlieghere if (!symbol->ValueIsAddress() || !symbol->GetAddressRef().IsValid()) 265623c3c4cSJonas Devlieghere return; 266623c3c4cSJonas Devlieghere 267623c3c4cSJonas Devlieghere Target &target = process_sp->GetTarget(); 268623c3c4cSJonas Devlieghere addr_t symbol_address = symbol->GetAddressRef().GetOpcodeLoadAddress(&target); 269623c3c4cSJonas Devlieghere 270623c3c4cSJonas Devlieghere if (symbol_address == LLDB_INVALID_ADDRESS) 271623c3c4cSJonas Devlieghere return; 272623c3c4cSJonas Devlieghere 273623c3c4cSJonas Devlieghere Breakpoint *breakpoint = 274623c3c4cSJonas Devlieghere process_sp->GetTarget() 275623c3c4cSJonas Devlieghere .CreateBreakpoint(symbol_address, /*internal=*/true, 276623c3c4cSJonas Devlieghere /*hardware=*/false) 277623c3c4cSJonas Devlieghere .get(); 278852a4bdbSJim Ingham const bool sync = false; 279623c3c4cSJonas Devlieghere breakpoint->SetCallback(InstrumentationRuntimeUBSan::NotifyBreakpointHit, 280852a4bdbSJim Ingham this, sync); 281623c3c4cSJonas Devlieghere breakpoint->SetBreakpointKind("undefined-behavior-sanitizer-report"); 282623c3c4cSJonas Devlieghere SetBreakpointID(breakpoint->GetID()); 283623c3c4cSJonas Devlieghere 284623c3c4cSJonas Devlieghere SetActive(true); 285623c3c4cSJonas Devlieghere } 286623c3c4cSJonas Devlieghere 287623c3c4cSJonas Devlieghere void InstrumentationRuntimeUBSan::Deactivate() { 288623c3c4cSJonas Devlieghere SetActive(false); 289623c3c4cSJonas Devlieghere 290623c3c4cSJonas Devlieghere auto BID = GetBreakpointID(); 291623c3c4cSJonas Devlieghere if (BID == LLDB_INVALID_BREAK_ID) 292623c3c4cSJonas Devlieghere return; 293623c3c4cSJonas Devlieghere 294623c3c4cSJonas Devlieghere if (ProcessSP process_sp = GetProcessSP()) { 295623c3c4cSJonas Devlieghere process_sp->GetTarget().RemoveBreakpointByID(BID); 296623c3c4cSJonas Devlieghere SetBreakpointID(LLDB_INVALID_BREAK_ID); 297623c3c4cSJonas Devlieghere } 298623c3c4cSJonas Devlieghere } 299623c3c4cSJonas Devlieghere 300623c3c4cSJonas Devlieghere lldb::ThreadCollectionSP 301623c3c4cSJonas Devlieghere InstrumentationRuntimeUBSan::GetBacktracesFromExtendedStopInfo( 302623c3c4cSJonas Devlieghere StructuredData::ObjectSP info) { 303623c3c4cSJonas Devlieghere ThreadCollectionSP threads; 304623c3c4cSJonas Devlieghere threads = std::make_shared<ThreadCollection>(); 305623c3c4cSJonas Devlieghere 306623c3c4cSJonas Devlieghere ProcessSP process_sp = GetProcessSP(); 307623c3c4cSJonas Devlieghere 308623c3c4cSJonas Devlieghere if (info->GetObjectForDotSeparatedPath("instrumentation_class") 309623c3c4cSJonas Devlieghere ->GetStringValue() != "UndefinedBehaviorSanitizer") 310623c3c4cSJonas Devlieghere return threads; 311623c3c4cSJonas Devlieghere 312623c3c4cSJonas Devlieghere std::vector<lldb::addr_t> PCs; 313623c3c4cSJonas Devlieghere auto trace = info->GetObjectForDotSeparatedPath("trace")->GetAsArray(); 314623c3c4cSJonas Devlieghere trace->ForEach([&PCs](StructuredData::Object *PC) -> bool { 3151370a1cbSMed Ismail Bennani PCs.push_back(PC->GetUnsignedIntegerValue()); 316623c3c4cSJonas Devlieghere return true; 317623c3c4cSJonas Devlieghere }); 318623c3c4cSJonas Devlieghere 319623c3c4cSJonas Devlieghere if (PCs.empty()) 320623c3c4cSJonas Devlieghere return threads; 321623c3c4cSJonas Devlieghere 322623c3c4cSJonas Devlieghere StructuredData::ObjectSP thread_id_obj = 323623c3c4cSJonas Devlieghere info->GetObjectForDotSeparatedPath("tid"); 324b804516dSDhruv Srivastava lldb::tid_t tid = 325b804516dSDhruv Srivastava thread_id_obj ? thread_id_obj->GetUnsignedIntegerValue() : 0; 326623c3c4cSJonas Devlieghere 32791e90cf6SFred Riss // We gather symbolication addresses above, so no need for HistoryThread to 32891e90cf6SFred Riss // try to infer the call addresses. 32991e90cf6SFred Riss bool pcs_are_call_addresses = true; 33091e90cf6SFred Riss ThreadSP new_thread_sp = std::make_shared<HistoryThread>( 33191e90cf6SFred Riss *process_sp, tid, PCs, pcs_are_call_addresses); 332623c3c4cSJonas Devlieghere std::string stop_reason_description = GetStopReasonDescription(info); 333623c3c4cSJonas Devlieghere new_thread_sp->SetName(stop_reason_description.c_str()); 334623c3c4cSJonas Devlieghere 335623c3c4cSJonas Devlieghere // Save this in the Process' ExtendedThreadList so a strong pointer retains 336623c3c4cSJonas Devlieghere // the object 337623c3c4cSJonas Devlieghere process_sp->GetExtendedThreadList().AddThread(new_thread_sp); 338623c3c4cSJonas Devlieghere threads->AddThread(new_thread_sp); 339623c3c4cSJonas Devlieghere 340623c3c4cSJonas Devlieghere return threads; 341623c3c4cSJonas Devlieghere } 342