Skip to content

Commit

Permalink
Write perfmap and jitdump files to /tmp by default [6.0 port] (#88486)
Browse files Browse the repository at this point in the history
* Write perfmap and jitdump files to /tmp by default

* Simplify perfmap path generation

* Minor comment update

---------

Co-authored-by: David Mason <[email protected]>
  • Loading branch information
tommcdon and davmason authored Jul 29, 2023
1 parent 1e34325 commit 70bff51
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 49 deletions.
2 changes: 1 addition & 1 deletion src/coreclr/inc/clrconfigvalues.h
Original file line number Diff line number Diff line change
Expand Up @@ -526,7 +526,7 @@ RETAIL_CONFIG_DWORD_INFO(UNSUPPORTED_ProfAPI_ValidateNGENInstrumentation, W("Pro

#ifdef FEATURE_PERFMAP
RETAIL_CONFIG_DWORD_INFO(EXTERNAL_PerfMapEnabled, W("PerfMapEnabled"), 0, "This flag is used on Linux to enable writing /tmp/perf-$pid.map. It is disabled by default")
RETAIL_CONFIG_STRING_INFO(EXTERNAL_PerfMapJitDumpPath, W("PerfMapJitDumpPath"), "Specifies a path to write the perf jitdump file. Defaults to GetTempPathA()")
RETAIL_CONFIG_STRING_INFO(EXTERNAL_PerfMapJitDumpPath, W("PerfMapJitDumpPath"), "Specifies a path to write the perf jitdump file. Defaults to /tmp")
RETAIL_CONFIG_DWORD_INFO(EXTERNAL_PerfMapIgnoreSignal, W("PerfMapIgnoreSignal"), 0, "When perf map is enabled, this option will configure the specified signal to be accepted and ignored as a marker in the perf logs. It is disabled by default")
RETAIL_CONFIG_DWORD_INFO(EXTERNAL_PerfMapShowOptimizationTiers, W("PerfMapShowOptimizationTiers"), 1, "Shows optimization tiers in the perf map for methods, as part of the symbol name. Useful for seeing separate stack frames for different optimization tiers of each method.")
RETAIL_CONFIG_STRING_INFO(EXTERNAL_NativeImagePerfMapFormat, W("NativeImagePerfMapFormat"), "Specifies the format of native image perfmap files generated by crossgen. Valid options are RVA or OFFSET.")
Expand Down
10 changes: 2 additions & 8 deletions src/coreclr/vm/perfinfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,13 @@
#include "perfinfo.h"
#include "pal.h"

PerfInfo::PerfInfo(int pid)
PerfInfo::PerfInfo(int pid, const char* basePath)
: m_Stream(nullptr)
{
LIMITED_METHOD_CONTRACT;

SString tempPath;
if (!WszGetTempPath(tempPath))
{
return;
}

SString path;
path.Printf("%Sperfinfo-%d.map", tempPath.GetUnicode(), pid);
path.Printf("%s/perfinfo-%d.map", basePath, pid);
OpenFile(path);
}

Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/vm/perfinfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
*/
class PerfInfo {
public:
PerfInfo(int pid);
PerfInfo(int pid, const char* basePath);
~PerfInfo();
void LogImage(PEFile* pFile, WCHAR* guid);

Expand Down
89 changes: 51 additions & 38 deletions src/coreclr/vm/perfmap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,14 @@
#define FMT_CODE_ADDR "%p"
#endif

#ifndef __ANDROID__
#define TEMP_DIRECTORY_PATH "/tmp"
#else
// On Android, "/tmp/" doesn't exist; temporary files should go to
// /data/local/tmp/
#define TEMP_DIRECTORY_PATH "/data/local/tmp"
#endif

Volatile<bool> PerfMap::s_enabled = false;
PerfMap * PerfMap::s_Current = nullptr;
bool PerfMap::s_ShowOptimizationTiers = false;
Expand All @@ -40,53 +48,64 @@ void PerfMap::Initialize()
{
LIMITED_METHOD_CONTRACT;

const DWORD perfMapEnabled = CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_PerfMapEnabled);
if (perfMapEnabled == DISABLED)
{
return;
}

// Build the path to the map file on disk.
char tempPathBuffer[MAX_LONGPATH+1];
const char* tempPath = InternalConstructPath(tempPathBuffer, sizeof(tempPathBuffer));

// Only enable the map if requested.
if (CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_PerfMapEnabled) == ALL || CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_PerfMapEnabled) == PERFMAP)
if (perfMapEnabled == ALL || perfMapEnabled == PERFMAP)
{
// Get the current process id.
int currentPid = GetCurrentProcessId();

// Create the map.
s_Current = new PerfMap(currentPid);
s_Current = new PerfMap(currentPid, tempPath);

int signalNum = (int) CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_PerfMapIgnoreSignal);

if (signalNum > 0)
{
PAL_IgnoreProfileSignal(signalNum);
}
}

if (CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_PerfMapShowOptimizationTiers) != 0)
{
s_ShowOptimizationTiers = true;
}

