================ @@ -480,3 +481,111 @@ CompilerType PlatformLinux::GetSiginfoType(const llvm::Triple &triple) { ast->CompleteTagDeclarationDefinition(siginfo_type); return siginfo_type; } + +static std::string GetDescriptionFromSiginfo(lldb::ValueObjectSP siginfo_sp) { + if (!siginfo_sp) + return ""; + + lldb_private::LinuxSignals linux_signals; + int code = siginfo_sp->GetChildMemberWithName("si_code")->GetValueAsSigned(0); + int signo = + siginfo_sp->GetChildMemberWithName("si_signo")->GetValueAsSigned(-1); + // si_code = 0 is SI_NOINFO, we just want the description with nothing + // important + if (code == 0) + return linux_signals.GetSignalDescription(signo, code); + + auto sifields = siginfo_sp->GetChildMemberWithName("_sifields"); + if (!sifields) + return linux_signals.GetSignalDescription(signo, code); + + // declare everything that we can populate later. + std::optional<lldb::addr_t> addr; + std::optional<lldb::addr_t> upper; + std::optional<lldb::addr_t> lower; + std::optional<uint32_t> pid; + std::optional<uint32_t> uid; + + // The negative si_codes are special and mean this signal was sent from user + // space not the kernel. These take precedence because they break some of the + // invariants around kernel sent signals. Such as SIGSEGV won't have an + // address. + if (code < 0) { + auto sikill = sifields->GetChildMemberWithName("_kill"); + if (sikill) { + auto pid_sp = sikill->GetChildMemberWithName("si_pid"); + if (pid_sp) + pid = pid_sp->GetValueAsUnsigned(-1); + auto uid_sp = sikill->GetChildMemberWithName("si_uid"); + if (uid_sp) + uid = uid_sp->GetValueAsUnsigned(-1); + } + } else { + + switch (signo) { + case SIGILL: + case SIGFPE: + case SIGBUS: { + auto sigfault = sifields->GetChildMemberWithName("_sigfault"); + if (!sigfault) + break; + + auto addr_sp = sigfault->GetChildMemberWithName("si_addr"); + if (addr_sp) + addr = addr_sp->GetValueAsUnsigned(-1); + break; + } + case SIGSEGV: { + auto sigfault = sifields->GetChildMemberWithName("_sigfault"); + if (!sigfault) + break; + + auto addr_sp = sigfault->GetChildMemberWithName("si_addr"); + if (addr_sp) + addr = addr_sp->GetValueAsUnsigned(-1); + + auto bounds_sp = sigfault->GetChildMemberWithName("_bounds"); + if (!bounds_sp) + break; + + auto addr_bnds_sp = bounds_sp->GetChildMemberWithName("_addr_bnd"); + if (!addr_bnds_sp) + break; + + auto lower_sp = addr_bnds_sp->GetChildMemberWithName("_lower"); + if (lower_sp) + lower = lower_sp->GetValueAsUnsigned(-1); + + auto upper_sp = addr_bnds_sp->GetChildMemberWithName("_upper"); + if (upper_sp) + upper = upper_sp->GetValueAsUnsigned(-1); + + break; + } + default: + break; + } + } + + return linux_signals.GetSignalDescription(signo, code, addr, lower, upper, + uid, pid); +} + +lldb::StopInfoSP PlatformLinux::GetStopInfoFromSiginfo(Thread &thread) { + ValueObjectSP siginfo_sp = thread.GetSiginfoValue(); + if (!siginfo_sp) + return {}; + auto signo_sp = siginfo_sp->GetChildMemberWithName("si_signo"); + auto sicode_sp = siginfo_sp->GetChildMemberWithName("si_code"); + if (!signo_sp || !sicode_sp) + return {}; + + std::string siginfo_description = GetDescriptionFromSiginfo(siginfo_sp); + if (siginfo_description.empty()) + return StopInfo::CreateStopReasonWithSignal( + thread, signo_sp->GetValueAsUnsigned(-1)); + else ---------------- labath wrote:
https://llvm.org/docs/CodingStandards.html#don-t-use-else-after-a-return https://github.com/llvm/llvm-project/pull/140150 _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits