Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 9 additions & 3 deletions src/ToolBox/SOS/Strike/datatarget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -196,8 +196,14 @@ DataTarget::Request(
}

HRESULT STDMETHODCALLTYPE
DataTarget::GetPid(
/* [out] */ DWORD *pdwProcessId)
DataTarget::VirtualUnwind(
/* [in] */ DWORD threadId,
/* [in] */ ULONG32 contextSize,
/* [in, out, size_is(contextSize)] */ PBYTE context)
{
return g_ExtSystem->GetCurrentProcessId(pdwProcessId);
if (g_ExtClient == NULL)
{
return E_UNEXPECTED;
}
return g_ExtClient->VirtualUnwind(threadId, contextSize, context);
}
6 changes: 4 additions & 2 deletions src/ToolBox/SOS/Strike/datatarget.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@ class DataTarget : public ICLRDataTarget, ICorDebugDataTarget4

// ICorDebugDataTarget4

virtual HRESULT STDMETHODCALLTYPE GetPid(
/* [out] */ DWORD *pdwProcessId);
virtual HRESULT STDMETHODCALLTYPE VirtualUnwind(
/* [in] */ DWORD threadId,
/* [in] */ ULONG32 contextSize,
/* [in, out, size_is(contextSize)] */ PBYTE context);
};
5 changes: 5 additions & 0 deletions src/ToolBox/SOS/Strike/strike.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6892,8 +6892,13 @@ HRESULT HandleCLRNotificationEvent()

if (!CheckCLRNotificationEvent(&dle))
{
#ifndef FEATURE_PAL
ExtOut("Expecting first chance CLRN exception\n");
return E_FAIL;
#else
g_ExtControl->Execute(DEBUG_EXECUTE_NOT_LOGGED, "process continue", 0);
return S_OK;
#endif
}

// Notification only needs to live for the lifetime of the call below, so it's a non-static
Expand Down
100 changes: 83 additions & 17 deletions src/ToolBox/SOS/lldbplugin/debugclient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
#include <cstdlib>
#include "sosplugin.h"
#include <string.h>
#include <dbgtargetcontext.h>
#include <string>

