Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Commit 22b6099

Browse files
committed
Merge pull request #1975 from mikem8361/sosfix
Fix sos clrstack unwinding for special HelperMethodFrame.
2 parents 4c3e266 + 2337ed9 commit 22b6099

File tree

24 files changed

+210
-92
lines changed

24 files changed

+210
-92
lines changed

src/ToolBox/SOS/Strike/datatarget.cpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -196,8 +196,14 @@ DataTarget::Request(
196196
}
197197

198198
HRESULT STDMETHODCALLTYPE
199-
DataTarget::GetPid(
200-
/* [out] */ DWORD *pdwProcessId)
199+
DataTarget::VirtualUnwind(
200+
/* [in] */ DWORD threadId,
201+
/* [in] */ ULONG32 contextSize,
202+
/* [in, out, size_is(contextSize)] */ PBYTE context)
201203
{
202-
return g_ExtSystem->GetCurrentProcessId(pdwProcessId);
204+
if (g_ExtClient == NULL)
205+
{
206+
return E_UNEXPECTED;
207+
}
208+
return g_ExtClient->VirtualUnwind(threadId, contextSize, context);
203209
}

src/ToolBox/SOS/Strike/datatarget.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,8 @@ class DataTarget : public ICLRDataTarget, ICorDebugDataTarget4
8585

8686
// ICorDebugDataTarget4
8787

88-
virtual HRESULT STDMETHODCALLTYPE GetPid(
89-
/* [out] */ DWORD *pdwProcessId);
88+
virtual HRESULT STDMETHODCALLTYPE VirtualUnwind(
89+
/* [in] */ DWORD threadId,
90+
/* [in] */ ULONG32 contextSize,
91+
/* [in, out, size_is(contextSize)] */ PBYTE context);
9092
};

src/ToolBox/SOS/Strike/strike.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6892,8 +6892,13 @@ HRESULT HandleCLRNotificationEvent()
68926892

68936893
if (!CheckCLRNotificationEvent(&dle))
68946894
{
6895+
#ifndef FEATURE_PAL
68956896
ExtOut("Expecting first chance CLRN exception\n");
68966897
return E_FAIL;
6898+
#else
6899+
g_ExtControl->Execute(DEBUG_EXECUTE_NOT_LOGGED, "process continue", 0);
6900+
return S_OK;
6901+
#endif
68976902
}
68986903

68996904
// Notification only needs to live for the lifetime of the call below, so it's a non-static

src/ToolBox/SOS/lldbplugin/debugclient.cpp

Lines changed: 83 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
#include <cstdlib>
88
#include "sosplugin.h"
99
#include <string.h>
10-
#include <dbgtargetcontext.h>
1110
#include <string>
1211

1312
ULONG g_currentThreadIndex = -1;
@@ -708,8 +707,8 @@ DebugClient::GetModuleDirectory(
708707
// Internal function
709708
ULONG64
710709
DebugClient::GetModuleBase(
711-
lldb::SBTarget target,
712-
lldb::SBModule module)
710+
/* const */ lldb::SBTarget& target,
711+
/* const */ lldb::SBModule& module)
713712
{
714713
// Find the first section with an valid base address
715714
int numSections = module.GetNumSections();
@@ -922,6 +921,19 @@ DebugClient::GetThreadContextById(
922921
dtcontext = (DT_CONTEXT*)context;
923922
dtcontext->ContextFlags = contextFlags;
924923

924+
GetContextFromFrame(frame, dtcontext);
925+
hr = S_OK;
926+
927+
exit:
928+
return hr;
929+
}
930+
931+
// Internal function
932+
void
933+
DebugClient::GetContextFromFrame(
934+
/* const */ lldb::SBFrame& frame,
935+
DT_CONTEXT *dtcontext)
936+
{
925937
#ifdef DBG_TARGET_AMD64
926938
dtcontext->Rip = frame.GetPC();
927939
dtcontext->Rsp = frame.GetSP();
@@ -969,29 +981,19 @@ DebugClient::GetThreadContextById(
969981
dtcontext->R11 = GetRegister(frame, "r11");
970982
dtcontext->R12 = GetRegister(frame, "r12");
971983
#endif
972-
973-
hr = S_OK;
974-
975-
exit:
976-
return hr;
977984
}
978985

979986
// Internal function
980987
DWORD_PTR
981-
DebugClient::GetRegister(lldb::SBFrame frame, const char *name)
988+
DebugClient::GetRegister(
989+
/* const */ lldb::SBFrame& frame,
990+
const char *name)
982991
{
983992
lldb::SBValue regValue = frame.FindRegister(name);
984993

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

988-
#ifdef _DEBUG
989-
if (!regValue.IsValid() || error.Fail())
990-
{
991-
Output(DEBUG_OUTPUT_ERROR, "Invalid register name '%s'\n", name);
992-
}
993-
#endif
994-
995997
return result;
996998
}
997999

@@ -1115,7 +1117,7 @@ DebugClient::GetExpression(
11151117
// Internal function
11161118
DWORD_PTR
11171119
DebugClient::GetExpression(
1118-
lldb::SBFrame frame,
1120+
/* const */ lldb::SBFrame& frame,
11191121
lldb::SBError& error,
11201122
PCSTR exp)
11211123
{
@@ -1130,6 +1132,70 @@ DebugClient::GetExpression(
11301132
return result;
11311133
}
11321134

1135+
HRESULT
1136+
DebugClient::VirtualUnwind(
1137+
DWORD threadID,
1138+
ULONG32 contextSize,
1139+
PBYTE context)
1140+
{
1141+
lldb::SBProcess process;
1142+
lldb::SBThread thread;
1143+
1144+
if (context == NULL || contextSize < sizeof(DT_CONTEXT))
1145+
{
1146+
return E_FAIL;
1147+
}
1148+
1149+
process = GetCurrentProcess();
1150+
if (!process.IsValid())
1151+
{
1152+
return E_FAIL;
1153+
}
1154+
1155+
thread = process.GetThreadByID(threadID);
1156+
if (!thread.IsValid())
1157+
{
1158+
return E_FAIL;
1159+
}
1160+
1161+
DT_CONTEXT *dtcontext = (DT_CONTEXT*)context;
1162+
lldb::SBFrame frameFound;
1163+
1164+
#ifdef DBG_TARGET_AMD64
1165+
DWORD64 spToFind = dtcontext->Rsp;
1166+
#elif DBG_TARGET_ARM
1167+
DWORD spToFind = dtcontext->Sp;
1168+
#endif
1169+
1170+
int numFrames = thread.GetNumFrames();
1171+
for (int i = 0; i < numFrames; i++)
1172+
{
1173+
lldb::SBFrame frame = thread.GetFrameAtIndex(i);
1174+
if (!frame.IsValid())
1175+
{
1176+
break;
1177+
}
1178+
1179+
lldb::addr_t sp = frame.GetSP();
1180+
1181+
if (sp == spToFind && (i + 1) < numFrames)
1182+
{
1183+
// Get next frame after finding the match
1184+
frameFound = thread.GetFrameAtIndex(i + 1);
1185+
break;
1186+
}
1187+
}
1188+
1189+
if (!frameFound.IsValid())
1190+
{
1191+
return E_FAIL;
1192+
}
1193+
1194+
GetContextFromFrame(frameFound, dtcontext);
1195+
1196+
return S_OK;
1197+
}
1198+
11331199
//----------------------------------------------------------------------------
11341200
// Helper functions
11351201
//----------------------------------------------------------------------------

src/ToolBox/SOS/lldbplugin/debugclient.h

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,10 @@ class DebugClient : public IDebugClient
1313
lldb::SBProcess GetCurrentProcess();
1414
lldb::SBThread GetCurrentThread();
1515
lldb::SBFrame GetCurrentFrame();
16-
ULONG64 GetModuleBase(lldb::SBTarget target, lldb::SBModule module);
17-
DWORD_PTR GetExpression(lldb::SBFrame frame, lldb::SBError& error, PCSTR exp);
18-
DWORD_PTR GetRegister(lldb::SBFrame frame, const char *name);
16+
ULONG64 GetModuleBase(lldb::SBTarget& target, lldb::SBModule& module);
17+
DWORD_PTR GetExpression(lldb::SBFrame& frame, lldb::SBError& error, PCSTR exp);
18+
void GetContextFromFrame(lldb::SBFrame& frame, DT_CONTEXT *dtcontext);
19+
DWORD_PTR GetRegister(lldb::SBFrame& frame, const char *name);
1920

2021
public:
2122
DebugClient(lldb::SBDebugger &debugger, lldb::SBCommandReturnObject &returnObject);
@@ -192,4 +193,9 @@ class DebugClient : public IDebugClient
192193

193194
DWORD_PTR GetExpression(
194195
PCSTR exp);
196+
197+
HRESULT VirtualUnwind(
198+
DWORD threadID,
199+
ULONG32 contextSize,
200+
PBYTE context);
195201
};

src/ToolBox/SOS/lldbplugin/inc/dbgeng.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -457,6 +457,11 @@ class IDebugClient : IDebugControl2, IDebugDataSpaces, IDebugSymbols, IDebugSyst
457457
// Evaluates a lldb expression into a value.
458458
virtual DWORD_PTR GetExpression(
459459
/* [in] */ PCSTR exp) = 0;
460+
461+
virtual HRESULT VirtualUnwind(
462+
/* [in] */ DWORD threadID,
463+
/* [in] */ ULONG32 contextSize,
464+
/* [in, out, size_is(contextSize)] */ PBYTE context) = 0;
460465
};
461466

462467
typedef class IDebugClient* PDEBUG_CLIENT;

src/ToolBox/SOS/lldbplugin/sosplugin.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include "mstypes.h"
88
#define DEFINE_EXCEPTION_RECORD
99
#include <dbgeng.h>
10+
#include <dbgtargetcontext.h>
1011
#include "debugclient.h"
1112

1213
typedef HRESULT (*CommandFunc)(PDEBUG_CLIENT client, const char *args);

src/debug/daccess/dacfn.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -218,24 +218,32 @@ DacWriteAll(TADDR addr, PVOID buffer, ULONG32 size, bool throwEx)
218218
return S_OK;
219219
}
220220

221+
#if defined(WIN64EXCEPTIONS) && defined(FEATURE_PAL)
221222
HRESULT
222-
DacGetPid(DWORD *pid)
223+
DacVirtualUnwind(DWORD threadId, PCONTEXT context, PT_KNONVOLATILE_CONTEXT_POINTERS contextPointers)
223224
{
224225
if (!g_dacImpl)
225226
{
226227
DacError(E_UNEXPECTED);
227228
UNREACHABLE();
228229
}
229230

231+
// The DAC code doesn't use these context pointers but zero them out to be safe.
232+
if (contextPointers != NULL)
233+
{
234+
memset(contextPointers, 0, sizeof(T_KNONVOLATILE_CONTEXT_POINTERS));
235+
}
236+
230237
ReleaseHolder<ICorDebugDataTarget4> dt;
231238
HRESULT hr = g_dacImpl->m_pTarget->QueryInterface(IID_ICorDebugDataTarget4, (void **)&dt);
232239
if (SUCCEEDED(hr))
233240
{
234-
hr = dt->GetPid(pid);
241+
hr = dt->VirtualUnwind(threadId, sizeof(CONTEXT), (BYTE*)context);
235242
}
236243

237244
return hr;
238245
}
246+
#endif // defined(WIN64EXCEPTIONS) && defined(FEATURE_PAL)
239247

240248
// DacAllocVirtual - Allocate memory from the target process
241249
// Note: this is only available to clients supporting the legacy

src/debug/di/shimdatatarget.cpp

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -68,22 +68,30 @@ ULONG STDMETHODCALLTYPE ShimDataTarget::Release()
6868
return ref;
6969
}
7070

