Skip to content

Commit

Permalink
Fix stack trace population to get proper source/line info for tier 1 …
Browse files Browse the repository at this point in the history
  • Loading branch information
kouvel committed Feb 9, 2018
1 parent 368bc34 commit d663e0b
Show file tree
Hide file tree
Showing 10 changed files with 150 additions and 15 deletions.
38 changes: 27 additions & 11 deletions src/debug/ee/debugger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14138,6 +14138,9 @@ bool Debugger::GetILOffsetFromNative (MethodDesc *pFunc, const BYTE *pbAddr,
}
CONTRACTL_END;

_ASSERTE(pFunc != NULL);
_ASSERTE(pbAddr != NULL);

if (!HasLazyData())
{
DebuggerLockHolder dbgLockHolder(this);
Expand All @@ -14151,23 +14154,36 @@ bool Debugger::GetILOffsetFromNative (MethodDesc *pFunc, const BYTE *pbAddr,
pFunc = pFunc->GetWrappedMethodDesc();
}

DebuggerJitInfo *jitInfo =
GetJitInfo(pFunc, (const BYTE *)pbAddr);
if (pFunc->IsDynamicMethod())
{
return false;
}

if (jitInfo != NULL)
DebuggerMethodInfo *methodInfo = GetOrCreateMethodInfo(pFunc->GetModule(), pFunc->GetMemberDef());
if (methodInfo == NULL)
{
CorDebugMappingResult map;
DWORD whichIDontCare;
return false;
}

*ilOffset = jitInfo->MapNativeOffsetToIL(
nativeOffset,
&map,
&whichIDontCare);
PCODE methodStartAddress = g_pEEInterface->GetNativeCodeStartAddress((PCODE)pbAddr);
if (methodStartAddress == NULL)
{
return false;
}

return true;
DebuggerJitInfo *jitInfo = methodInfo->FindOrCreateInitAndAddJitInfo(pFunc, methodStartAddress);
if (jitInfo == NULL)
{
return false;
}

return false;
CorDebugMappingResult map;
DWORD whichIDontCare;
*ilOffset = jitInfo->MapNativeOffsetToIL(
nativeOffset,
&map,
&whichIDontCare);
return true;
}

/******************************************************************************
Expand Down
2 changes: 1 addition & 1 deletion src/debug/ee/debugger.h
Original file line number Diff line number Diff line change
Expand Up @@ -1010,7 +1010,7 @@ class DebuggerMethodInfo
DebuggerJitInfo * FindJitInfo(MethodDesc * pMD, TADDR addrNativeStartAddr);

// Creating the Jit-infos.
DebuggerJitInfo *FindOrCreateInitAndAddJitInfo(MethodDesc* fd, TADDR startAddr);
DebuggerJitInfo *FindOrCreateInitAndAddJitInfo(MethodDesc* fd, PCODE startAddr);
DebuggerJitInfo *CreateInitAndAddJitInfo(MethodDesc* fd, TADDR startAddr, BOOL* jitInfoWasCreated);


Expand Down
6 changes: 3 additions & 3 deletions src/debug/ee/functioninfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1548,7 +1548,7 @@ DebuggerJitInfo * DebuggerMethodInfo::FindJitInfo(MethodDesc * pMD,
*
*/