ULONG g_currentThreadIndex = -1;
Expand Down Expand Up @@ -708,8 +707,8 @@ DebugClient::GetModuleDirectory(
// Internal function
ULONG64
DebugClient::GetModuleBase(
lldb::SBTarget target,
lldb::SBModule module)
/* const */ lldb::SBTarget& target,
/* const */ lldb::SBModule& module)
{
// Find the first section with an valid base address
int numSections = module.GetNumSections();
Expand Down Expand Up @@ -922,6 +921,19 @@ DebugClient::GetThreadContextById(
dtcontext = (DT_CONTEXT*)context;
dtcontext->ContextFlags = contextFlags;

GetContextFromFrame(frame, dtcontext);
hr = S_OK;

exit:
return hr;
}

// Internal function
void
DebugClient::GetContextFromFrame(
/* const */ lldb::SBFrame& frame,
DT_CONTEXT *dtcontext)
{
#ifdef DBG_TARGET_AMD64
dtcontext->Rip = frame.GetPC();
dtcontext->Rsp = frame.GetSP();
Expand Down Expand Up @@ -969,29 +981,19 @@ DebugClient::GetThreadContextById(
dtcontext->R11 = GetRegister(frame, "r11");
dtcontext->R12 = GetRegister(frame, "r12");
#endif

hr = S_OK;

exit:
return hr;
}

// Internal function
DWORD_PTR
DebugClient::GetRegister(lldb::SBFrame frame, const char *name)
DebugClient::GetRegister(
/* const */ lldb::SBFrame& frame,
const char *name)
{
lldb::SBValue regValue = frame.FindRegister(name);

lldb::SBError error;
DWORD_PTR result = regValue.GetValueAsUnsigned(error);

#ifdef _DEBUG
if (!regValue.IsValid() || error.Fail())
{
Output(DEBUG_OUTPUT_ERROR, "Invalid register name '%s'\n", name);
}
#endif

return result;
}

Expand Down Expand Up @@ -1115,7 +1117,7 @@ DebugClient::GetExpression(
// Internal function
DWORD_PTR
DebugClient::GetExpression(
lldb::SBFrame frame,
/* const */ lldb::SBFrame& frame,
lldb::SBError& error,
PCSTR exp)
{
Expand All @@ -1130,6 +1132,70 @@ DebugClient::GetExpression(
return result;
}

HRESULT
DebugClient::VirtualUnwind(
DWORD threadID,
ULONG32 contextSize,
PBYTE context)
{
lldb::SBProcess process;
lldb::SBThread thread;

if (context == NULL || contextSize < sizeof(DT_CONTEXT))
{
return E_FAIL;
}

process = GetCurrentProcess();
if (!process.IsValid())
{
return E_FAIL;
}

thread = process.GetThreadByID(threadID);
if (!thread.IsValid())
{
return E_FAIL;
}

DT_CONTEXT *dtcontext = (DT_CONTEXT*)context;
lldb::SBFrame frameFound;

#ifdef DBG_TARGET_AMD64
DWORD64 spToFind = dtcontext->Rsp;
#elif DBG_TARGET_ARM
DWORD spToFind = dtcontext->Sp;
#endif

int numFrames = thread.GetNumFrames();
for (int i = 0; i < numFrames; i++)
{
lldb::SBFrame frame = thread.GetFrameAtIndex(i);
if (!frame.IsValid())
{
break;
}

lldb::addr_t sp = frame.GetSP();

if (sp == spToFind && (i + 1) < numFrames)
{
// Get next frame after finding the match
frameFound = thread.GetFrameAtIndex(i + 1);
break;
}
}

if (!frameFound.IsValid())
{
return E_FAIL;
}

GetContextFromFrame(frameFound, dtcontext);

return S_OK;
}

//----------------------------------------------------------------------------
// Helper functions
//----------------------------------------------------------------------------
Expand Down
12 changes: 9 additions & 3 deletions src/ToolBox/SOS/lldbplugin/debugclient.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,10 @@ class DebugClient : public IDebugClient
lldb::SBProcess GetCurrentProcess();
lldb::SBThread GetCurrentThread();
lldb::SBFrame GetCurrentFrame();
ULONG64 GetModuleBase(lldb::SBTarget target, lldb::SBModule module);
DWORD_PTR GetExpression(lldb::SBFrame frame, lldb::SBError& error, PCSTR exp);
DWORD_PTR GetRegister(lldb::SBFrame frame, const char *name);
ULONG64 GetModuleBase(lldb::SBTarget& target, lldb::SBModule& module);
DWORD_PTR GetExpression(lldb::SBFrame& frame, lldb::SBError& error, PCSTR exp);
void GetContextFromFrame(lldb::SBFrame& frame, DT_CONTEXT *dtcontext);
DWORD_PTR GetRegister(lldb::SBFrame& frame, const char *name);

public:
DebugClient(lldb::SBDebugger &debugger, lldb::SBCommandReturnObject &returnObject);
Expand Down Expand Up @@ -192,4 +193,9 @@ class DebugClient : public IDebugClient

DWORD_PTR GetExpression(
PCSTR exp);

HRESULT VirtualUnwind(
DWORD threadID,
ULONG32 contextSize,
PBYTE context);
};
5 changes: 5 additions & 0 deletions src/ToolBox/SOS/lldbplugin/inc/dbgeng.h
Original file line number Diff line number Diff line change
Expand Up @@ -457,6 +457,11 @@ class IDebugClient : IDebugControl2, IDebugDataSpaces, IDebugSymbols, IDebugSyst
// Evaluates a lldb expression into a value.
virtual DWORD_PTR GetExpression(
/* [in] */ PCSTR exp) = 0;

virtual HRESULT VirtualUnwind(
/* [in] */ DWORD threadID,
/* [in] */ ULONG32 contextSize,
/* [in, out, size_is(contextSize)] */ PBYTE context) = 0;
};

typedef class IDebugClient* PDEBUG_CLIENT;
Expand Down
1 change: 1 addition & 0 deletions src/ToolBox/SOS/lldbplugin/sosplugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include "mstypes.h"
#define DEFINE_EXCEPTION_RECORD
#include <dbgeng.h>
#include <dbgtargetcontext.h>
#include "debugclient.h"

typedef HRESULT (*CommandFunc)(PDEBUG_CLIENT client, const char *args);
Expand Down
10 changes: 8 additions & 2 deletions src/debug/daccess/dacfn.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -219,19 +219,25 @@ DacWriteAll(TADDR addr, PVOID buffer, ULONG32 size, bool throwEx)
}

HRESULT
DacGetPid(DWORD *pid)
DacVirtualUnwind(DWORD threadId, CONTEXT *context, KNONVOLATILE_CONTEXT_POINTERS *contextPointers)
{
if (!g_dacImpl)
{
DacError(E_UNEXPECTED);
UNREACHABLE();
}

// The DAC code doesn't use these context pointers but zero them out to be safe.
if (contextPointers != NULL)
{
memset(contextPointers, 0, sizeof(KNONVOLATILE_CONTEXT_POINTERS));
}

ReleaseHolder<ICorDebugDataTarget4> dt;
HRESULT hr = g_dacImpl->m_pTarget->QueryInterface(IID_ICorDebugDataTarget4, (void **)&dt);
if (SUCCEEDED(hr))
{
hr = dt->GetPid(pid);
hr = dt->VirtualUnwind(threadId, sizeof(CONTEXT), (BYTE*)context);
}

return hr;
Expand Down
24 changes: 16 additions & 8 deletions src/debug/di/shimdatatarget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,22 +68,30 @@ ULONG STDMETHODCALLTYPE ShimDataTarget::Release()
return ref;
}


//---------------------------------------------------------------------------------------
//
// Get the OS Process ID that this DataTarget is for.
//
// Return Value:
// The OS PID of the process this data target is representing.
HRESULT STDMETHODCALLTYPE ShimDataTarget::GetPid(DWORD *pdwProcessId)
DWORD ShimDataTarget::GetPid()
{
if (pdwProcessId == NULL)
{
return E_INVALIDARG;
}
return m_processId;
}

*pdwProcessId = m_processId;
return S_OK;
//---------------------------------------------------------------------------------------
//
// Unwind the stack to the next frame.
//
// Return Value:
// context and contextPointers filled in with the next frame
//
HRESULT STDMETHODCALLTYPE ShimDataTarget::VirtualUnwind(DWORD threadId, ULONG32 contextSize, PBYTE context)
{
#ifndef FEATURE_PAL
_ASSERTE(!"ShimDataTarget::VirtualUnwind NOT IMPLEMENTED");
#endif
return E_NOTIMPL;
}

//---------------------------------------------------------------------------------------
Expand Down
7 changes: 5 additions & 2 deletions src/debug/di/shimdatatarget.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ class ShimDataTarget : public ICorDebugMutableDataTarget, ICorDebugDataTarget4
// is unavailable because it's running
void SetError(HRESULT hr);

// Get the OS Process ID that this DataTarget is for.
DWORD GetPid();

//
// IUnknown.
//
Expand Down Expand Up @@ -86,8 +89,8 @@ class ShimDataTarget : public ICorDebugMutableDataTarget, ICorDebugDataTarget4
// ICorDebugDataTarget4
//

// Get the OS Process ID that this DataTarget is for.
virtual HRESULT STDMETHODCALLTYPE GetPid(DWORD *pdwProcessId);
// Unwind to the next stack frame
virtual HRESULT STDMETHODCALLTYPE VirtualUnwind(DWORD threadId, ULONG32 contextSize, PBYTE context);

protected:
// Pid of the target process.
Expand Down
18 changes: 5 additions & 13 deletions src/debug/di/shimprocess.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -133,9 +133,7 @@ void ShimProcess::SetProcess(ICorDebugProcess * pProcess)
if (pProcess != NULL)
{
// Verify that DataTarget + new process have the same pid?
DWORD pid = 0;
_ASSERTE(SUCCEEDED(m_pLiveDataTarget->GetPid(&pid)));
_ASSERTE(m_pProcess->GetPid() == pid);
_ASSERTE(m_pProcess->GetPid() == m_pLiveDataTarget->GetPid());
}
}