71-
7271
//---------------------------------------------------------------------------------------
7372
//
7473
// Get the OS Process ID that this DataTarget is for.
7574
//
7675
// Return Value:
7776
// The OS PID of the process this data target is representing.
78-
HRESULT STDMETHODCALLTYPE ShimDataTarget::GetPid(DWORD *pdwProcessId)
77+
DWORD ShimDataTarget::GetPid()
7978
{
80-
if (pdwProcessId == NULL)
81-
{
82-
return E_INVALIDARG;
83-
}
79+
return m_processId;
80+
}
8481

85-
*pdwProcessId = m_processId;
86-
return S_OK;
82+
//---------------------------------------------------------------------------------------
83+
//
84+
// Unwind the stack to the next frame.
85+
//
86+
// Return Value:
87+
// context and contextPointers filled in with the next frame
88+
//
89+
HRESULT STDMETHODCALLTYPE ShimDataTarget::VirtualUnwind(DWORD threadId, ULONG32 contextSize, PBYTE context)
90+
{
91+
#ifndef FEATURE_PAL
92+
_ASSERTE(!"ShimDataTarget::VirtualUnwind NOT IMPLEMENTED");
93+
#endif
94+
return E_NOTIMPL;
8795
}
8896

8997
//---------------------------------------------------------------------------------------

src/debug/di/shimdatatarget.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ class ShimDataTarget : public ICorDebugMutableDataTarget, ICorDebugDataTarget4
3636
// is unavailable because it's running
3737
void SetError(HRESULT hr);
3838

39+
// Get the OS Process ID that this DataTarget is for.
40+
DWORD GetPid();
41+
3942
//
4043
// IUnknown.
4144
//
@@ -86,8 +89,8 @@ class ShimDataTarget : public ICorDebugMutableDataTarget, ICorDebugDataTarget4
8689
// ICorDebugDataTarget4
8790
//
8891

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

9295
protected:
9396
// Pid of the target process.

0 commit comments

Comments
 (0)