-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Generate map files for symbol resolution for Linux native images on PerfView #4068
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please add function-level comments for each of these new functions. |
||
{ | ||
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", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would recommend finishing the line with just a newline and not a semi-colon. Is there a reason that the extra semi-colon is helpful for the future? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There's benefit that in the perfcollect script it's more convenient to have to deal with just one delimiter (the semicolin and not the newline). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also keep in mind that the ending semicolin is within the value part of the command, any user can choose to format the value anyway they want since every command is one line. I'm not sure how this affects anybody else? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. My thought was that the semi-colon is just another thing for someone else to parse out. It just affects other users of the file. For example, if someone adds another type of entry, then they need to parse the semi-colon out on the other end just like you do for this scenario. Not a huge deal either way, so if it makes the parsing simpler, I think it's fine to leave it. |
||
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 | ||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please add the file header at the top. You can find it in any of the existing source files. |
||
#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 { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For style, please put the curly braces on their own line. |
||
public: | ||
PerfInfo(int pid); | ||
~PerfInfo(); | ||
void LogImage(PEFile* pFile, WCHAR* guid); | ||
|
||
private: | ||
CFileStream* m_Stream; | ||
|
||
const char sDelimiter = ';'; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You should put a comment block at the top of this file that describes the file format (and use of delimiter) so that readers understand the file format. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You should also add a comment describing the naming scheme for the file (e.g. perfinfo-%pid.map). In reply to: 58457264 [](ancestors = 58457264) |
||
|
||
void OpenFile(SString& path); | ||
|
||
void WriteLine(SString& type, SString& value); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You should add a comment describing what this method does, and that it is for use within methods that log specific info (e.g. LogImageLoad). |
||
|
||
}; | ||
|
||
|
||
#endif |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,6 +10,8 @@ | |
#include "sstring.h" | ||
#include "fstream.h" | ||
|
||
class PerfInfo; | ||
|
||
// Generates a perfmap file. | ||
class PerfMap | ||
{ | ||
|
@@ -20,6 +22,9 @@ class PerfMap | |
// The file stream to write the map to. | ||
CFileStream * m_FileStream; | ||
|
||
// The perfinfo file to log images to. | ||
PerfInfo* m_PerfInfo; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please put a line in between the FilStream and the PerfInfo declaration and put a comment on the PerfInfo declaration. |
||
|
||
// Set to true if an error is encountered when writing to the file. | ||
bool m_ErrorEncountered; | ||
|
||
|
@@ -43,18 +48,18 @@ class PerfMap | |
// 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: | ||
// Initialize the map for the current process. | ||
static void Initialize(); | ||
|
||
// Log a native image load to the map. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please update the comment - you can just remove "native". |
||
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); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add the file header here as well.