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

Fix stack trace population to get proper source/line info for tier 1 methods #16302

Merged
merged 1 commit into from
Feb 12, 2018
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
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>