#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_EX(EXTERNAL_PerfMapJitDumpPath, W("PerfMapJitDumpPath"), "Specifies a path to write the perf jitdump file. Defaults to /tmp", CLRConfig::LookupOptions::TrimWhiteSpaceFromStringValue)
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.")
#endif
#define FMT_CODE_ADDR "%p"
+#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;
PerfMap::Enable(perfMapType, false);
}
+const char * PerfMap::InternalConstructPath()
+{
+ CLRConfigNoCache value = CLRConfigNoCache::Get("PerfMapJitDumpPath");
+ if (value.IsSet())
+ {
+ return value.AsString();
+ }
+ return TEMP_DIRECTORY_PATH;
+}
+
void PerfMap::Enable(PerfMapType type, bool sendExisting)
{
LIMITED_METHOD_CONTRACT;
{
CrstHolder ch(&(s_csPerfMap));
+ const char* basePath = InternalConstructPath();
+
if (s_Current == nullptr && (type == PerfMapType::ALL || type == PerfMapType::PERFMAP))
{
s_Current = new PerfMap();
}
int currentPid = GetCurrentProcessId();
- s_Current->OpenFileForPid(currentPid);
+ s_Current->OpenFileForPid(currentPid, basePath);
s_enabled = true;
}
if (!PAL_PerfJitDump_IsStarted() && (type == PerfMapType::ALL || type == PerfMapType::JITDUMP))
- {
- const char* jitdumpPath;
- char jitdumpPathBuffer[4096];
-
- CLRConfigNoCache value = CLRConfigNoCache::Get("PerfMapJitDumpPath");
- if (value.IsSet())
- {
- jitdumpPath = value.AsString();
- }
- else
- {
- GetTempPathA(sizeof(jitdumpPathBuffer) - 1, jitdumpPathBuffer);
- jitdumpPath = jitdumpPathBuffer;
- }
-
- PAL_PerfJitDump_Start(jitdumpPath);
+ {
+ PAL_PerfJitDump_Start(basePath);
if (CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_PerfMapShowOptimizationTiers) != 0)
{
m_PerfInfo = nullptr;
}
-void PerfMap::OpenFileForPid(int pid)
+void PerfMap::OpenFileForPid(int pid, const char* basePath)
{
- // Build the path to the map file on disk.
- WCHAR tempPath[MAX_LONGPATH+1];
- if(!GetTempPathW(MAX_LONGPATH, tempPath))
- {
- return;
- }
-
- SString path;
- path.Append(tempPath);
- path.AppendPrintf("perf-%d.map", pid);
+ SString fullPath;
+ fullPath.Printf("%s/perf-%d.map", basePath, pid);
// Open the map file for writing.
- OpenFile(path);
+ OpenFile(fullPath);
- m_PerfInfo = new PerfInfo(pid);
+ m_PerfInfo = new PerfInfo(pid, basePath);
}
// Open the specified destination map file.
// Set to true if an error is encountered when writing to the file.
bool m_ErrorEncountered;
- // Construct a new map for the specified pid.
+ // Construct a new map
PerfMap();
- void OpenFileForPid(int pid);
+ // Open a perfmap map for the specified pid
+ void OpenFileForPid(int pid, const char* basePath);
// Write a line to the map file.
void WriteLine(SString & line);
+ // Default to /tmp or use DOTNET_PerfMapJitDumpPath if set
+ static const char* InternalConstructPath();
+
protected:
// Open the perf map file for write.
void OpenFile(SString& path);