@@ -2589,45 +2589,49 @@ lldb::addr_t SwiftLanguageRuntime::GetAsyncContext(RegisterContext *regctx) {
2589
2589
}
2590
2590
2591
2591
// / Functional wrapper to read a register as an address.
2592
- static std::optional <addr_t > ReadRegisterAsAddress (RegisterContext ®ctx,
2593
- RegisterKind regkind,
2594
- unsigned regnum) {
2592
+ static llvm::Expected <addr_t > ReadRegisterAsAddress (RegisterContext ®ctx,
2593
+ RegisterKind regkind,
2594
+ unsigned regnum) {
2595
2595
unsigned lldb_regnum =
2596
2596
regctx.ConvertRegisterKindToRegisterNumber (regkind, regnum);
2597
2597
auto reg = regctx.ReadRegisterAsUnsigned (lldb_regnum, LLDB_INVALID_ADDRESS);
2598
2598
if (reg != LLDB_INVALID_ADDRESS)
2599
2599
return reg;
2600
- return {};
2600
+ return llvm::createStringError (
2601
+ " SwiftLanguageRuntime: failed to read register from regctx" );
2601
2602
}
2602
2603
2603
2604
// / Functional wrapper to read a pointer from process memory at `addr +
2604
2605
// / offset`.
2605
- static std::optional <addr_t >
2606
- ReadPtrFromAddr (Process &process, std::optional <addr_t > addr, int offset = 0 ) {
2606
+ static llvm::Expected <addr_t >
2607
+ ReadPtrFromAddr (Process &process, llvm::Expected <addr_t > addr, int offset = 0 ) {
2607
2608
if (!addr)
2608
- return {} ;
2609
+ return addr ;
2609
2610
Status error;
2610
2611
addr_t ptr = process.ReadPointerFromMemory (*addr + offset, error);
2611
2612
if (ptr != LLDB_INVALID_ADDRESS)
2612
2613
return ptr;
2613
- return {};
2614
+ return llvm::createStringError (" SwiftLanguageRuntime: Failed to read ptr "
2615
+ " from memory address 0x%8.8" PRIx64,
2616
+ *addr + offset);
2614
2617
}
2615
2618
2616
2619
// / Computes the Canonical Frame Address (CFA) by converting the abstract
2617
2620
// / location of UnwindPlan::Row::FAValue into a concrete address. This is a
2618
2621
// / simplified version of the methods in RegisterContextUnwind, since plumbing
2619
2622
// / access to those here would be challenging.
2620
- static std::optional <addr_t > GetCFA (Process &process, RegisterContext ®ctx,
2621
- RegisterKind regkind,
2622
- UnwindPlan::Row::FAValue cfa_loc) {
2623
+ static llvm::Expected <addr_t > GetCFA (Process &process, RegisterContext ®ctx,
2624
+ RegisterKind regkind,
2625
+ UnwindPlan::Row::FAValue cfa_loc) {
2623
2626
using ValueType = UnwindPlan::Row::FAValue::ValueType;
2624
2627
switch (cfa_loc.GetValueType ()) {
2625
2628
case ValueType::isRegisterPlusOffset: {
2626
2629
unsigned regnum = cfa_loc.GetRegisterNumber ();
2627
- if (std::optional <addr_t > regvalue =
2630
+ if (llvm::Expected <addr_t > regvalue =
2628
2631
ReadRegisterAsAddress (regctx, regkind, regnum))
2629
2632
return *regvalue + cfa_loc.GetOffset ();
2630
- break ;
2633
+ else
2634
+ return regvalue;
2631
2635
}
2632
2636
case ValueType::isConstant:
2633
2637
case ValueType::isDWARFExpression:
@@ -2636,27 +2640,34 @@ static std::optional<addr_t> GetCFA(Process &process, RegisterContext ®ctx,
2636
2640
case ValueType::unspecified:
2637
2641
break ;
2638
2642
}
2639
- return {};
2643
+ return llvm::createStringError (
2644
+ " SwiftLanguageRuntime: Unsupported FA location type = %d" ,
2645
+ cfa_loc.GetValueType ());
2640
2646
}
2641
2647
2642
2648
// / Attempts to use UnwindPlans that inspect assembly to recover the entry value
2643
2649
// / of the async context register. This is a simplified version of the methods
2644
2650
// / in RegisterContextUnwind, since plumbing access to those here would be
2645
2651
// / challenging.
2646
- static std::optional <addr_t > ReadAsyncContextRegisterFromUnwind (
2652
+ static llvm::Expected <addr_t > ReadAsyncContextRegisterFromUnwind (
2647
2653
SymbolContext &sc, Process &process, Address pc, Address func_start_addr,
2648
2654
RegisterContext ®ctx, AsyncUnwindRegisterNumbers regnums) {
2649
2655
FuncUnwindersSP unwinders =
2650
2656
pc.GetModule ()->GetUnwindTable ().GetFuncUnwindersContainingAddress (pc,
2651
2657
sc);
2652
2658
if (!unwinders)
2653
- return {};
2659
+ return llvm::createStringError (" SwiftLanguageRuntime: Failed to find "
2660
+ " function unwinder at address 0x%8.8" PRIx64,
2661
+ pc.GetFileAddress ());
2654
2662
2655
2663
Target &target = process.GetTarget ();
2656
2664
UnwindPlanSP unwind_plan =
2657
2665
unwinders->GetUnwindPlanAtNonCallSite (target, regctx.GetThread ());
2658
2666
if (!unwind_plan)
2659
- return {};
2667
+ return llvm::createStringError (
2668
+ " SwiftLanguageRuntime: Failed to find non call site unwind plan at "
2669
+ " address 0x%8.8" PRIx64,
2670
+ pc.GetFileAddress ());
2660
2671
2661
2672
const RegisterKind unwind_regkind = unwind_plan->GetRegisterKind ();
2662
2673
UnwindPlan::RowSP row = unwind_plan->GetRowForFunctionOffset (
@@ -2668,7 +2679,8 @@ static std::optional<addr_t> ReadAsyncContextRegisterFromUnwind(
2668
2679
if (!regctx.ConvertBetweenRegisterKinds (
2669
2680
regnums.GetRegisterKind (), regnums.async_ctx_regnum , unwind_regkind,
2670
2681
async_reg_unwind_regdomain))
2671
- return {};
2682
+ return llvm::createStringError (
2683
+ " SwiftLanguageRuntime: Failed to convert register domains" );
2672
2684
2673
2685
// If the plan doesn't have information about the async register, we can use
2674
2686
// its current value, as this is a callee saved register.
@@ -2689,16 +2701,16 @@ static std::optional<addr_t> ReadAsyncContextRegisterFromUnwind(
2689
2701
return ReadRegisterAsAddress (regctx, unwind_regkind, regnum);
2690
2702
}
2691
2703
case RestoreType::atCFAPlusOffset: {
2692
- std::optional <addr_t > cfa =
2704
+ llvm::Expected <addr_t > cfa =
2693
2705
GetCFA (process, regctx, unwind_regkind, row->GetCFAValue ());
2694
- return ReadPtrFromAddr (process, cfa, regloc.GetOffset ());
2706
+ return ReadPtrFromAddr (process, std::move ( cfa) , regloc.GetOffset ());
2695
2707
}
2696
2708
case RestoreType::isCFAPlusOffset: {
2697
- std::optional <addr_t > cfa =
2698
- GetCFA (process, regctx, unwind_regkind, row->GetCFAValue ());
2699
- if (! cfa)
2700
- return {};
2701
- return *cfa + regloc. GetOffset () ;
2709
+ if (llvm::Expected <addr_t > cfa =
2710
+ GetCFA (process, regctx, unwind_regkind, row->GetCFAValue ()))
2711
+ return * cfa + regloc. GetOffset ();
2712
+ else
2713
+ return cfa ;
2702
2714
}
2703
2715
case RestoreType::isConstant:
2704
2716
return regloc.GetConstant ();
@@ -2708,9 +2720,10 @@ static std::optional<addr_t> ReadAsyncContextRegisterFromUnwind(
2708
2720
case RestoreType::isAFAPlusOffset:
2709
2721
case RestoreType::isDWARFExpression:
2710
2722
case RestoreType::atDWARFExpression:
2711
- return {} ;
2723
+ break ;
2712
2724
}
2713
- return {};
2725
+ return llvm::createStringError (
2726
+ " SwiftLanguageRuntime: Unsupported register location type = %d" , loctype);
2714
2727
}
2715
2728
2716
2729
// Examine the register state and detect the transition from a real
@@ -2721,6 +2734,11 @@ SwiftLanguageRuntime::GetRuntimeUnwindPlan(ProcessSP process_sp,
2721
2734
RegisterContext *regctx,
2722
2735
bool &behaves_like_zeroth_frame) {
2723
2736
LLDB_SCOPED_TIMER ();
2737
+ auto log_expected = [](llvm::Error error) {
2738
+ Log *log = GetLog (LLDBLog::Unwind);
2739
+ LLDB_LOG_ERROR (log, std::move (error), " SwiftLanguageRuntime: error {0}" );
2740
+ return UnwindPlanSP ();
2741
+ };
2724
2742
2725
2743
Target &target (process_sp->GetTarget ());
2726
2744
auto arch = target.GetArchitecture ();
@@ -2771,12 +2789,14 @@ SwiftLanguageRuntime::GetRuntimeUnwindPlan(ProcessSP process_sp,
2771
2789
bool indirect_context =
2772
2790
IsSwiftAsyncAwaitResumePartialFunctionSymbol (mangled_name.GetStringRef ());
2773
2791
2774
- std::optional <addr_t > async_reg = ReadAsyncContextRegisterFromUnwind (
2792
+ llvm::Expected <addr_t > async_reg = ReadAsyncContextRegisterFromUnwind (
2775
2793
sc, *process_sp, pc, func_start_addr, *regctx, *regnums);
2776
- std::optional<addr_t > async_ctx =
2777
- indirect_context ? ReadPtrFromAddr (*m_process, async_reg) : async_reg;
2778
- if (!async_reg || !async_ctx)
2779
- return UnwindPlanSP ();
2794
+ if (!async_reg)
2795
+ return log_expected (async_reg.takeError ());
2796
+ llvm::Expected<addr_t > async_ctx =
2797
+ indirect_context ? ReadPtrFromAddr (*m_process, *async_reg) : *async_reg;
2798
+ if (!async_ctx)
2799
+ return log_expected (async_ctx.takeError ());
2780
2800
2781
2801
UnwindPlan::RowSP row (new UnwindPlan::Row);
2782
2802
const int32_t ptr_size = 8 ;
0 commit comments