summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrian Robbins <brianrob@microsoft.com>2016-04-13 14:15:14 -0700
committerBrian Robbins <brianrob@microsoft.com>2016-04-13 14:15:14 -0700
commit0ec739e4416d12eeaac0c365fae09e503b080eaf (patch)
treeb638735a4ba2bd80a9de6e2e6c796766dc8ce5f9
parent3ad8f15af54add9dcc3ecb8b89f3b9a82c65bef3 (diff)
parent484c855fe4a91a8ea67213457d69182669c65ded (diff)
downloadcoreclr-0ec739e4416d12eeaac0c365fae09e503b080eaf.tar.gz
coreclr-0ec739e4416d12eeaac0c365fae09e503b080eaf.tar.bz2
coreclr-0ec739e4416d12eeaac0c365fae09e503b080eaf.zip
Merge pull request #4068 from Lucrecious/master
Generate map files for symbol resolution for Linux native images on PerfView
-rw-r--r--src/vm/CMakeLists.txt1
-rw-r--r--src/vm/crossgen/CMakeLists.txt1
-rw-r--r--src/vm/domainfile.cpp10
-rw-r--r--src/vm/perfinfo.cpp125
-rw-r--r--src/vm/perfinfo.h40
-rw-r--r--src/vm/perfmap.cpp52
-rw-r--r--src/vm/perfmap.h13
7 files changed, 200 insertions, 42 deletions
diff --git a/src/vm/CMakeLists.txt b/src/vm/CMakeLists.txt
index 13106a4a68..346acb264f 100644
--- a/src/vm/CMakeLists.txt
+++ b/src/vm/CMakeLists.txt
@@ -115,6 +115,7 @@ set(VM_SOURCES_DAC_AND_WKS_COMMON
peimage.cpp
peimagelayout.cpp
perfmap.cpp
+ perfinfo.cpp
precode.cpp
prestub.cpp
rejit.cpp
diff --git a/src/vm/crossgen/CMakeLists.txt b/src/vm/crossgen/CMakeLists.txt
index e3b5c6ae74..24a6fbdc53 100644
--- a/src/vm/crossgen/CMakeLists.txt
+++ b/src/vm/crossgen/CMakeLists.txt
@@ -150,6 +150,7 @@ endif (WIN32)
if (CLR_CMAKE_PLATFORM_LINUX)
list(APPEND VM_CROSSGEN_SOURCES
../perfmap.cpp
+ ../perfinfo.cpp
)
endif (CLR_CMAKE_PLATFORM_LINUX)
diff --git a/src/vm/domainfile.cpp b/src/vm/domainfile.cpp
index 3837e82a60..9ccf46e35c 100644
--- a/src/vm/domainfile.cpp
+++ b/src/vm/domainfile.cpp
@@ -1310,11 +1310,6 @@ void DomainFile::FinishLoad()
// Inform metadata that it has been loaded from a native image
// (and so there was an opportunity to check for or fix inconsistencies in the original IL metadata)
m_pFile->GetMDImport()->SetVerifiedByTrustedSource(TRUE);
-
-#ifdef FEATURE_PERFMAP
- // Notify the perfmap of the native image load.
- PerfMap::LogNativeImageLoad(m_pFile);
-#endif
}
// Are we absolutely required to use a native image?
@@ -1382,6 +1377,11 @@ void DomainFile::FinishLoad()
// Set a bit to indicate that the module has been loaded in some domain, and therefore
// typeloads can involve types from this module. (Used for candidate instantiations.)
GetModule()->SetIsReadyForTypeLoad();
+
+#ifdef FEATURE_PERFMAP
+ // Notify the perfmap of the IL image load.
+ PerfMap::LogImageLoad(m_pFile);
+#endif
}
void DomainFile::VerifyExecution()
diff --git a/src/vm/perfinfo.cpp b/src/vm/perfinfo.cpp
new file mode 100644
index 0000000000..3f85f44ebc
--- /dev/null
+++ b/src/vm/perfinfo.cpp
@@ -0,0 +1,125 @@
+// 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.
+// ===========================================================================
+// File: perfinfo.cpp
+//
+
+#include "common.h"
+
+#if defined(FEATURE_PERFMAP) && !defined(DACCESS_COMPILE)
+#include "perfinfo.h"
+#include "pal.h"
+
+PerfInfo::PerfInfo(int pid)
+{
+ LIMITED_METHOD_CONTRACT;
+
+ SString tempPath;
+ if (!WszGetTempPath(tempPath))
+ {
+ return;
+ }
+
+ SString path;
+ path.Printf("%Sperfinfo-%d.map", tempPath.GetUnicode(), pid);
+ OpenFile(path);
+}
+
+// Logs image loads into the process' perfinfo-%d.map file
+void PerfInfo::LogImage(PEFile* pFile, WCHAR* guid)
+{
+ CONTRACTL
+ {
+ THROWS;
+ GC_NOTRIGGER;
+ MODE_PREEMPTIVE;
+ PRECONDITION(pFile != NULL);
+ PRECONDITION(guid != NULL);
+ } CONTRACTL_END;
+
+ SString value;
+ const SString& path = pFile->GetPath();
+ value.Printf("%S%c%S", path.GetUnicode(), sDelimiter, guid);
+
+ SString command;
+ command.Printf("%s", "ImageLoad");
+ WriteLine(command, value);
+
+}
+
+// Writes a command line, with "type" being the type of command, with "value" as the command's corresponding instructions/values. This is to be used to log specific information, e.g. LogImage
+void PerfInfo::WriteLine(SString& type, SString& value)
+{
+
+ CONTRACTL
+ {
+ THROWS;
+ GC_NOTRIGGER;
+ MODE_PREEMPTIVE;
+ } CONTRACTL_END;
+
+ if (m_Stream == NULL)
+ {
+ return;
+ }
+
+ SString line;
+ line.Printf("%S%c%S%c\n",
+ type.GetUnicode(), sDelimiter, value.GetUnicode(), sDelimiter);
+
+ EX_TRY
+ {
+ StackScratchBuffer scratch;
+ const char* strLine = line.GetANSI(scratch);
+ ULONG inCount = line.GetCount();
+ ULONG outCount;
+
+ m_Stream->Write(strLine, inCount, &outCount);
+
+ if (inCount != outCount)
+ {
+ // error encountered
+ }
+ }
+ EX_CATCH{} EX_END_CATCH(SwallowAllExceptions);
+}
+
+// Opens a file ready to be written in.
+void PerfInfo::OpenFile(SString& path)
+{
+ STANDARD_VM_CONTRACT;
+
+ m_Stream = new (nothrow) CFileStream();
+
+ if (m_Stream != NULL)
+ {
+ HRESULT hr = m_Stream->OpenForWrite(path.GetUnicode());
+ if (FAILED(hr))
+ {
+ delete m_Stream;
+ m_Stream = NULL;
+ }
+ }
+}
+
+PerfInfo::~PerfInfo()
+{
+ LIMITED_METHOD_CONTRACT;
+
+ delete m_Stream;
+ m_Stream = NULL;
+}
+
+
+#endif
+
+
+
+
+
+
+
+
+
+
diff --git a/src/vm/perfinfo.h b/src/vm/perfinfo.h
new file mode 100644
index 0000000000..4ea87f35b4
--- /dev/null
+++ b/src/vm/perfinfo.h
@@ -0,0 +1,40 @@
+// 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.
+// ===========================================================================
+// File: perfinfo.h
+//
+
+#ifndef PERFINFO_H
+#define PERFINFO_H
+
+
+#include "sstring.h"
+#include "fstream.h"
+
+/*
+ A perfinfo-%d.map is created for every process that is created with manage code, the %d
+ being repaced with the process ID.
+ Every line in the perfinfo-%d.map is a type and value, separated by sDelimiter character: type;value
+ type represents what the user might want to do with its given value. value has a format chosen by
+ the user for parsing later on.
+*/
+class PerfInfo {
+public:
+ PerfInfo(int pid);
+ ~PerfInfo();
+ void LogImage(PEFile* pFile, WCHAR* guid);
+
+private:
+ CFileStream* m_Stream;
+
+ const char sDelimiter = ';';
+
+ void OpenFile(SString& path);
+
+ void WriteLine(SString& type, SString& value);
+
+};
+
+
+#endif
diff --git a/src/vm/perfmap.cpp b/src/vm/perfmap.cpp
index 5c83584bda..4e04ca7d43 100644
--- a/src/vm/perfmap.cpp
+++ b/src/vm/perfmap.cpp
@@ -9,6 +9,7 @@
#if defined(FEATURE_PERFMAP) && !defined(DACCESS_COMPILE)
#include "perfmap.h"
+#include "perfinfo.h"
#include "pal.h"
PerfMap * PerfMap::s_Current = NULL;
@@ -61,6 +62,8 @@ PerfMap::PerfMap(int pid)
// Open the map file for writing.
OpenFile(path);
+
+ m_PerfInfo = new PerfInfo(pid);
}
// Construct a new map without a specified file name.
@@ -77,6 +80,9 @@ PerfMap::~PerfMap()
delete m_FileStream;
m_FileStream = NULL;
+
+ delete m_PerfInfo;
+ m_PerfInfo = NULL;
}
// Open the specified destination map file.
@@ -159,8 +165,17 @@ void PerfMap::LogMethod(MethodDesc * pMethod, PCODE pCode, size_t codeSize)
EX_CATCH{} EX_END_CATCH(SwallowAllExceptions);
}
-// Log a native image to the map.
-void PerfMap::LogNativeImage(PEFile * pFile)
+
+void PerfMap::LogImageLoad(PEFile * pFile)
+{
+ if (s_Current != NULL)
+ {
+ s_Current->LogImage(pFile);
+ }
+}
+
+// Log an image load to the map.
+void PerfMap::LogImage(PEFile * pFile)
{
CONTRACTL{
THROWS;
@@ -169,52 +184,23 @@ void PerfMap::LogNativeImage(PEFile * pFile)
PRECONDITION(pFile != NULL);
} CONTRACTL_END;
+
if (m_FileStream == NULL || m_ErrorEncountered)
{
// A failure occurred, do not log.
return;
}
- // Logging failures should not cause any exceptions to flow upstream.
EX_TRY
{
- // Get the native image name.
- LPCUTF8 lpcSimpleName = pFile->GetSimpleName();
-
- // Get the native image signature.
WCHAR wszSignature[39];
GetNativeImageSignature(pFile, wszSignature, lengthof(wszSignature));
- SString strNativeImageSymbol;
- strNativeImageSymbol.Printf("%s.ni.%S", lpcSimpleName, wszSignature);
-
- // Get the base addess of the native image.
- SIZE_T baseAddress = (SIZE_T)pFile->GetLoaded()->GetBase();
-
- // Get the image size
- COUNT_T imageSize = pFile->GetLoaded()->GetVirtualSize();
-
- // Log baseAddress imageSize strNativeImageSymbol
- StackScratchBuffer scratch;
- SString line;
- line.Printf("%p %x %s\n", baseAddress, imageSize, strNativeImageSymbol.GetANSI(scratch));
-
- // Write the line.
- WriteLine(line);
+ m_PerfInfo->LogImage(pFile, wszSignature);
}
EX_CATCH{} EX_END_CATCH(SwallowAllExceptions);
}
-// Log a native image load to the map.
-void PerfMap::LogNativeImageLoad(PEFile * pFile)
-{
- STANDARD_VM_CONTRACT;
-
- if (s_Current != NULL)
- {
- s_Current->LogNativeImage(pFile);
- }
-}
// Log a method to the map.
void PerfMap::LogJITCompiledMethod(MethodDesc * pMethod, PCODE pCode, size_t codeSize)
diff --git a/src/vm/perfmap.h b/src/vm/perfmap.h
index ca86f5b028..fe38ed3ad5 100644
--- a/src/vm/perfmap.h
+++ b/src/vm/perfmap.h
@@ -10,6 +10,8 @@
#include "sstring.h"
#include "fstream.h"
+class PerfInfo;
+
// Generates a perfmap file.
class PerfMap
{
@@ -20,6 +22,9 @@ private:
// The file stream to write the map to.
CFileStream * m_FileStream;
+ // The perfinfo file to log images to.
+ PerfInfo* m_PerfInfo;
+
// Set to true if an error is encountered when writing to the file.
bool m_ErrorEncountered;
@@ -43,10 +48,10 @@ protected:
// Does the actual work to log a method to the map.
void LogMethod(MethodDesc * pMethod, PCODE pCode, size_t codeSize);
- // Does the actual work to log a native image load to the map.
- void LogNativeImage(PEFile * pFile);
+ // Does the actual work to log an image
+ void LogImage(PEFile * pFile);
- // Get the native image signature and store it as a string.
+ // Get the image signature and store it as a string.
static void GetNativeImageSignature(PEFile * pFile, WCHAR * pwszSig, unsigned int nSigSize);
public:
@@ -54,7 +59,7 @@ public:
static void Initialize();
// Log a native image load to the map.
- static void LogNativeImageLoad(PEFile * pFile);
+ static void LogImageLoad(PEFile * pFile);
// Log a JIT compiled method to the map.
static void LogJITCompiledMethod(MethodDesc * pMethod, PCODE pCode, size_t codeSize);