summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMateusz Moscicki/System (PLT) /SRPOL/Engineer/Samsung Electronics <m.moscicki2@samsung.com>2024-01-12 08:46:43 +0100
committerGitHub Enterprise <noreply-CODE@samsung.com>2024-01-12 16:46:43 +0900
commit1439e662dc11f05e61b625b09e1cd49ef64a2172 (patch)
tree091c8097ee738f26929a691f92d1dcfe3a7dabb3
parentdb21d5f9b7b3390eadbf6176530064091c81a16b (diff)
downloadruntime-accepted/tizen_unified_riscv.tar.gz
runtime-accepted/tizen_unified_riscv.tar.bz2
runtime-accepted/tizen_unified_riscv.zip
[Tizen] Add method to write coredump of .NET process (#384)accepted/tizen/unified/riscv/20240115.053917accepted/tizen_unified_riscv
This method allows to create minimal coredump (as createdump does) of a process that is in dumping state after crush. This is a modified version of https://github.sec.samsung.net/dotnet/coreclr/commit/4d043d61ecacae0b9922ecc10a73749e7c8e5987 commit, adapted to .NET 8.0 Co-authored-by: Mateusz Moscicki <m.moscicki2@partner.samsung.com>
-rw-r--r--packaging/coreclr.spec3
-rw-r--r--src/coreclr/debug/createdump/CMakeLists.txt29
-rw-r--r--src/coreclr/debug/createdump/crashinfo.cpp29
-rw-r--r--src/coreclr/debug/createdump/crashinfo.h5
-rw-r--r--src/coreclr/debug/createdump/crashinfounix.cpp25
-rw-r--r--src/coreclr/debug/createdump/dnetmemoryenumlib.cpp287
-rw-r--r--src/coreclr/debug/createdump/dnetmemoryenumlib.h61
-rw-r--r--src/coreclr/debug/createdump/threadinfo.cpp96
-rw-r--r--src/coreclr/debug/createdump/threadinfo.h1
9 files changed, 517 insertions, 19 deletions
diff --git a/packaging/coreclr.spec b/packaging/coreclr.spec
index 6340b2f9855..26862111a96 100644
--- a/packaging/coreclr.spec
+++ b/packaging/coreclr.spec
@@ -470,6 +470,7 @@ cp %{_reldir_clr}/libjitinterface_%{_tarch}.so %{buildroot}%{_datadir}/
cp %{_reldir_clr}/ilasm %{buildroot}%{_datadir}/%{netcoreappdir}
cp %{_reldir_clr}/ildasm %{buildroot}%{_datadir}/%{netcoreappdir}
cp %{_reldir_clr}/createdump %{buildroot}%{_datadir}/%{netcoreappdir}
+cp %{_reldir_clr}/libdnetmemoryenum.so %{buildroot}%{_datadir}/%{netcoreappdir}
# CoreFX native
cp %{_reldir_fx_native}/libSystem.Globalization.Native.so %{buildroot}%{_datadir}/%{netcoreappdir}
@@ -718,7 +719,7 @@ cp ./nuget/*.nupkg %{buildroot}/nuget
%{_datadir}/%{netcoreappdir}/ilasm
%{_datadir}/%{netcoreappdir}/ildasm
%{_datadir}/%{netcoreappdir}/createdump
-
+%{_datadir}/%{netcoreappdir}/libdnetmemoryenum.so
%if 0%{skipmanaged}
%else
diff --git a/src/coreclr/debug/createdump/CMakeLists.txt b/src/coreclr/debug/createdump/CMakeLists.txt
index 666bd682835..cbf131b0df0 100644
--- a/src/coreclr/debug/createdump/CMakeLists.txt
+++ b/src/coreclr/debug/createdump/CMakeLists.txt
@@ -107,6 +107,35 @@ endif(CLR_CMAKE_HOST_OSX)
)
set_target_properties(createdump PROPERTIES LINK_FLAGS -pie)
+ set(DNETMEMORYENUM_SOURCES
+ dumpname.cpp
+ crashinfounix.cpp
+ threadinfounix.cpp
+ createdumpunix.cpp
+ crashinfo.cpp
+ threadinfo.cpp
+ datatarget.cpp
+ dumpwriter.cpp
+ dumpwriterelf.cpp
+ crashreportwriter.cpp
+ dnetmemoryenumlib.cpp
+ createdumppal.cpp
+ ${CLR_SRC_NATIVE_DIR}/minipal/utf8.c
+ )
+
+ add_library_clr(dnetmemoryenum SHARED
+ ${DNETMEMORYENUM_SOURCES}
+ )
+
+ set_property(TARGET dnetmemoryenum PROPERTY COMPILE_FLAGS "-fPIC")
+
+ target_link_libraries(dnetmemoryenum
+ corguids
+ dbgutil
+ )
+
+ install_clr(TARGETS dnetmemoryenum DESTINATIONS . sharedFramework COMPONENT runtime)
+
endif(CLR_CMAKE_HOST_WIN32)
install_clr(TARGETS createdump DESTINATIONS . sharedFramework COMPONENT runtime)
diff --git a/src/coreclr/debug/createdump/crashinfo.cpp b/src/coreclr/debug/createdump/crashinfo.cpp
index 8af6ec4a54f..351e6a08e0c 100644
--- a/src/coreclr/debug/createdump/crashinfo.cpp
+++ b/src/coreclr/debug/createdump/crashinfo.cpp
@@ -147,17 +147,36 @@ CrashInfo::LogMessage(
}
//
+// Set registers for all threads
+//
+void
+CrashInfo::SetThreadsRegisters(const std::vector<elf_prstatus*> &statuses)
+{
+ for (ThreadInfo* thread : m_threads) {
+ for (elf_prstatus* status : statuses) {
+ if (thread->Tid() == status->pr_pid) {
+ thread->SetRegisters(status);
+ break;
+ }
+ }
+ }
+}
+
+//
// Gather all the necessary crash dump info.
//
bool
-CrashInfo::GatherCrashInfo(DumpType dumpType)
+CrashInfo::GatherCrashInfo(DumpType dumpType, bool initialize_threads)
{
- // Get the info about the threads (registers, etc.)
- for (ThreadInfo* thread : m_threads)
+ if (initialize_threads)
{
- if (!thread->Initialize())
+ // Get the info about the threads (registers, etc.)
+ for (ThreadInfo* thread : m_threads)
{
- return false;
+ if (!thread->Initialize())
+ {
+ return false;
+ }
}
}
#ifdef __APPLE__
diff --git a/src/coreclr/debug/createdump/crashinfo.h b/src/coreclr/debug/createdump/crashinfo.h
index 6673e2dec7d..0253d2ad92d 100644
--- a/src/coreclr/debug/createdump/crashinfo.h
+++ b/src/coreclr/debug/createdump/crashinfo.h
@@ -93,8 +93,9 @@ public:
bool Initialize();
void CleanupAndResumeProcess();
- bool EnumerateAndSuspendThreads();
- bool GatherCrashInfo(DumpType dumpType);
+ bool EnumerateAndSuspendThreads(bool suspend = true);
+ void SetThreadsRegisters(const std::vector<elf_prstatus*> &statuses);
+ bool GatherCrashInfo(DumpType minidumpType, bool initialize_threads = true);
void CombineMemoryRegions();
bool EnumerateMemoryRegionsWithDAC(DumpType dumpType);
bool ReadMemory(void* address, void* buffer, size_t size); // read memory and add to dump
diff --git a/src/coreclr/debug/createdump/crashinfounix.cpp b/src/coreclr/debug/createdump/crashinfounix.cpp
index 70b2ddb270d..d37312764bf 100644
--- a/src/coreclr/debug/createdump/crashinfounix.cpp
+++ b/src/coreclr/debug/createdump/crashinfounix.cpp
@@ -102,7 +102,7 @@ CrashInfo::CleanupAndResumeProcess()
// Suspends all the threads and creating a list of them. Should be the before gathering any info about the process.
//
bool
-CrashInfo::EnumerateAndSuspendThreads()
+CrashInfo::EnumerateAndSuspendThreads(bool suspend)
{
char taskPath[128];
int chars = snprintf(taskPath, sizeof(taskPath), "/proc/%u/task", m_pid);
@@ -125,17 +125,20 @@ CrashInfo::EnumerateAndSuspendThreads()
pid_t tid = static_cast<pid_t>(strtol(entry->d_name, nullptr, 10));
if (tid != 0)
{
- // Reference: http://stackoverflow.com/questions/18577956/how-to-use-ptrace-to-get-a-consistent-view-of-multiple-threads
- if (ptrace(PTRACE_ATTACH, tid, nullptr, nullptr) != -1)
+ if (suspend)
{
- int waitStatus;
- waitpid(tid, &waitStatus, __WALL);
- }
- else
- {
- printf_error("Problem suspending threads: ptrace(ATTACH, %d) FAILED %s (%d)\n", tid, strerror(errno), errno);
- closedir(taskDir);
- return false;
+ // Reference: http://stackoverflow.com/questions/18577956/how-to-use-ptrace-to-get-a-consistent-view-of-multiple-threads
+ if (ptrace(PTRACE_ATTACH, tid, nullptr, nullptr) != -1)
+ {
+ int waitStatus;
+ waitpid(tid, &waitStatus, __WALL);
+ }
+ else
+ {
+ printf_error("Problem suspending threads: ptrace(ATTACH, %d) FAILED %s (%d)\n", tid, strerror(errno), errno);
+ closedir(taskDir);
+ return false;
+ }
}
// Add to the list of threads
ThreadInfo* thread = new ThreadInfo(*this, tid);
diff --git a/src/coreclr/debug/createdump/dnetmemoryenumlib.cpp b/src/coreclr/debug/createdump/dnetmemoryenumlib.cpp
new file mode 100644
index 00000000000..0148e5d4346
--- /dev/null
+++ b/src/coreclr/debug/createdump/dnetmemoryenumlib.cpp
@@ -0,0 +1,287 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019-2024 Samsung Electronics Co., Ltd.
+ *
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <stdarg.h>
+#include <iostream>
+#include <vector>
+#include <minipal/utf8.h>
+#include "createdump.h"
+#include "dnetmemoryenumlib.h"
+
+const int DEFAULT_SIGNAL = 6;
+
+bool g_diagnostics = false;
+bool g_diagnosticsVerbose = false;
+
+#if defined(HOST_ARM64)
+// Flag to check if atomics feature is available on
+// the machine
+bool g_arm64_atomics_present = false;
+#endif
+
+std::vector<SimpleMemoryRegion> sm_regions;
+
+int
+prepare_crash_info(pid_t pid, elf_prstatus **statuses, int statuses_count,
+ DUMP_TYPE minidump_type, ReleaseHolder<CrashInfo> &crash_info)
+{
+ g_diagnostics = true;
+
+ CreateDumpOptions options;
+ options.DumpType = DumpType::Heap;
+ options.DumpPathTemplate = nullptr;
+ options.AppModel = AppModelType::Normal;
+ options.CrashReport = false;
+ options.CreateDump = true;
+ options.Signal = DEFAULT_SIGNAL;
+ options.CrashThread = pid;
+ options.Pid = pid;
+ options.SignalCode = 0;
+ options.SignalErrno = 0;
+ options.SignalAddress = 0;
+ options.ExceptionRecord = 0;
+
+ std::vector<elf_prstatus*> stats(statuses, statuses + statuses_count);
+
+ switch (minidump_type) {
+ case DT_NORMAL:
+ default:
+ options.DumpType = DumpType::Mini;
+ break;
+ case DT_WITH_PRIV_AND_SHARED_MEM:
+ options.DumpType = DumpType::Triage;
+ break;
+ case DT_FULL:
+ options.DumpType = DumpType::Full;
+ break;
+ }
+
+ int exitCode = REGERR_OK;
+
+ if (pid != 0)
+ {
+ crash_info = new CrashInfo(options);
+
+ // Initialize PAGE_SIZE
+#if defined(__arm__) || defined(__aarch64__) || defined(__loongarch64) || defined(__riscv)
+ g_pageSize = sysconf(_SC_PAGESIZE);
+#endif
+
+ if (!crash_info->Initialize())
+ {
+ return REGERR_CRASHINFO_INITIALIZE_ERROR;
+ }
+
+ if (!crash_info->EnumerateAndSuspendThreads(false))
+ {
+ return REGERR_ENUMERATION_ERROR;
+ }
+ crash_info->SetThreadsRegisters(stats);
+ if (!crash_info->GatherCrashInfo(options.DumpType, false))
+ {
+ return REGERR_GATHER_CRASHINFO_ERROR;
+ }
+ if (!crash_info->EnumerateMemoryRegionsWithDAC(options.DumpType))
+ {
+ return REGERR_ENUMERATIONDAC_ERROR;
+ }
+ crash_info->CombineMemoryRegions();
+ }
+ else
+ {
+ exitCode = REGERR_WRONG_PID;
+ }
+ return exitCode;
+}
+
+extern "C" DLLEXPORT int
+DotNetMemoryEnumInit()
+{
+ return 0;
+}
+
+extern "C" DLLEXPORT void
+DotNetMemoryEnumFinish()
+{
+}
+
+extern "C" DLLEXPORT int
+DotNetMemoryWriteDump(pid_t pid, elf_prstatus **statuses, int statuses_count,
+ DUMP_TYPE minidump_type, const char *dump_path)
+{
+ ReleaseHolder<CrashInfo> crashInfo;
+ int exitCode = prepare_crash_info(pid, statuses, statuses_count, minidump_type, crashInfo);
+
+ if (exitCode != REGERR_OK)
+ return exitCode;
+
+ DumpWriter dumpWriter(*crashInfo);
+
+ if (!dumpWriter.OpenDump(dump_path))
+ exitCode = REGERR_OPENDUMP_ERROR;
+
+ if (!dumpWriter.WriteDump())
+ exitCode = REGERR_WRITEDUMP_ERROR;
+
+ return exitCode;
+}
+
+void
+printf_status(const char* format, ...)
+{
+ va_list args;
+ va_start(args, format);
+ fprintf(stdout, "[createdump] ");
+ vfprintf(stdout, format, args);
+ fflush(stdout);
+ va_end(args);
+}
+
+void
+printf_error(const char* format, ...)
+{
+ va_list args;
+ va_start(args, format);
+ fprintf(stderr, "[createdump] ");
+ vfprintf(stderr, format, args);
+ fflush(stderr);
+ va_end(args);
+}
+
+void
+trace_printf(const char* format, ...)
+{
+ if (g_diagnostics)
+ {
+ va_list args;
+ va_start(args, format);
+ fprintf(stdout, "[dnetmemoryenumlib] ");
+ vfprintf(stdout, format, args);
+ fflush(stdout);
+ va_end(args);
+ }
+}
+
+void
+trace_verbose_printf(const char* format, ...)
+{
+ if (g_diagnosticsVerbose)
+ {
+ va_list args;
+ va_start(args, format);
+ fprintf(stdout, "[dnetmemoryenumlib] ");
+ vfprintf(stdout, format, args);
+ fflush(stdout);
+ va_end(args);
+ }
+}
+
+#ifdef HOST_UNIX
+void
+CrashInfo::Trace(const char* format, ...)
+{
+ if (g_diagnostics)
+ {
+ va_list args;
+ va_start(args, format);
+ fprintf(stdout, "[dnetmemoryenumlib] ");
+ vfprintf(stdout, format, args);
+ fflush(stdout);
+ va_end(args);
+ }
+}
+
+void
+CrashInfo::TraceVerbose(const char* format, ...)
+{
+ if (g_diagnosticsVerbose)
+ {
+ va_list args;
+ va_start(args, format);
+ fprintf(stdout, "[dnetmemoryenumlib] ");
+ vfprintf(stdout, format, args);
+ fflush(stdout);
+ va_end(args);
+ }
+}
+#endif
+
+const char*
+GetDumpTypeString(DumpType dumpType)
+{
+ switch (dumpType)
+ {
+ case DumpType::Mini:
+ return "minidump";
+ case DumpType::Heap:
+ return "minidump with heap";
+ case DumpType::Triage:
+ return "triage minidump";
+ case DumpType::Full:
+ return "full dump";
+ default:
+ return "unknown";
+ }
+}
+
+MINIDUMP_TYPE
+GetMiniDumpType(DumpType dumpType)
+{
+ switch (dumpType)
+ {
+ case DumpType::Mini:
+ return (MINIDUMP_TYPE)(MiniDumpNormal |
+ MiniDumpWithDataSegs |
+ MiniDumpWithHandleData |
+ MiniDumpWithThreadInfo);
+ case DumpType::Heap:
+ return (MINIDUMP_TYPE)(MiniDumpWithPrivateReadWriteMemory |
+ MiniDumpWithDataSegs |
+ MiniDumpWithHandleData |
+ MiniDumpWithUnloadedModules |
+ MiniDumpWithFullMemoryInfo |
+ MiniDumpWithThreadInfo |
+ MiniDumpWithTokenInformation);
+ case DumpType::Triage:
+ return (MINIDUMP_TYPE)(MiniDumpFilterTriage |
+ MiniDumpIgnoreInaccessibleMemory |
+ MiniDumpWithoutOptionalData |
+ MiniDumpWithProcessThreadData |
+ MiniDumpFilterModulePaths |
+ MiniDumpWithUnloadedModules |
+ MiniDumpFilterMemory |
+ MiniDumpWithHandleData);
+ case DumpType::Full:
+ default:
+ return (MINIDUMP_TYPE)(MiniDumpWithFullMemory |
+ MiniDumpWithDataSegs |
+ MiniDumpWithHandleData |
+ MiniDumpWithUnloadedModules |
+ MiniDumpWithFullMemoryInfo |
+ MiniDumpWithThreadInfo |
+ MiniDumpWithTokenInformation);
+ }
+}
diff --git a/src/coreclr/debug/createdump/dnetmemoryenumlib.h b/src/coreclr/debug/createdump/dnetmemoryenumlib.h
new file mode 100644
index 00000000000..0823d9735ea
--- /dev/null
+++ b/src/coreclr/debug/createdump/dnetmemoryenumlib.h
@@ -0,0 +1,61 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019-2024 Samsung Electronics Co., Ltd.
+ *
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef __DNETMEMORYENUMLIB_H__
+#define __DNETMEMORYENUMLIB_H__
+
+#include <stdint.h>
+#include <stdlib.h>
+
+struct SimpleMemoryRegion {
+ uintptr_t m_startAddress;
+ size_t m_size;
+};
+
+enum DUMP_TYPE {
+ DT_NORMAL = 0,
+ DT_WITH_PRIV_AND_SHARED_MEM,
+ DT_FULL
+};
+
+enum REG_ERR {
+ REGERR_OK = 0,
+ REGERR_WRONG_PID = -1,
+ REGERR_INITIALIZATION_ERROR = -2,
+ REGERR_ENUMERATION_ERROR = -3,
+ REGERR_OPENDUMP_ERROR = -4,
+ REGERR_WRITEDUMP_ERROR = -5,
+ REGERR_ENUMERATIONDAC_ERROR = -6,
+ REGERR_CRASHINFO_INITIALIZE_ERROR = -7,
+ REGERR_GATHER_CRASHINFO_ERROR = -8,
+};
+
+extern "C" DLLEXPORT int DotNetMemoryWriteDump(pid_t pid, elf_prstatus **statuses, int statuses_count,
+ DUMP_TYPE minidump_type, const char *dump_path);
+extern "C" DLLEXPORT int DotNetMemoryEnumInit();
+extern "C" DLLEXPORT void DotNetMemoryEnumFinish();
+
+#endif
diff --git a/src/coreclr/debug/createdump/threadinfo.cpp b/src/coreclr/debug/createdump/threadinfo.cpp
index 9d4e8377749..9c908ad9610 100644
--- a/src/coreclr/debug/createdump/threadinfo.cpp
+++ b/src/coreclr/debug/createdump/threadinfo.cpp
@@ -396,3 +396,99 @@ ThreadInfo::IsCrashThread() const
{
return m_tid == m_crashInfo.CrashThread();
}
+
+void ThreadInfo::SetRegisters(elf_prstatus *prstatus)
+{
+#if defined(__x86_64__)
+ struct user_regs_struct *u_reg = (struct user_regs_struct *)&prstatus->pr_reg;
+ m_gpRegisters.rip = u_reg->rip;
+ m_gpRegisters.rbp = u_reg->rbp;
+ m_gpRegisters.rsp = u_reg->rsp;
+
+ m_gpRegisters.rax = u_reg->rax;
+ m_gpRegisters.rbx = u_reg->rbx;
+ m_gpRegisters.rcx = u_reg->rcx;
+ m_gpRegisters.rdx = u_reg->rdx;
+ m_gpRegisters.rsi = u_reg->rsi;
+ m_gpRegisters.rdi = u_reg->rdi;
+
+ m_gpRegisters.cs = u_reg->cs;
+ m_gpRegisters.gs = u_reg->gs;
+ m_gpRegisters.es = u_reg->es;
+ m_gpRegisters.fs = u_reg->fs;
+ m_gpRegisters.ds = u_reg->ds;
+ m_gpRegisters.ss = u_reg->ss;
+ m_gpRegisters.fs_base = u_reg->fs_base;
+ m_gpRegisters.gs_base = u_reg->gs_base;
+
+ m_gpRegisters.orig_rax = u_reg->orig_rax;
+
+ m_gpRegisters.r8 = u_reg->r8;
+ m_gpRegisters.r9 = u_reg->r9;
+ m_gpRegisters.r10 = u_reg->r10;
+ m_gpRegisters.r11 = u_reg->r11;
+ m_gpRegisters.r12 = u_reg->r12;
+ m_gpRegisters.r13 = u_reg->r13;
+ m_gpRegisters.r14 = u_reg->r14;
+ m_gpRegisters.r15 = u_reg->r15;
+
+ m_gpRegisters.eflags = u_reg->eflags;
+#elif defined(__i386__)
+ struct user_regs_struct *u_reg = (struct user_regs_struct *)&prstatus->pr_reg;
+ m_gpRegisters.ebx = u_reg->ebx;
+ m_gpRegisters.ecx = u_reg->ecx;
+ m_gpRegisters.edx = u_reg->edx;
+ m_gpRegisters.esi = u_reg->esi;
+ m_gpRegisters.edi = u_reg->edi;
+ m_gpRegisters.ebp = u_reg->ebp;
+ m_gpRegisters.eax = u_reg->eax;
+ m_gpRegisters.xds = u_reg->xds;
+ m_gpRegisters.xes = u_reg->xes;
+ m_gpRegisters.xfs = u_reg->xfs;
+ m_gpRegisters.xgs = u_reg->xgs;
+ m_gpRegisters.orig_eax = u_reg->orig_eax;
+ m_gpRegisters.eip = u_reg->eip;
+ m_gpRegisters.xcs = u_reg->xcs;
+ m_gpRegisters.eflags = u_reg->eflags;
+ m_gpRegisters.esp = u_reg->esp;
+ m_gpRegisters.xss = u_reg->xss;
+#elif defined(__arm__)
+
+#define REGS_REGULAR_NUM 13
+#define REG_FP 11
+#define REG_IP 12
+#define REG_SP 13
+#define REG_LR 14
+#define REG_PC 15
+#define REG_SPSR 16
+ struct user_regs *u_reg = (struct user_regs *)&prstatus->pr_reg;
+ m_gpRegisters.ARM_sp = u_reg->uregs[REG_SP];
+ m_gpRegisters.ARM_lr = u_reg->uregs[REG_LR];
+ m_gpRegisters.ARM_pc = u_reg->uregs[REG_PC];
+ m_gpRegisters.ARM_cpsr = u_reg->uregs[REG_SPSR];
+
+ m_gpRegisters.ARM_r0 = u_reg->uregs[0];
+ m_gpRegisters.ARM_ORIG_r0 = u_reg->uregs[0];
+ m_gpRegisters.ARM_r1 = u_reg->uregs[1];
+ m_gpRegisters.ARM_r2 = u_reg->uregs[2];
+ m_gpRegisters.ARM_r3 = u_reg->uregs[3];
+ m_gpRegisters.ARM_r4 = u_reg->uregs[4];
+ m_gpRegisters.ARM_r5 = u_reg->uregs[5];
+ m_gpRegisters.ARM_r6 = u_reg->uregs[6];
+ m_gpRegisters.ARM_r7 = u_reg->uregs[7];
+ m_gpRegisters.ARM_r8 = u_reg->uregs[8];
+ m_gpRegisters.ARM_r9 = u_reg->uregs[9];
+ m_gpRegisters.ARM_r10 = u_reg->uregs[10];
+ m_gpRegisters.ARM_fp = u_reg->uregs[REG_FP];
+ m_gpRegisters.ARM_ip = u_reg->uregs[REG_IP];
+#elif defined(__aarch64__)
+ struct user_regs_struct *u_reg = (struct user_regs_struct *)&prstatus->pr_reg;
+ memcpy(m_gpRegisters.regs, u_reg, sizeof(m_gpRegisters.regs));
+ m_gpRegisters.sp = u_reg->sp;
+ m_gpRegisters.pc = u_reg->pc;
+ m_gpRegisters.pstate = u_reg->pstate;
+#elif defined(__riscv)
+ struct user_regs_struct *u_reg = (struct user_regs_struct *)&prstatus->pr_reg;
+ memcpy(&m_gpRegisters, u_reg, sizeof(m_gpRegisters));
+#endif
+}
diff --git a/src/coreclr/debug/createdump/threadinfo.h b/src/coreclr/debug/createdump/threadinfo.h
index d9f38a70f02..8d93fbe716e 100644
--- a/src/coreclr/debug/createdump/threadinfo.h
+++ b/src/coreclr/debug/createdump/threadinfo.h
@@ -112,6 +112,7 @@ public:
bool UnwindThread(IXCLRDataProcess* pClrDataProcess, ISOSDacInterface* pSos);
void GetThreadStack();
void GetThreadContext(uint32_t flags, CONTEXT* context) const;
+ void SetRegisters(elf_prstatus *prstatus);
inline pid_t Tid() const { return m_tid; }
inline pid_t Ppid() const { return m_ppid; }