@@ -2589,45 +2589,49 @@ lldb::addr_t SwiftLanguageRuntime::GetAsyncContext(RegisterContext *regctx) {
25892589}
25902590
25912591// / 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) {
25952595 unsigned lldb_regnum =
25962596 regctx.ConvertRegisterKindToRegisterNumber (regkind, regnum);
25972597 auto reg = regctx.ReadRegisterAsUnsigned (lldb_regnum, LLDB_INVALID_ADDRESS);
25982598 if (reg != LLDB_INVALID_ADDRESS)
25992599 return reg;
2600- return {};
2600+ return llvm::createStringError (
2601+ " SwiftLanguageRuntime: failed to read register from regctx" );
26012602}
26022603
26032604// / Functional wrapper to read a pointer from process memory at `addr +
26042605// / 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 ) {
26072608 if (!addr)
2608- return {} ;
2609+ return addr ;
26092610 Status error;
26102611 addr_t ptr = process.ReadPointerFromMemory (*addr + offset, error);
26112612 if (ptr != LLDB_INVALID_ADDRESS)
26122613 return ptr;
2613- return {};
2614+ return llvm::createStringError (" SwiftLanguageRuntime: Failed to read ptr "
2615+ " from memory address 0x%8.8" PRIx64,
2616+ *addr + offset);
26142617}
26152618
26162619// / Computes the Canonical Frame Address (CFA) by converting the abstract
26172620// / location of UnwindPlan::Row::FAValue into a concrete address. This is a
26182621// / simplified version of the methods in RegisterContextUnwind, since plumbing
26192622// / 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) {
26232626 using ValueType = UnwindPlan::Row::FAValue::ValueType;
26242627 switch (cfa_loc.GetValueType ()) {
26252628 case ValueType::isRegisterPlusOffset: {
26262629 unsigned regnum = cfa_loc.GetRegisterNumber ();
2627- if (std::optional <addr_t > regvalue =
2630+ if (llvm::Expected <addr_t > regvalue =
26282631 ReadRegisterAsAddress (regctx, regkind, regnum))
26292632 return *regvalue + cfa_loc.GetOffset ();
2630- break ;
2633+ else
2634+ return regvalue;
26312635 }
26322636 case ValueType::isConstant:
26332637 case ValueType::isDWARFExpression:
@@ -2636,27 +2640,34 @@ static std::optional<addr_t> GetCFA(Process &process, RegisterContext ®ctx,
26362640 case ValueType::unspecified:
26372641 break ;
26382642 }
2639- return {};
2643+ return llvm::createStringError (
2644+ " SwiftLanguageRuntime: Unsupported FA location type = %d" ,
2645+ cfa_loc.GetValueType ());
26402646}
26412647
26422648// / Attempts to use UnwindPlans that inspect assembly to recover the entry value
26432649// / of the async context register. This is a simplified version of the methods
26442650// / in RegisterContextUnwind, since plumbing access to those here would be
26452651// / challenging.
2646- static std::optional <addr_t > ReadAsyncContextRegisterFromUnwind (
2652+ static llvm::Expected <addr_t > ReadAsyncContextRegisterFromUnwind (
26472653 SymbolContext &sc, Process &process, Address pc, Address func_start_addr,
26482654 RegisterContext ®ctx, AsyncUnwindRegisterNumbers regnums) {
26492655 FuncUnwindersSP unwinders =
26502656 pc.GetModule ()->GetUnwindTable ().GetFuncUnwindersContainingAddress (pc,
26512657 sc);
26522658 if (!unwinders)
2653- return {};
2659+ return llvm::createStringError (" SwiftLanguageRuntime: Failed to find "
2660+ " function unwinder at address 0x%8.8" PRIx64,
2661+ pc.GetFileAddress ());
26542662
26552663 Target &target = process.GetTarget ();
26562664 UnwindPlanSP unwind_plan =
26572665 unwinders->GetUnwindPlanAtNonCallSite (target, regctx.GetThread ());
26582666 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 ());
26602671
26612672 const RegisterKind unwind_regkind = unwind_plan->GetRegisterKind ();
26622673 UnwindPlan::RowSP row = unwind_plan->GetRowForFunctionOffset (
@@ -2668,7 +2679,8 @@ static std::optional<addr_t> ReadAsyncContextRegisterFromUnwind(
26682679 if (!regctx.ConvertBetweenRegisterKinds (
26692680 regnums.GetRegisterKind (), regnums.async_ctx_regnum , unwind_regkind,
26702681 async_reg_unwind_regdomain))
2671- return {};
2682+ return llvm::createStringError (
2683+ " SwiftLanguageRuntime: Failed to convert register domains" );
26722684
26732685 // If the plan doesn't have information about the async register, we can use
26742686 // its current value, as this is a callee saved register.
@@ -2689,16 +2701,16 @@ static std::optional<addr_t> ReadAsyncContextRegisterFromUnwind(
26892701 return ReadRegisterAsAddress (regctx, unwind_regkind, regnum);
26902702 }
26912703 case RestoreType::atCFAPlusOffset: {
2692- std::optional <addr_t > cfa =
2704+ llvm::Expected <addr_t > cfa =
26932705 GetCFA (process, regctx, unwind_regkind, row->GetCFAValue ());
2694- return ReadPtrFromAddr (process, cfa, regloc.GetOffset ());
2706+ return ReadPtrFromAddr (process, std::move ( cfa) , regloc.GetOffset ());
26952707 }
26962708 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 ;
27022714 }
27032715 case RestoreType::isConstant:
27042716 return regloc.GetConstant ();
@@ -2708,9 +2720,10 @@ static std::optional<addr_t> ReadAsyncContextRegisterFromUnwind(
27082720 case RestoreType::isAFAPlusOffset:
27092721 case RestoreType::isDWARFExpression:
27102722 case RestoreType::atDWARFExpression:
2711- return {} ;
2723+ break ;
27122724 }
2713- return {};
2725+ return llvm::createStringError (
2726+ " SwiftLanguageRuntime: Unsupported register location type = %d" , loctype);
27142727}
27152728
27162729// Examine the register state and detect the transition from a real
@@ -2721,6 +2734,11 @@ SwiftLanguageRuntime::GetRuntimeUnwindPlan(ProcessSP process_sp,
27212734 RegisterContext *regctx,
27222735 bool &behaves_like_zeroth_frame) {
27232736 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+ };
27242742
27252743 Target &target (process_sp->GetTarget ());
27262744 auto arch = target.GetArchitecture ();
@@ -2771,12 +2789,14 @@ SwiftLanguageRuntime::GetRuntimeUnwindPlan(ProcessSP process_sp,
27712789 bool indirect_context =
27722790 IsSwiftAsyncAwaitResumePartialFunctionSymbol (mangled_name.GetStringRef ());
27732791
2774- std::optional <addr_t > async_reg = ReadAsyncContextRegisterFromUnwind (
2792+ llvm::Expected <addr_t > async_reg = ReadAsyncContextRegisterFromUnwind (
27752793 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 ());
27802800
27812801 UnwindPlan::RowSP row (new UnwindPlan::Row);
27822802 const int32_t ptr_size = 8 ;
0 commit comments