@@ -419,6 +419,66 @@ CreateRunThroughTaskSwitchingTrampolines(Thread &thread,
419
419
return nullptr ;
420
420
}
421
421
422
+ // / Demangle `symbol_name` and extracts the text at the node described by
423
+ // / `node_path`, if it exists; otherwise, returns an empty string.
424
+ static std::string FindClassName (StringRef symbol_name,
425
+ llvm::ArrayRef<Node::Kind> node_path) {
426
+ swift::Demangle::Context ctx;
427
+ NodePointer demangled_node =
428
+ SwiftLanguageRuntime::DemangleSymbolAsNode (symbol_name, ctx);
429
+
430
+ if (!demangled_node) {
431
+ std::string symbol_name_str = symbol_name.str ();
432
+ LLDB_LOGF (GetLog (LLDBLog::Step),
433
+ " SwiftLanguageRuntime: failed to demangle %s." ,
434
+ symbol_name_str.c_str ());
435
+ return " " ;
436
+ }
437
+ NodePointer class_node = childAtPath (demangled_node, node_path);
438
+ if (!class_node || !class_node->hasText ()) {
439
+ std::string node_str = getNodeTreeAsString (demangled_node);
440
+ LLDB_LOGF (GetLog (LLDBLog::Step),
441
+ " SwiftLanguageRuntime: failed to extract name from "
442
+ " demangle node: %s" ,
443
+ node_str.c_str ());
444
+ return " " ;
445
+ }
446
+ return class_node->getText ().str ();
447
+ }
448
+
449
+ // / If sc_list is non-empty, returns a plan that runs to any of its addresses.
450
+ // / Otherwise, returns nullptr.
451
+ static ThreadPlanSP
452
+ CreateThreadPlanRunToSCInList (Thread &thread, const SymbolContextList &sc_list,
453
+ bool stop_others) {
454
+ std::vector<addr_t > load_addresses;
455
+ Target &target = thread.GetProcess ()->GetTarget ();
456
+ for (const SymbolContext &sc : sc_list) {
457
+ const Symbol *ctor_symbol = sc.symbol ;
458
+ if (ctor_symbol)
459
+ load_addresses.push_back (ctor_symbol->GetLoadAddress (&target));
460
+ }
461
+
462
+ if (load_addresses.empty ()) {
463
+ LLDB_LOG (GetLog (LLDBLog::Step),
464
+ " SwiftLanguageRuntime: empty sc_list found." );
465
+ return {};
466
+ }
467
+ return std::make_shared<ThreadPlanRunToAddress>(thread, load_addresses,
468
+ stop_others);
469
+ }
470
+
471
+ // / Search all modules for `target_func` and creates a RunToAddress plan
472
+ // / targeting all symbols found.
473
+ static ThreadPlanSP CreateRunToAddressPlan (StringRef target_func,
474
+ Thread &thread, bool stop_others) {
475
+ ModuleList modules = thread.GetProcess ()->GetTarget ().GetImages ();
476
+ SymbolContextList sc_list;
477
+ modules.FindFunctionSymbols (ConstString (target_func), eFunctionNameTypeFull,
478
+ sc_list);
479
+ return CreateThreadPlanRunToSCInList (thread, sc_list, stop_others);
480
+ }
481
+
422
482
static lldb::ThreadPlanSP GetStepThroughTrampolinePlan (Thread &thread,
423
483
bool stop_others) {
424
484
// Here are the trampolines we have at present.
@@ -475,19 +535,7 @@ static lldb::ThreadPlanSP GetStepThroughTrampolinePlan(Thread &thread,
475
535
log ->Printf (
476
536
" Stepped to thunk \" %s\" (kind: %s) stepping to target: \" %s\" ." ,
477
537
symbol_name, GetThunkKindName (thunk_kind), thunk_target.c_str ());
478
-
479
- ModuleList modules = thread.GetProcess ()->GetTarget ().GetImages ();
480
- SymbolContextList sc_list;
481
- modules.FindFunctionSymbols (ConstString (thunk_target),
482
- eFunctionNameTypeFull, sc_list);
483
- if (sc_list.GetSize () == 1 && sc_list[0 ].symbol ) {
484
- Symbol &thunk_symbol = *sc_list[0 ].symbol ;
485
- Address target_address = thunk_symbol.GetAddress ();
486
- if (target_address.IsValid ())
487
- return std::make_shared<ThreadPlanRunToAddress>(thread, target_address,
488
- stop_others);
489
- }
490
- return nullptr ;
538
+ return CreateRunToAddressPlan (thunk_target, thread, stop_others);
491
539
}
492
540
case ThunkAction::StepIntoConformance: {
493
541
// The TTW symbols encode the protocol conformance requirements
@@ -582,37 +630,19 @@ static lldb::ThreadPlanSP GetStepThroughTrampolinePlan(Thread &thread,
582
630
}
583
631
case ThunkAction::StepIntoAllocatingInit: {
584
632
LLDB_LOGF (log , " Stepping into allocating init: \" %s\" " , symbol_name);
585
- swift::Demangle::Context ctx;
586
- NodePointer demangled_node =
587
- SwiftLanguageRuntime::DemangleSymbolAsNode (symbol_name, ctx);
588
-
589
633
using Kind = Node::Kind;
590
- NodePointer class_node = childAtPath (
591
- demangled_node, {Kind::Allocator, Kind::Class, Kind::Identifier});
592
- if (!class_node || !class_node->hasText ()) {
593
- std::string node_str = getNodeTreeAsString (demangled_node);
594
- LLDB_LOGF (log ,
595
- " Failed to extract constructor name from demangle node: %s" ,
596
- node_str.c_str ());
634
+ static constexpr auto class_path = {Kind::Allocator, Kind::Class,
635
+ Kind::Identifier};
636
+ std::string class_name = FindClassName (symbol_name, class_path);
637
+ if (class_name.empty ())
597
638
return nullptr ;
598
- }
599
639
600
640
ModuleFunctionSearchOptions options{/* include_symbols*/ true ,
601
641
/* include_inlines*/ true };
602
- std::string ctor_name = llvm::formatv (" {0}.init" , class_node-> getText () );
642
+ std::string ctor_name = llvm::formatv (" {0}.init" , class_name );
603
643
SymbolContextList sc_list;
604
644
sc.module_sp ->FindFunctions (RegularExpression (ctor_name), options, sc_list);
605
- std::vector<addr_t > load_addresses;
606
- Target &target = thread.GetProcess ()->GetTarget ();
607
- for (const SymbolContext &ctor_sc : sc_list) {
608
- const Symbol *ctor_symbol = ctor_sc.symbol ;
609
- if (ctor_symbol)
610
- load_addresses.push_back (ctor_symbol->GetLoadAddress (&target));
611
- }
612
- if (load_addresses.empty ())
613
- return nullptr ;
614
- return std::make_shared<ThreadPlanRunToAddress>(thread, load_addresses,
615
- stop_others);
645
+ return CreateThreadPlanRunToSCInList (thread, sc_list, stop_others);
616
646
}
617
647
case ThunkAction::StepThrough: {
618
648
if (log )
0 commit comments