DebuggerJitInfo *DebuggerMethodInfo::FindOrCreateInitAndAddJitInfo(MethodDesc* fd, TADDR startAddr)
DebuggerJitInfo *DebuggerMethodInfo::FindOrCreateInitAndAddJitInfo(MethodDesc* fd, PCODE startAddr)
{
CONTRACTL
{
Expand All @@ -1569,15 +1569,15 @@ DebuggerJitInfo *DebuggerMethodInfo::FindOrCreateInitAndAddJitInfo(MethodDesc* f
if (startAddr == NULL)
{
// This will grab the start address for the current code version.
startAddr = (TADDR)g_pEEInterface->GetFunctionAddress(fd);
startAddr = g_pEEInterface->GetFunctionAddress(fd);
if (startAddr == NULL)
{
return NULL;
}
}
else
{
_ASSERTE(g_pEEInterface->GetNativeCodeMethodDesc((PCODE)startAddr) == fd);
_ASSERTE(g_pEEInterface->GetNativeCodeMethodDesc(startAddr) == fd);
}

// Check the lsit to see if we've already populated an entry for this JitInfo.
Expand Down
13 changes: 13 additions & 0 deletions src/vm/codeman.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4156,6 +4156,19 @@ ExecutionManager::FindCodeRangeWithLock(PCODE currentPC)
return GetRangeSection(currentPC);
}


//**************************************************************************
PCODE ExecutionManager::GetCodeStartAddress(PCODE currentPC)
{
WRAPPER_NO_CONTRACT;
_ASSERTE(currentPC != NULL);

EECodeInfo codeInfo(currentPC);
if (!codeInfo.IsValid())
return NULL;
return (PCODE)codeInfo.GetStartAddress();
}

//**************************************************************************
MethodDesc * ExecutionManager::GetCodeMethodDesc(PCODE currentPC)
{
Expand Down
3 changes: 3 additions & 0 deletions src/vm/codeman.h
Original file line number Diff line number Diff line change
Expand Up @@ -1245,6 +1245,9 @@ class ExecutionManager
// Special version with profiler hook
static BOOL IsManagedCode(PCODE currentPC, HostCallPreference hostCallPreference, BOOL *pfFailedReaderLock);

// Returns method's start address for a given PC
static PCODE GetCodeStartAddress(PCODE currentPC);

// Returns methodDesc for given PC
static MethodDesc * GetCodeMethodDesc(PCODE currentPC);

Expand Down
2 changes: 2 additions & 0 deletions src/vm/eedbginterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,8 @@ class EEDebugInterface

#endif // #ifndef DACCESS_COMPILE

virtual PCODE GetNativeCodeStartAddress(PCODE address) = 0;

virtual MethodDesc *GetNativeCodeMethodDesc(const PCODE address) = 0;

#ifndef DACCESS_COMPILE
Expand Down
8 changes: 8 additions & 0 deletions src/vm/eedbginterfaceimpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -469,6 +469,14 @@ BOOL EEDbgInterfaceImpl::IsManagedNativeCode(const BYTE *address)
return ExecutionManager::IsManagedCode((PCODE)address);
}

PCODE EEDbgInterfaceImpl::GetNativeCodeStartAddress(PCODE address)
{
WRAPPER_NO_CONTRACT;
_ASSERTE(address != NULL);

return ExecutionManager::GetCodeStartAddress(address);
}

MethodDesc *EEDbgInterfaceImpl::GetNativeCodeMethodDesc(const PCODE address)
{
CONTRACT(MethodDesc *)
Expand Down
2 changes: 2 additions & 0 deletions src/vm/eedbginterfaceimpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,8 @@ class EEDbgInterfaceImpl : public EEDebugInterface

BOOL IsManagedNativeCode(const BYTE *address);

PCODE GetNativeCodeStartAddress(PCODE address) DAC_UNEXPECTED();

MethodDesc *GetNativeCodeMethodDesc(const PCODE address) DAC_UNEXPECTED();

#ifndef USE_GC_INFO_DECODER
Expand Down
58 changes: 58 additions & 0 deletions tests/src/baseservices/exceptions/stacktrace/Tier1StackTrace.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Threading;

internal static class Program
{
private static int Main()
{
const int Pass = 100, Fail = 1;

string tier0StackTrace = Capture(true);
PromoteToTier1(() => Capture(false));
string tier1StackTrace = Capture(true);
return tier0StackTrace == tier1StackTrace ? Pass : Fail;
}

private static void PromoteToTier1(Action action)
{
// Call the method once to register a call for call counting
action();

// Allow time for call counting to begin
Thread.Sleep(500);

// Call the method enough times to trigger tier 1 promotion
for (int i = 0; i < 100; i++)
{
action();
}

// Allow time for the method to be jitted at tier 1
Thread.Sleep(500);
}

[MethodImpl(MethodImplOptions.NoInlining)]
private static string Capture(bool doWork)
{
if (!doWork)
{
return null;
}

string stackTrace = new StackTrace(true).ToString().Trim();

// Remove the last line of the stack trace, which would correspond with Main()
int lastNewLineIndex = stackTrace.LastIndexOf('\n');
if (lastNewLineIndex == -1)
{
return null;
}
return stackTrace.Substring(0, lastNewLineIndex).Trim();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{8758BFAC-7D36-4244-8A36-4C464C0AFA6D}</ProjectGuid>
<OutputType>Exe</OutputType>
<LangVersion>latest</LangVersion>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<Optimize>true</Optimize>
<CLRTestPriority>1</CLRTestPriority>
</PropertyGroup>
<!-- Default configurations to help VS understand the configurations -->
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
</PropertyGroup>
<ItemGroup>
<Compile Include="Tier1StackTrace.cs" />
</ItemGroup>
<PropertyGroup>
<CLRTestBatchPreCommands><![CDATA[
$(CLRTestBatchPreCommands)
set COMPlus_EXPERIMENTAL_TieredCompilation=1
]]></CLRTestBatchPreCommands>
<BashCLRTestPreCommands><![CDATA[
$(BashCLRTestPreCommands)
export COMPlus_EXPERIMENTAL_TieredCompilation=1
]]></BashCLRTestPreCommands>
</PropertyGroup>
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
</Project>

0 comments on commit d663e0b

Please sign in to comment.