summaryrefslogtreecommitdiff
path: root/src/debug/createdump/threadinfo.cpp
diff options
context:
space:
mode:
authorMike McLaughlin <mikem@microsoft.com>2017-04-24 17:12:36 -0700
committerGitHub <noreply@github.com>2017-04-24 17:12:36 -0700
commitc53fa592ba54c0f346856d680cc30348850eba83 (patch)
tree060149803ed42df869a145039114ca03ba60760c /src/debug/createdump/threadinfo.cpp
parent3712f59c73f00d3312e62f9440c7f03fc7d458e7 (diff)
downloadcoreclr-c53fa592ba54c0f346856d680cc30348850eba83.tar.gz
coreclr-c53fa592ba54c0f346856d680cc30348850eba83.tar.bz2
coreclr-c53fa592ba54c0f346856d680cc30348850eba83.zip
Add "createdump" command to SOS. (#11161)
Uses the createdump utility code as a library. Changed the "-m, --micro" option to "-t, --triage". Lots of cleanup.
Diffstat (limited to 'src/debug/createdump/threadinfo.cpp')
-rw-r--r--src/debug/createdump/threadinfo.cpp99
1 files changed, 90 insertions, 9 deletions
diff --git a/src/debug/createdump/threadinfo.cpp b/src/debug/createdump/threadinfo.cpp
index 52af060b89..8e73fcf2cb 100644
--- a/src/debug/createdump/threadinfo.cpp
+++ b/src/debug/createdump/threadinfo.cpp
@@ -4,6 +4,11 @@
#include "createdump.h"
+#define FPREG_ErrorOffset(fpregs) *(DWORD*)&((fpregs).rip)
+#define FPREG_ErrorSelector(fpregs) *(((WORD*)&((fpregs).rip)) + 2)
+#define FPREG_DataOffset(fpregs) *(DWORD*)&((fpregs).rdp)
+#define FPREG_DataSelector(fpregs) *(((WORD*)&((fpregs).rdp)) + 2)
+
ThreadInfo::ThreadInfo(pid_t tid) :
m_tid(tid)
{
@@ -14,15 +19,24 @@ ThreadInfo::~ThreadInfo()
}
bool
-ThreadInfo::Initialize()
+ThreadInfo::Initialize(ICLRDataTarget* dataTarget)
{
if (!CrashInfo::GetStatus(m_tid, &m_ppid, &m_tgid, nullptr))
{
return false;
}
- if (!GetRegisters())
+ if (dataTarget != nullptr)
{
- return false;
+ if (!GetRegistersWithDataTarget(dataTarget))
+ {
+ return false;
+ }
+ }
+ else {
+ if (!GetRegistersWithPTrace())
+ {
+ return false;
+ }
}
TRACE("Thread %04x RIP %016llx RSP %016llx\n", m_tid, m_gpRegisters.rip, m_gpRegisters.rsp);
return true;
@@ -39,7 +53,7 @@ ThreadInfo::ResumeThread()
}
bool
-ThreadInfo::GetRegisters()
+ThreadInfo::GetRegistersWithPTrace()
{
if (ptrace((__ptrace_request)PTRACE_GETREGS, m_tid, nullptr, &m_gpRegisters) == -1)
{
@@ -61,6 +75,70 @@ ThreadInfo::GetRegisters()
return true;
}
+bool
+ThreadInfo::GetRegistersWithDataTarget(ICLRDataTarget* dataTarget)
+{
+ CONTEXT context;
+ context.ContextFlags = CONTEXT_ALL;
+ if (dataTarget->GetThreadContext(m_tid, context.ContextFlags, sizeof(context), reinterpret_cast<PBYTE>(&context)) != S_OK)
+ {
+ return false;
+ }
+#if defined(__x86_64__)
+ m_gpRegisters.rbp = context.Rbp;
+ m_gpRegisters.rip = context.Rip;
+ m_gpRegisters.cs = context.SegCs;
+ m_gpRegisters.eflags = context.EFlags;
+ m_gpRegisters.ss = context.SegSs;
+ m_gpRegisters.rsp = context.Rsp;
+ m_gpRegisters.rdi = context.Rdi;
+
+ m_gpRegisters.rsi = context.Rsi;
+ m_gpRegisters.rbx = context.Rbx;
+ m_gpRegisters.rdx = context.Rdx;
+ m_gpRegisters.rcx = context.Rcx;
+ m_gpRegisters.rax = context.Rax;
+ m_gpRegisters.orig_rax = context.Rax;
+ m_gpRegisters.r8 = context.R8;
+ m_gpRegisters.r9 = context.R9;
+ m_gpRegisters.r10 = context.R10;
+ m_gpRegisters.r11 = context.R11;
+ m_gpRegisters.r12 = context.R12;
+ m_gpRegisters.r13 = context.R13;
+ m_gpRegisters.r14 = context.R14;
+ m_gpRegisters.r15 = context.R15;
+
+ m_gpRegisters.ds = context.SegDs;
+ m_gpRegisters.es = context.SegEs;
+ m_gpRegisters.fs = context.SegFs;
+ m_gpRegisters.gs = context.SegGs;
+ m_gpRegisters.fs_base = 0;
+ m_gpRegisters.gs_base = 0;
+
+ m_fpRegisters.cwd = context.FltSave.ControlWord;
+ m_fpRegisters.swd = context.FltSave.StatusWord;
+ m_fpRegisters.ftw = context.FltSave.TagWord;
+ m_fpRegisters.fop = context.FltSave.ErrorOpcode;
+
+ FPREG_ErrorOffset(m_fpRegisters) = context.FltSave.ErrorOffset;
+ FPREG_ErrorSelector(m_fpRegisters) = context.FltSave.ErrorSelector;
+ FPREG_DataOffset(m_fpRegisters) = context.FltSave.DataOffset;
+ FPREG_DataSelector(m_fpRegisters) = context.FltSave.DataSelector;
+
+ m_fpRegisters.mxcsr = context.FltSave.MxCsr;
+ m_fpRegisters.mxcr_mask = context.FltSave.MxCsr_Mask;
+
+ assert(sizeof(context.FltSave.FloatRegisters) == sizeof(m_fpRegisters.st_space));
+ memcpy(m_fpRegisters.st_space, context.FltSave.FloatRegisters, sizeof(m_fpRegisters.st_space));
+
+ assert(sizeof(context.FltSave.XmmRegisters) == sizeof(m_fpRegisters.xmm_space));
+ memcpy(m_fpRegisters.xmm_space, context.FltSave.XmmRegisters, sizeof(m_fpRegisters.xmm_space));
+#else
+#error Platform not supported
+#endif
+ return true;
+}
+
void
ThreadInfo::GetThreadStack(const CrashInfo& crashInfo, uint64_t* startAddress, size_t* size) const
{
@@ -95,6 +173,7 @@ void
ThreadInfo::GetThreadContext(uint32_t flags, CONTEXT* context) const
{
context->ContextFlags = flags;
+#if defined(__x86_64__)
if ((flags & CONTEXT_CONTROL) == CONTEXT_CONTROL)
{
context->Rbp = m_gpRegisters.rbp;
@@ -135,10 +214,10 @@ ThreadInfo::GetThreadContext(uint32_t flags, CONTEXT* context) const
context->FltSave.TagWord = m_fpRegisters.ftw;
context->FltSave.ErrorOpcode = m_fpRegisters.fop;
- context->FltSave.ErrorOffset = (DWORD)m_fpRegisters.rip;
- context->FltSave.ErrorSelector = *(((WORD *)&m_fpRegisters.rip) + 2);
- context->FltSave.DataOffset = (DWORD)m_fpRegisters.rdp;
- context->FltSave.DataSelector = *(((WORD *)&m_fpRegisters.rdp) + 2);
+ context->FltSave.ErrorOffset = FPREG_ErrorOffset(m_fpRegisters);
+ context->FltSave.ErrorSelector = FPREG_ErrorSelector(m_fpRegisters);
+ context->FltSave.DataOffset = FPREG_DataOffset(m_fpRegisters);
+ context->FltSave.DataSelector = FPREG_DataSelector(m_fpRegisters);
context->FltSave.MxCsr = m_fpRegisters.mxcsr;
context->FltSave.MxCsr_Mask = m_fpRegisters.mxcr_mask;
@@ -150,5 +229,7 @@ ThreadInfo::GetThreadContext(uint32_t flags, CONTEXT* context) const
memcpy(context->FltSave.XmmRegisters, m_fpRegisters.xmm_space, sizeof(context->FltSave.XmmRegisters));
}
// TODO: debug registers?
- // TODO: x86 registers
+#else
+#error Platform not supported
+#endif
}