[Lldb-commits] [lldb] [LLDB][ELF Core] Support all the Generic (Negative) SI Codes. (PR #140150)
Pavel Labath via lldb-commits
lldb-commits at lists.llvm.org
Fri May 23 01:13:47 PDT 2025
================
@@ -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
More information about the lldb-commits
mailing list