Expand Down Expand Up @@ -740,11 +738,8 @@ HRESULT ShimProcess::HandleWin32DebugEvent(const DEBUG_EVENT * pEvent)
// This assert could be our only warning of various catastrophic failures in the left-side.
if (!dwFirstChance && (pRecord->ExceptionCode == STATUS_BREAKPOINT) && !m_fIsInteropDebugging)
{
DWORD pid = 0;
if (m_pLiveDataTarget != NULL)
{
m_pLiveDataTarget->GetPid(&pid);
}
DWORD pid = (m_pLiveDataTarget == NULL) ? 0 : m_pLiveDataTarget->GetPid();

CONSISTENCY_CHECK_MSGF(false,
("Unhandled breakpoint exception in debuggee (pid=%d (0x%x)) on thread %d(0x%x)\n"
"This may mean there was an assert in the debuggee on that thread.\n"
Expand Down Expand Up @@ -1748,11 +1743,8 @@ void ShimProcess::PreDispatchEvent(bool fRealCreateProcessEvent /*= false*/)
CORDB_ADDRESS ShimProcess::GetCLRInstanceBaseAddress()
{
CORDB_ADDRESS baseAddress = CORDB_ADDRESS(NULL);
DWORD dwPid = 0;
if (FAILED(m_pLiveDataTarget->GetPid(&dwPid)))
{
return baseAddress;
}
DWORD dwPid = m_pLiveDataTarget->GetPid();

#if defined(FEATURE_CORESYSTEM)
// Debugger attaching to CoreCLR via CoreCLRCreateCordbObject should have already specified CLR module address.
// Code that help to find it now lives in dbgshim.
Expand Down
8 changes: 5 additions & 3 deletions src/inc/cordebug.idl
Original file line number Diff line number Diff line change
Expand Up @@ -823,9 +823,11 @@ interface ICorDebugDataTarget3 : IUnknown
interface ICorDebugDataTarget4 : IUnknown
{
/*
* gives back a process id
*/
HRESULT GetPid([out] DWORD *pdwProcessId);
* Unwinds one native stack frame in the target process/thread
*/
HRESULT VirtualUnwind([in] DWORD threadId,
[in] ULONG32 contextSize,
[in, out, size_is(contextSize)] BYTE *context);
};

/*
Expand Down
2 changes: 1 addition & 1 deletion src/inc/daccess.h
Original file line number Diff line number Diff line change
Expand Up @@ -663,7 +663,7 @@ HRESULT DacFreeVirtual(TADDR mem, ULONG32 size, ULONG32 typeFlags,
PVOID DacInstantiateTypeByAddress(TADDR addr, ULONG32 size, bool throwEx);
PVOID DacInstantiateTypeByAddressNoReport(TADDR addr, ULONG32 size, bool throwEx);
PVOID DacInstantiateClassByVTable(TADDR addr, ULONG32 minSize, bool throwEx);
HRESULT DacGetPid(DWORD *pid);
HRESULT DacVirtualUnwind(ULONG32 threadId, CONTEXT *context, KNONVOLATILE_CONTEXT_POINTERS *contextPointers);

// Copy a null-terminated ascii or unicode string from the target to the host.
// Note that most of the work here is to find the null terminator. If you know the exact length,
Expand Down
Loading