s_enabled = true;
// only enable JitDumps if requested
if (perfMapEnabled == ALL || perfMapEnabled == JITDUMP)
{
PAL_PerfJitDump_Start(tempPath);
}

if (CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_PerfMapEnabled) == ALL || CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_PerfMapEnabled) == JITDUMP)
if (CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_PerfMapShowOptimizationTiers) != 0)
{
char jitdumpPath[4096];

// CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_PerfMapJitDumpPath) returns a LPWSTR
// Use GetEnvironmentVariableA because it is simpler.
// Keep comment here to make it searchable.
DWORD len = GetEnvironmentVariableA("COMPlus_PerfMapJitDumpPath", jitdumpPath, sizeof(jitdumpPath) - 1);

if (len == 0)
{
GetTempPathA(sizeof(jitdumpPath) - 1, jitdumpPath);
}
s_ShowOptimizationTiers = true;
}

s_enabled = true;
}

PAL_PerfJitDump_Start(jitdumpPath);
// InternalConstructPath is guaranteed to return a non-null path
// the function uses the input buffer only whe PerfMapJitDumpPath environment variable is set
const char * PerfMap::InternalConstructPath(char *tmpBuf, int lenBuf)
{
DWORD len = GetEnvironmentVariableA("DOTNET_PerfMapJitDumpPath", tmpBuf, lenBuf);
if (len == 0)
{
len = GetEnvironmentVariableA("COMPlus_PerfMapJitDumpPath", tmpBuf, lenBuf);
}

if (CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_PerfMapShowOptimizationTiers) != 0)
{
s_ShowOptimizationTiers = true;
}

s_enabled = true;
if (len == 0 || // GetEnvironmentVariableA returns 0 if the variable is not found,
len >= lenBuf) // or the length of the string not including the null terminator on success.
{
return TEMP_DIRECTORY_PATH;
}

return tmpBuf;
}

// Destroy the map for the process - called from EEShutdownHelper.
Expand All @@ -103,27 +122,21 @@ void PerfMap::Destroy()
}

// Construct a new map for the process.
PerfMap::PerfMap(int pid)
PerfMap::PerfMap(int pid, const char* path)
{
LIMITED_METHOD_CONTRACT;

// Initialize with no failures.
m_ErrorEncountered = false;

// Build the path to the map file on disk.
WCHAR tempPath[MAX_LONGPATH+1];
if(!GetTempPathW(MAX_LONGPATH, tempPath))
{
return;
}

SString path;
path.Printf("%Sperf-%d.map", &tempPath, pid);
SString pathFile;
pathFile.Printf("%s/perf-%d.map", path, pid);

// Open the map file for writing.
OpenFile(path);
OpenFile(pathFile);

m_PerfInfo = new PerfInfo(pid);
m_PerfInfo = new PerfInfo(pid, path);
}

// Construct a new map without a specified file name.
Expand Down
5 changes: 4 additions & 1 deletion src/coreclr/vm/perfmap.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,10 @@ class PerfMap
bool m_ErrorEncountered;

// Construct a new map for the specified pid.
PerfMap(int pid);
PerfMap(int pid, const char* path);

// Default to /tmp or use DOTNET_PerfMapJitDumpPath if set
static const char* InternalConstructPath(char *tmpBuf, int lenBuf);

protected:
// Indicates whether optimization tiers should be shown for methods in perf maps
Expand Down

0 comments on commit 70bff51

Please sign in to comment.