brintos

brintos / llvm-project-archived public Read only

0
0
Text · 21.6 KiB · da14da4 Raw
604 lines · cpp
1//===-- PlatformLinux.cpp -------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "PlatformLinux.h"10#include "lldb/Host/Config.h"11 12#include <cstdio>13#if LLDB_ENABLE_POSIX14#include <sys/utsname.h>15#endif16 17#include "Plugins/Process/Utility/LinuxSignals.h"18#include "Utility/ARM64_DWARF_Registers.h"19#include "lldb/Core/Debugger.h"20#include "lldb/Core/PluginManager.h"21#include "lldb/Host/HostInfo.h"22#include "lldb/Symbol/UnwindPlan.h"23#include "lldb/Target/Process.h"24#include "lldb/Target/Target.h"25#include "lldb/Utility/FileSpec.h"26#include "lldb/Utility/LLDBLog.h"27#include "lldb/Utility/Log.h"28#include "lldb/Utility/State.h"29#include "lldb/Utility/Status.h"30#include "lldb/Utility/StreamString.h"31 32// Define these constants from Linux mman.h for use when targeting remote linux33// systems even when host has different values.34#define MAP_PRIVATE 235#define MAP_ANON 0x2036 37// For other platforms that use platform linux38#ifndef SIGILL39#define SIGILL 440#endif41#ifndef SIGBUS42#define SIGBUS 743#endif44#ifndef SIGFPE45#define SIGFPE 846#endif47#ifndef SIGSEGV48#define SIGSEGV 1149#endif50 51using namespace lldb;52using namespace lldb_private;53using namespace lldb_private::platform_linux;54 55LLDB_PLUGIN_DEFINE(PlatformLinux)56 57static uint32_t g_initialize_count = 0;58 59 60PlatformSP PlatformLinux::CreateInstance(bool force, const ArchSpec *arch) {61  Log *log = GetLog(LLDBLog::Platform);62  LLDB_LOG(log, "force = {0}, arch=({1}, {2})", force,63           arch ? arch->GetArchitectureName() : "<null>",64           arch ? arch->GetTriple().getTriple() : "<null>");65 66  bool create = force;67  if (!create && arch && arch->IsValid()) {68    const llvm::Triple &triple = arch->GetTriple();69    switch (triple.getOS()) {70    case llvm::Triple::Linux:71      create = true;72      break;73 74#if defined(__linux__)75    // Only accept "unknown" for the OS if the host is linux and it "unknown"76    // wasn't specified (it was just returned because it was NOT specified)77    case llvm::Triple::OSType::UnknownOS:78      create = !arch->TripleOSWasSpecified();79      break;80#endif81    default:82      break;83    }84  }85 86  LLDB_LOG(log, "create = {0}", create);87  if (create) {88    return PlatformSP(new PlatformLinux(false));89  }90  return PlatformSP();91}92 93llvm::StringRef PlatformLinux::GetPluginDescriptionStatic(bool is_host) {94  if (is_host)95    return "Local Linux user platform plug-in.";96  return "Remote Linux user platform plug-in.";97}98 99void PlatformLinux::Initialize() {100  PlatformPOSIX::Initialize();101 102  if (g_initialize_count++ == 0) {103#if defined(__linux__) && !defined(__ANDROID__)104    PlatformSP default_platform_sp(new PlatformLinux(true));105    default_platform_sp->SetSystemArchitecture(HostInfo::GetArchitecture());106    Platform::SetHostPlatform(default_platform_sp);107#endif108    PluginManager::RegisterPlugin(109        PlatformLinux::GetPluginNameStatic(false),110        PlatformLinux::GetPluginDescriptionStatic(false),111        PlatformLinux::CreateInstance, nullptr);112  }113}114 115void PlatformLinux::Terminate() {116  if (g_initialize_count > 0) {117    if (--g_initialize_count == 0) {118      PluginManager::UnregisterPlugin(PlatformLinux::CreateInstance);119    }120  }121 122  PlatformPOSIX::Terminate();123}124 125/// Default Constructor126PlatformLinux::PlatformLinux(bool is_host)127    : PlatformPOSIX(is_host) // This is the local host platform128{129  if (is_host) {130    ArchSpec hostArch = HostInfo::GetArchitecture(HostInfo::eArchKindDefault);131    m_supported_architectures.push_back(hostArch);132    if (hostArch.GetTriple().isArch64Bit()) {133      m_supported_architectures.push_back(134          HostInfo::GetArchitecture(HostInfo::eArchKind32));135    }136  } else {137    m_supported_architectures = CreateArchList(138        {llvm::Triple::x86_64, llvm::Triple::x86, llvm::Triple::arm,139         llvm::Triple::aarch64, llvm::Triple::mips64, llvm::Triple::mips64,140         llvm::Triple::hexagon, llvm::Triple::mips, llvm::Triple::mips64el,141         llvm::Triple::mipsel, llvm::Triple::msp430, llvm::Triple::systemz,142         llvm::Triple::loongarch64, llvm::Triple::ppc64le,143         llvm::Triple::riscv64},144        llvm::Triple::Linux);145  }146}147 148std::vector<ArchSpec>149PlatformLinux::GetSupportedArchitectures(const ArchSpec &process_host_arch) {150  if (m_remote_platform_sp)151    return m_remote_platform_sp->GetSupportedArchitectures(process_host_arch);152  return m_supported_architectures;153}154 155void PlatformLinux::GetStatus(Stream &strm) {156  Platform::GetStatus(strm);157 158#if LLDB_ENABLE_POSIX159  // Display local kernel information only when we are running in host mode.160  // Otherwise, we would end up printing non-Linux information (when running on161  // Mac OS for example).162  if (IsHost()) {163    struct utsname un;164 165    if (uname(&un))166      return;167 168    strm.Printf("    Kernel: %s\n", un.sysname);169    strm.Printf("   Release: %s\n", un.release);170    strm.Printf("   Version: %s\n", un.version);171  }172#endif173}174 175uint32_t176PlatformLinux::GetResumeCountForLaunchInfo(ProcessLaunchInfo &launch_info) {177  uint32_t resume_count = 0;178 179  // Always resume past the initial stop when we use eLaunchFlagDebug180  if (launch_info.GetFlags().Test(eLaunchFlagDebug)) {181    // Resume past the stop for the final exec into the true inferior.182    ++resume_count;183  }184 185  // If we're not launching a shell, we're done.186  const FileSpec &shell = launch_info.GetShell();187  if (!shell)188    return resume_count;189 190  std::string shell_string = shell.GetPath();191  // We're in a shell, so for sure we have to resume past the shell exec.192  ++resume_count;193 194  // Figure out what shell we're planning on using.195  const char *shell_name = strrchr(shell_string.c_str(), '/');196  if (shell_name == nullptr)197    shell_name = shell_string.c_str();198  else199    shell_name++;200 201  if (strcmp(shell_name, "csh") == 0 || strcmp(shell_name, "tcsh") == 0 ||202      strcmp(shell_name, "zsh") == 0 || strcmp(shell_name, "sh") == 0) {203    // These shells seem to re-exec themselves.  Add another resume.204    ++resume_count;205  }206 207  return resume_count;208}209 210bool PlatformLinux::CanDebugProcess() {211  if (IsHost()) {212    return true;213  } else {214    // If we're connected, we can debug.215    return IsConnected();216  }217}218 219void PlatformLinux::CalculateTrapHandlerSymbolNames() {220  m_trap_handlers.push_back(ConstString("_sigtramp"));221  m_trap_handlers.push_back(ConstString("__kernel_rt_sigreturn"));222  m_trap_handlers.push_back(ConstString("__restore_rt"));223}224 225static lldb::UnwindPlanSP GetAArch64TrapHandlerUnwindPlan(ConstString name) {226  UnwindPlanSP unwind_plan_sp;227  if (name != "__kernel_rt_sigreturn")228    return unwind_plan_sp;229 230  UnwindPlan::Row row;231 232  // In the signal trampoline frame, sp points to an rt_sigframe[1], which is:233  //  - 128-byte siginfo struct234  //  - ucontext struct:235  //     - 8-byte long (uc_flags)236  //     - 8-byte pointer (uc_link)237  //     - 24-byte stack_t238  //     - 128-byte signal set239  //     - 8 bytes of padding because sigcontext has 16-byte alignment240  //     - sigcontext/mcontext_t241  // [1]242  // https://github.com/torvalds/linux/blob/master/arch/arm64/kernel/signal.c243  int32_t offset = 128 + 8 + 8 + 24 + 128 + 8;244  // Then sigcontext[2] is:245  // - 8 byte fault address246  // - 31 8 byte registers247  // - 8 byte sp248  // - 8 byte pc249  // [2]250  // https://github.com/torvalds/linux/blob/master/arch/arm64/include/uapi/asm/sigcontext.h251 252  // Skip fault address253  offset += 8;254  row.GetCFAValue().SetIsRegisterPlusOffset(arm64_dwarf::sp, offset);255 256  row.SetRegisterLocationToAtCFAPlusOffset(arm64_dwarf::x0, 0 * 8, false);257  row.SetRegisterLocationToAtCFAPlusOffset(arm64_dwarf::x1, 1 * 8, false);258  row.SetRegisterLocationToAtCFAPlusOffset(arm64_dwarf::x2, 2 * 8, false);259  row.SetRegisterLocationToAtCFAPlusOffset(arm64_dwarf::x3, 3 * 8, false);260  row.SetRegisterLocationToAtCFAPlusOffset(arm64_dwarf::x4, 4 * 8, false);261  row.SetRegisterLocationToAtCFAPlusOffset(arm64_dwarf::x5, 5 * 8, false);262  row.SetRegisterLocationToAtCFAPlusOffset(arm64_dwarf::x6, 6 * 8, false);263  row.SetRegisterLocationToAtCFAPlusOffset(arm64_dwarf::x7, 7 * 8, false);264  row.SetRegisterLocationToAtCFAPlusOffset(arm64_dwarf::x8, 8 * 8, false);265  row.SetRegisterLocationToAtCFAPlusOffset(arm64_dwarf::x9, 9 * 8, false);266  row.SetRegisterLocationToAtCFAPlusOffset(arm64_dwarf::x10, 10 * 8, false);267  row.SetRegisterLocationToAtCFAPlusOffset(arm64_dwarf::x11, 11 * 8, false);268  row.SetRegisterLocationToAtCFAPlusOffset(arm64_dwarf::x12, 12 * 8, false);269  row.SetRegisterLocationToAtCFAPlusOffset(arm64_dwarf::x13, 13 * 8, false);270  row.SetRegisterLocationToAtCFAPlusOffset(arm64_dwarf::x14, 14 * 8, false);271  row.SetRegisterLocationToAtCFAPlusOffset(arm64_dwarf::x15, 15 * 8, false);272  row.SetRegisterLocationToAtCFAPlusOffset(arm64_dwarf::x16, 16 * 8, false);273  row.SetRegisterLocationToAtCFAPlusOffset(arm64_dwarf::x17, 17 * 8, false);274  row.SetRegisterLocationToAtCFAPlusOffset(arm64_dwarf::x18, 18 * 8, false);275  row.SetRegisterLocationToAtCFAPlusOffset(arm64_dwarf::x19, 19 * 8, false);276  row.SetRegisterLocationToAtCFAPlusOffset(arm64_dwarf::x20, 20 * 8, false);277  row.SetRegisterLocationToAtCFAPlusOffset(arm64_dwarf::x21, 21 * 8, false);278  row.SetRegisterLocationToAtCFAPlusOffset(arm64_dwarf::x22, 22 * 8, false);279  row.SetRegisterLocationToAtCFAPlusOffset(arm64_dwarf::x23, 23 * 8, false);280  row.SetRegisterLocationToAtCFAPlusOffset(arm64_dwarf::x24, 24 * 8, false);281  row.SetRegisterLocationToAtCFAPlusOffset(arm64_dwarf::x25, 25 * 8, false);282  row.SetRegisterLocationToAtCFAPlusOffset(arm64_dwarf::x26, 26 * 8, false);283  row.SetRegisterLocationToAtCFAPlusOffset(arm64_dwarf::x27, 27 * 8, false);284  row.SetRegisterLocationToAtCFAPlusOffset(arm64_dwarf::x28, 28 * 8, false);285  row.SetRegisterLocationToAtCFAPlusOffset(arm64_dwarf::fp, 29 * 8, false);286  row.SetRegisterLocationToAtCFAPlusOffset(arm64_dwarf::x30, 30 * 8, false);287  row.SetRegisterLocationToAtCFAPlusOffset(arm64_dwarf::sp, 31 * 8, false);288  row.SetRegisterLocationToAtCFAPlusOffset(arm64_dwarf::pc, 32 * 8, false);289 290  // The sigcontext may also contain floating point and SVE registers.291  // However this would require a dynamic unwind plan so they are not included292  // here.293 294  unwind_plan_sp = std::make_shared<UnwindPlan>(eRegisterKindDWARF);295  unwind_plan_sp->AppendRow(std::move(row));296  unwind_plan_sp->SetSourceName("AArch64 Linux sigcontext");297  unwind_plan_sp->SetSourcedFromCompiler(eLazyBoolYes);298  // Because sp is the same throughout the function299  unwind_plan_sp->SetUnwindPlanValidAtAllInstructions(eLazyBoolYes);300  unwind_plan_sp->SetUnwindPlanForSignalTrap(eLazyBoolYes);301 302  return unwind_plan_sp;303}304 305lldb::UnwindPlanSP306PlatformLinux::GetTrapHandlerUnwindPlan(const llvm::Triple &triple,307                                        ConstString name) {308  if (triple.isAArch64())309    return GetAArch64TrapHandlerUnwindPlan(name);310 311  return {};312}313 314MmapArgList PlatformLinux::GetMmapArgumentList(const ArchSpec &arch,315                                               addr_t addr, addr_t length,316                                               unsigned prot, unsigned flags,317                                               addr_t fd, addr_t offset) {318  uint64_t flags_platform = 0;319  uint64_t map_anon = arch.IsMIPS() ? 0x800 : MAP_ANON;320 321  if (flags & eMmapFlagsPrivate)322    flags_platform |= MAP_PRIVATE;323  if (flags & eMmapFlagsAnon)324    flags_platform |= map_anon;325 326  MmapArgList args({addr, length, prot, flags_platform, fd, offset});327  return args;328}329 330CompilerType PlatformLinux::GetSiginfoType(const llvm::Triple &triple) {331  {332    std::lock_guard<std::mutex> guard(m_mutex);333    if (!m_type_system)334      m_type_system = std::make_shared<TypeSystemClang>("siginfo", triple);335  }336  TypeSystemClang *ast = m_type_system.get();337 338  bool si_errno_then_code = true;339 340  switch (triple.getArch()) {341  case llvm::Triple::mips:342  case llvm::Triple::mipsel:343  case llvm::Triple::mips64:344  case llvm::Triple::mips64el:345    // mips has si_code and si_errno swapped346    si_errno_then_code = false;347    break;348  default:349    break;350  }351 352  // generic types353  CompilerType int_type = ast->GetBasicType(eBasicTypeInt);354  CompilerType uint_type = ast->GetBasicType(eBasicTypeUnsignedInt);355  CompilerType short_type = ast->GetBasicType(eBasicTypeShort);356  CompilerType long_type = ast->GetBasicType(eBasicTypeLong);357  CompilerType voidp_type = ast->GetBasicType(eBasicTypeVoid).GetPointerType();358 359  // platform-specific types360  CompilerType &pid_type = int_type;361  CompilerType &uid_type = uint_type;362  CompilerType &clock_type = long_type;363  CompilerType &band_type = long_type;364 365  CompilerType sigval_type = ast->CreateRecordType(366      nullptr, OptionalClangModuleID(), lldb::eAccessPublic, "__lldb_sigval_t",367      llvm::to_underlying(clang::TagTypeKind::Union), lldb::eLanguageTypeC);368  ast->StartTagDeclarationDefinition(sigval_type);369  ast->AddFieldToRecordType(sigval_type, "sival_int", int_type,370                            lldb::eAccessPublic, 0);371  ast->AddFieldToRecordType(sigval_type, "sival_ptr", voidp_type,372                            lldb::eAccessPublic, 0);373  ast->CompleteTagDeclarationDefinition(sigval_type);374 375  CompilerType sigfault_bounds_type = ast->CreateRecordType(376      nullptr, OptionalClangModuleID(), lldb::eAccessPublic, "",377      llvm::to_underlying(clang::TagTypeKind::Union), lldb::eLanguageTypeC);378  ast->StartTagDeclarationDefinition(sigfault_bounds_type);379  ast->AddFieldToRecordType(380      sigfault_bounds_type, "_addr_bnd",381      ast->CreateStructForIdentifier(llvm::StringRef(),382                                     {383                                         {"_lower", voidp_type},384                                         {"_upper", voidp_type},385                                     }),386      lldb::eAccessPublic, 0);387  ast->AddFieldToRecordType(sigfault_bounds_type, "_pkey", uint_type,388                            lldb::eAccessPublic, 0);389  ast->CompleteTagDeclarationDefinition(sigfault_bounds_type);390 391  // siginfo_t392  CompilerType siginfo_type = ast->CreateRecordType(393      nullptr, OptionalClangModuleID(), lldb::eAccessPublic, "__lldb_siginfo_t",394      llvm::to_underlying(clang::TagTypeKind::Struct), lldb::eLanguageTypeC);395  ast->StartTagDeclarationDefinition(siginfo_type);396  ast->AddFieldToRecordType(siginfo_type, "si_signo", int_type,397                            lldb::eAccessPublic, 0);398 399  if (si_errno_then_code) {400    ast->AddFieldToRecordType(siginfo_type, "si_errno", int_type,401                              lldb::eAccessPublic, 0);402    ast->AddFieldToRecordType(siginfo_type, "si_code", int_type,403                              lldb::eAccessPublic, 0);404  } else {405    ast->AddFieldToRecordType(siginfo_type, "si_code", int_type,406                              lldb::eAccessPublic, 0);407    ast->AddFieldToRecordType(siginfo_type, "si_errno", int_type,408                              lldb::eAccessPublic, 0);409  }410 411  // the structure is padded on 64-bit arches to fix alignment412  if (triple.isArch64Bit())413    ast->AddFieldToRecordType(siginfo_type, "__pad0", int_type,414                              lldb::eAccessPublic, 0);415 416  // union used to hold the signal data417  CompilerType union_type = ast->CreateRecordType(418      nullptr, OptionalClangModuleID(), lldb::eAccessPublic, "",419      llvm::to_underlying(clang::TagTypeKind::Union), lldb::eLanguageTypeC);420  ast->StartTagDeclarationDefinition(union_type);421 422  ast->AddFieldToRecordType(423      union_type, "_kill",424      ast->CreateStructForIdentifier(llvm::StringRef(),425                                     {426                                         {"si_pid", pid_type},427                                         {"si_uid", uid_type},428                                     }),429      lldb::eAccessPublic, 0);430 431  ast->AddFieldToRecordType(432      union_type, "_timer",433      ast->CreateStructForIdentifier(llvm::StringRef(),434                                     {435                                         {"si_tid", int_type},436                                         {"si_overrun", int_type},437                                         {"si_sigval", sigval_type},438                                     }),439      lldb::eAccessPublic, 0);440 441  ast->AddFieldToRecordType(442      union_type, "_rt",443      ast->CreateStructForIdentifier(llvm::StringRef(),444                                     {445                                         {"si_pid", pid_type},446                                         {"si_uid", uid_type},447                                         {"si_sigval", sigval_type},448                                     }),449      lldb::eAccessPublic, 0);450 451  ast->AddFieldToRecordType(452      union_type, "_sigchld",453      ast->CreateStructForIdentifier(llvm::StringRef(),454                                     {455                                         {"si_pid", pid_type},456                                         {"si_uid", uid_type},457                                         {"si_status", int_type},458                                         {"si_utime", clock_type},459                                         {"si_stime", clock_type},460                                     }),461      lldb::eAccessPublic, 0);462 463  ast->AddFieldToRecordType(464      union_type, "_sigfault",465      ast->CreateStructForIdentifier(llvm::StringRef(),466                                     {467                                         {"si_addr", voidp_type},468                                         {"si_addr_lsb", short_type},469                                         {"_bounds", sigfault_bounds_type},470                                     }),471      lldb::eAccessPublic, 0);472 473  ast->AddFieldToRecordType(474      union_type, "_sigpoll",475      ast->CreateStructForIdentifier(llvm::StringRef(),476                                     {477                                         {"si_band", band_type},478                                         {"si_fd", int_type},479                                     }),480      lldb::eAccessPublic, 0);481 482  // NB: SIGSYS is not present on ia64 but we don't seem to support that483  ast->AddFieldToRecordType(484      union_type, "_sigsys",485      ast->CreateStructForIdentifier(llvm::StringRef(),486                                     {487                                         {"_call_addr", voidp_type},488                                         {"_syscall", int_type},489                                         {"_arch", uint_type},490                                     }),491      lldb::eAccessPublic, 0);492 493  ast->CompleteTagDeclarationDefinition(union_type);494  ast->AddFieldToRecordType(siginfo_type, "_sifields", union_type,495                            lldb::eAccessPublic, 0);496 497  ast->CompleteTagDeclarationDefinition(siginfo_type);498  return siginfo_type;499}500 501static std::string GetDescriptionFromSiginfo(lldb::ValueObjectSP siginfo_sp) {502  if (!siginfo_sp)503    return "";504 505  lldb_private::LinuxSignals linux_signals;506  int code = siginfo_sp->GetChildMemberWithName("si_code")->GetValueAsSigned(0);507  int signo =508      siginfo_sp->GetChildMemberWithName("si_signo")->GetValueAsSigned(-1);509 510  auto sifields = siginfo_sp->GetChildMemberWithName("_sifields");511  if (!sifields)512    return linux_signals.GetSignalDescription(signo, code);513 514  // declare everything that we can populate later.515  std::optional<lldb::addr_t> addr;516  std::optional<lldb::addr_t> upper;517  std::optional<lldb::addr_t> lower;518  std::optional<uint32_t> pid;519  std::optional<uint32_t> uid;520 521  // The negative si_codes are special and mean this signal was sent from user522  // space not the kernel. These take precedence because they break some of the523  // invariants around kernel sent signals. Such as SIGSEGV won't have an524  // address.525  if (code < 0) {526    auto sikill = sifields->GetChildMemberWithName("_kill");527    if (sikill) {528      auto pid_sp = sikill->GetChildMemberWithName("si_pid");529      if (pid_sp)530        pid = pid_sp->GetValueAsUnsigned(-1);531      auto uid_sp = sikill->GetChildMemberWithName("si_uid");532      if (uid_sp)533        uid = uid_sp->GetValueAsUnsigned(-1);534    }535  } else {536 537    switch (signo) {538    case SIGILL:539    case SIGFPE:540    case SIGBUS: {541      auto sigfault = sifields->GetChildMemberWithName("_sigfault");542      if (!sigfault)543        break;544 545      auto addr_sp = sigfault->GetChildMemberWithName("si_addr");546      if (addr_sp)547        addr = addr_sp->GetValueAsUnsigned(-1);548      break;549    }550    case SIGSEGV: {551      auto sigfault = sifields->GetChildMemberWithName("_sigfault");552      if (!sigfault)553        break;554 555      auto addr_sp = sigfault->GetChildMemberWithName("si_addr");556      if (addr_sp)557        addr = addr_sp->GetValueAsUnsigned(-1);558 559      auto bounds_sp = sigfault->GetChildMemberWithName("_bounds");560      if (!bounds_sp)561        break;562 563      auto addr_bnds_sp = bounds_sp->GetChildMemberWithName("_addr_bnd");564      if (!addr_bnds_sp)565        break;566 567      auto lower_sp = addr_bnds_sp->GetChildMemberWithName("_lower");568      if (lower_sp)569        lower = lower_sp->GetValueAsUnsigned(-1);570 571      auto upper_sp = addr_bnds_sp->GetChildMemberWithName("_upper");572      if (upper_sp)573        upper = upper_sp->GetValueAsUnsigned(-1);574 575      break;576    }577    default:578      break;579    }580  }581 582  return linux_signals.GetSignalDescription(signo, code, addr, lower, upper,583                                            pid, uid);584}585 586lldb::StopInfoSP PlatformLinux::GetStopInfoFromSiginfo(Thread &thread) {587  ValueObjectSP siginfo_sp = thread.GetSiginfoValue();588  if (!siginfo_sp)589    return {};590  auto signo_sp = siginfo_sp->GetChildMemberWithName("si_signo");591  auto sicode_sp = siginfo_sp->GetChildMemberWithName("si_code");592  if (!signo_sp || !sicode_sp)593    return {};594 595  std::string siginfo_description = GetDescriptionFromSiginfo(siginfo_sp);596  if (siginfo_description.empty())597    return StopInfo::CreateStopReasonWithSignal(598        thread, signo_sp->GetValueAsUnsigned(-1));599 600  return StopInfo::CreateStopReasonWithSignal(601      thread, signo_sp->GetValueAsUnsigned(-1), siginfo_description.c_str(),602      sicode_sp->GetValueAsUnsigned(0));603}604