superpmi_collect_help = """\
Command to run SuperPMI collect over. Note that there cannot be any dotnet CLI commands
-invoked inside this command, as they will fail due to the shim altjit being set.
+invoked inside this command, as they will fail due to the shim JIT being set.
"""
replay_mch_files_help = """\
env_copy = os.environ.copy()
env_copy["SuperPMIShimLogPath"] = self.temp_location
env_copy["SuperPMIShimPath"] = self.jit_path
- env_copy["COMPlus_AltJit"] = "*"
- env_copy["COMPlus_AltJitNgen"] = "*"
- env_copy["COMPlus_AltJitName"] = self.collection_shim_name
+ env_copy["COMPlus_JitName"] = self.collection_shim_name
env_copy["COMPlus_EnableExtraSuperPmiQueries"] = "1"
env_copy["COMPlus_TieredCompilation"] = "0"
logging.debug("")
print_platform_specific_environment_vars(logging.DEBUG, self.coreclr_args, "SuperPMIShimLogPath", self.temp_location)
print_platform_specific_environment_vars(logging.DEBUG, self.coreclr_args, "SuperPMIShimPath", self.jit_path)
- print_platform_specific_environment_vars(logging.DEBUG, self.coreclr_args, "COMPlus_AltJit", "*")
- print_platform_specific_environment_vars(logging.DEBUG, self.coreclr_args, "COMPlus_AltJitNgen", "*")
- print_platform_specific_environment_vars(logging.DEBUG, self.coreclr_args, "COMPlus_AltJitName", self.collection_shim_name)
+ print_platform_specific_environment_vars(logging.DEBUG, self.coreclr_args, "COMPlus_JitName", self.collection_shim_name)
print_platform_specific_environment_vars(logging.DEBUG, self.coreclr_args, "COMPlus_EnableExtraSuperPmiQueries", "1")
print_platform_specific_environment_vars(logging.DEBUG, self.coreclr_args, "COMPlus_TieredCompilation", "0")
if self.coreclr_args.use_zapdisable:
logging.debug("Temp Location: %s", temp_location)
logging.debug("")
- flags = [
+ # `repro_flags` are the subset of flags we tell the user to pass to superpmi when reproducing
+ # a failure. This won't include things like "-p" for parallelism or "-r" to create a repro .mc file.
+ repro_flags = []
+
+ common_flags = [
"-v", "ew", # only display errors and warnings
"-r", os.path.join(temp_location, "repro") # Repro name, create .mc repro files
]
- altjit_string = "*" if self.coreclr_args.altjit else ""
- altjit_replay_flags = [
- "-jitoption", "force", "AltJit=" + altjit_string,
- "-jitoption", "force", "AltJitNgen=" + altjit_string,
- "-jitoption", "force", "EnableExtraSuperPmiQueries=0"
- ]
- flags += altjit_replay_flags
+ if self.coreclr_args.altjit:
+ repro_flags += [
+ "-jitoption", "force", "AltJit=*",
+ "-jitoption", "force", "AltJitNgen=*"
+ ]
+ if self.coreclr_args.arch == "arm":
+ repro_flags += [ "-target", "arm" ]
+ elif self.coreclr_args.arch == "arm64":
+ repro_flags += [ "-target", "arm64" ]
if not self.coreclr_args.sequential:
- flags += [ "-p" ]
+ common_flags += [ "-p" ]
if self.coreclr_args.break_on_assert:
- flags += [ "-boa" ]
+ common_flags += [ "-boa" ]
if self.coreclr_args.break_on_error:
- flags += [ "-boe" ]
+ common_flags += [ "-boe" ]
if self.coreclr_args.spmi_log_file is not None:
- flags += [ "-w", self.coreclr_args.spmi_log_file ]
+ common_flags += [ "-w", self.coreclr_args.spmi_log_file ]
+
+ # TEMPORARY: when we have collections that are done using COMPlus_JitName
+ # instead of COMPlus_AltJit, we can remove these.
+ if not self.coreclr_args.altjit:
+ repro_flags += [
+ "-jitoption", "force", "AltJit=",
+ "-jitoption", "force", "AltJitNgen="
+ ]
+ repro_flags += [ "-jitoption", "force", "EnableExtraSuperPmiQueries=0" ]
+ # END TEMPORARY
- if self.coreclr_args.altjit:
- if self.coreclr_args.arch == "arm":
- flags += [ "-target", "arm" ]
- elif self.coreclr_args.arch == "arm64":
- flags += [ "-target", "arm64" ]
+ common_flags += repro_flags
# For each MCH file that we are going to replay, do the replay and replay post-processing.
#
logging.info("Running SuperPMI replay of %s", mch_file)
+ flags = common_flags
+
fail_mcl_file = os.path.join(temp_location, os.path.basename(mch_file) + "_fail.mcl")
flags += [
"-f", fail_mcl_file, # Failing mc List
if return_code == 0:
logging.warning("Warning: SuperPMI returned a zero exit code, but generated a non-zero-sized mcl file")
print_fail_mcl_file_method_numbers(fail_mcl_file)
- repro_base_command_line = "{} {} {}".format(self.superpmi_path, " ".join(altjit_replay_flags), self.jit_path)
+ repro_base_command_line = "{} {} {}".format(self.superpmi_path, " ".join(repro_flags), self.jit_path)
save_repro_mc_files(temp_location, self.coreclr_args, repro_base_command_line)
if not self.coreclr_args.skip_cleanup:
"COMPlus_JitDump": "*",
"COMPlus_NgenDump": "*" }
- altjit_string = "*" if self.coreclr_args.altjit else ""
+ altjit_asm_diffs_flags = []
+ altjit_replay_flags = []
+
+ if self.coreclr_args.altjit:
+ target_flags = []
+ if self.coreclr_args.arch == "arm":
+ target_flags += [ "-target", "arm" ]
+ elif self.coreclr_args.arch == "arm64":
+ target_flags += [ "-target", "arm64" ]
+
+ altjit_asm_diffs_flags = target_flags + [
+ "-jitoption", "force", "AltJit=*",
+ "-jitoption", "force", "AltJitNgen=*",
+ "-jit2option", "force", "AltJit=*",
+ "-jit2option", "force", "AltJitNgen=*"
+ ]
- altjit_asm_diffs_flags = [
- "-jitoption", "force", "AltJit=" + altjit_string,
- "-jitoption", "force", "AltJitNgen=" + altjit_string,
- "-jitoption", "force", "EnableExtraSuperPmiQueries=0",
- "-jit2option", "force", "AltJit=" + altjit_string,
- "-jit2option", "force", "AltJitNgen=" + altjit_string,
- "-jit2option", "force", "EnableExtraSuperPmiQueries=0"
- ]
+ altjit_replay_flags = target_flags + [
+ "-jitoption", "force", "AltJit=*",
+ "-jitoption", "force", "AltJitNgen=*"
+ ]
- altjit_replay_flags = [
- "-jitoption", "force", "AltJit=" + altjit_string,
- "-jitoption", "force", "AltJitNgen=" + altjit_string,
- "-jitoption", "force", "EnableExtraSuperPmiQueries=0"
- ]
+ # TEMPORARY: when we have collections that are done using COMPlus_JitName
+ # instead of COMPlus_AltJit, we can remove these.
+ if not self.coreclr_args.altjit:
+ altjit_asm_diffs_flags = [
+ "-jitoption", "force", "AltJit=",
+ "-jitoption", "force", "AltJitNgen=",
+ "-jit2option", "force", "AltJit=",
+ "-jit2option", "force", "AltJitNgen="
+ ]
+ altjit_replay_flags = [
+ "-jitoption", "force", "AltJit=",
+ "-jitoption", "force", "AltJitNgen="
+ ]
+ altjit_asm_diffs_flags += [ "-jitoption", "force", "EnableExtraSuperPmiQueries=0" ]
+ altjit_replay_flags += [ "-jitoption", "force", "EnableExtraSuperPmiQueries=0" ]
+ # END TEMPORARY
# Keep track if any MCH file replay had asm diffs
files_with_asm_diffs = []
if self.coreclr_args.spmi_log_file is not None:
flags += [ "-w", self.coreclr_args.spmi_log_file ]
- if self.coreclr_args.altjit:
- if self.coreclr_args.arch == "arm":
- flags += [ "-target", "arm" ]
- elif self.coreclr_args.arch == "arm64":
- flags += [ "-target", "arm64" ]
-
# Change the working directory to the Core_Root we will call SuperPMI from.
# This is done to allow libcoredistools to be loaded correctly on unix
# as the loadlibrary path will be relative to the current directory.
"collection_args",
lambda unused: True,
"Unable to set collection_args",
- modify_arg=lambda collection_args: collection_args.split(" ") if collection_args is not None else collection_args)
+ modify_arg=lambda collection_args: collection_args.split(" ") if collection_args is not None else [])
coreclr_args.verify(args,
"pmi",
// Here's the global data for JIT load and initialization state.
JIT_LOAD_DATA g_JitLoadData;
+// Validate that the name used to load the JIT is just a simple file name
+// and does not contain something that could be used in a non-qualified path.
+// For example, using the string "..\..\..\myjit.dll" we might attempt to
+// load a JIT from the root of the drive.
+//
+// The minimal set of characters that we must check for and exclude are:
+// '\\' - (backslash)
+// '/' - (forward slash)
+// ':' - (colon)
+//
+// Returns false if we find any of these characters in 'pwzJitName'
+// Returns true if we reach the null terminator without encountering
+// any of these characters.
+//
+static bool ValidateJitName(LPCWSTR pwzJitName)
+{
+ LPCWSTR pCurChar = pwzJitName;
+ wchar_t curChar;
+ do {
+ curChar = *pCurChar;
+ if ((curChar == '\\') || (curChar == '/') || (curChar == ':'))
+ {
+ // Return false if we find any of these character in 'pwzJitName'
+ return false;
+ }
+ pCurChar++;
+ } while (curChar != 0);
+
+ // Return true; we have reached the null terminator
+ //
+ return true;
+}
+
// LoadAndInitializeJIT: load the JIT dll into the process, and initialize it (call the UtilCode initialization function,
// check the JIT-EE interface GUID, etc.)
//
*phJit = NULL;
*ppICorJitCompiler = NULL;
- HRESULT hr = E_FAIL;
-
- PathString CoreClrFolderHolder;
- bool havePath = false;
-
- if (GetClrModulePathName(CoreClrFolderHolder))
+ if (pwzJitName == nullptr)
{
- // Load JIT from next to CoreCLR binary
- havePath = true;
+ pJitLoadData->jld_hr = E_FAIL;
+ LOG((LF_JIT, LL_FATALERROR, "LoadAndInitializeJIT: pwzJitName is null"));
+ return;
}
- if (havePath && !CoreClrFolderHolder.IsEmpty())
+ HRESULT hr = E_FAIL;
+
+ if (ValidateJitName(pwzJitName))
{
- SString::Iterator iter = CoreClrFolderHolder.End();
- BOOL findSep = CoreClrFolderHolder.FindBack(iter, DIRECTORY_SEPARATOR_CHAR_W);
- if (findSep)
+ // Load JIT from next to CoreCLR binary
+ PathString CoreClrFolderHolder;
+ if (GetClrModulePathName(CoreClrFolderHolder) && !CoreClrFolderHolder.IsEmpty())
{
- SString sJitName(pwzJitName);
- CoreClrFolderHolder.Replace(iter + 1, CoreClrFolderHolder.End() - (iter + 1), sJitName);
-
- *phJit = CLRLoadLibrary(CoreClrFolderHolder.GetUnicode());
- if (*phJit != NULL)
+ SString::Iterator iter = CoreClrFolderHolder.End();
+ BOOL findSep = CoreClrFolderHolder.FindBack(iter, DIRECTORY_SEPARATOR_CHAR_W);
+ if (findSep)
{
- hr = S_OK;
+ SString sJitName(pwzJitName);
+ CoreClrFolderHolder.Replace(iter + 1, CoreClrFolderHolder.End() - (iter + 1), sJitName);
+
+ *phJit = CLRLoadLibrary(CoreClrFolderHolder.GetUnicode());
+ if (*phJit != NULL)
+ {
+ hr = S_OK;
+ }
}
}
}
-
+ else
+ {
+ LOG((LF_JIT, LL_FATALERROR, "LoadAndInitializeJIT: invalid characters in %S\n", pwzJitName));
+ }
if (SUCCEEDED(hr))
{
{
STANDARD_VM_CONTRACT;
- return MAKEDLLNAME_W(W("clrjit"));
+ LPCWSTR pwzJitName = NULL;
+
+ // Try to obtain a name for the jit library from the env. variable
+ IfFailThrow(CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_JitName, const_cast<LPWSTR *>(&pwzJitName)));
+
+ if (NULL == pwzJitName)
+ {
+ pwzJitName = MAKEDLLNAME_W(W("clrjit"));
+ }
+
+ return pwzJitName;
}
#endif // !FEATURE_MERGE_JIT_AND_ENGINE
Console.WriteLine("Setting environment variables:");
Console.WriteLine(" SuperPMIShimLogPath=" + s_tempDir);
Console.WriteLine(" SuperPMIShimPath=" + Global.JitPath);
- Console.WriteLine(" COMPlus_AltJit=*");
- Console.WriteLine(" COMPlus_AltJitName=" + Global.CollectorShimName);
+ Console.WriteLine(" COMPlus_JitName=" + Global.CollectorShimName);
Environment.SetEnvironmentVariable("SuperPMIShimLogPath", s_tempDir);
Environment.SetEnvironmentVariable("SuperPMIShimPath", Global.JitPath);
- Environment.SetEnvironmentVariable("COMPlus_AltJit", "*");
- Environment.SetEnvironmentVariable("COMPlus_AltJitName", Global.CollectorShimName);
+ Environment.SetEnvironmentVariable("COMPlus_JitName", Global.CollectorShimName);
RunProgramsWhileCollecting(runProgramPath, runProgramArguments);
// Un-set environment variables
Environment.SetEnvironmentVariable("SuperPMIShimLogPath", "");
Environment.SetEnvironmentVariable("SuperPMIShimPath", "");
- Environment.SetEnvironmentVariable("COMPlus_AltJit", "");
- Environment.SetEnvironmentVariable("COMPlus_AltJitName", "");
+ Environment.SetEnvironmentVariable("COMPlus_JitName", "");
// Did any .mc files get generated?
string[] mcFiles = Directory.GetFiles(s_tempDir, "*.mc");
Console.WriteLine("If -mch is not given, all generated files are deleted, and the result is simply the exit code");
Console.WriteLine("indicating whether the collection succeeded. This is useful as a test.");
Console.WriteLine("");
- Console.WriteLine("If the COMPlus_AltJit variable is already set, it is assumed SuperPMI collection is already happening,");
+ Console.WriteLine("If the COMPlus_JitName variable is already set, it is assumed SuperPMI collection is already happening,");
Console.WriteLine("and the program exits with success.");
Console.WriteLine("");
Console.WriteLine("On success, the return code is 100.");
// Done with argument parsing.
- string altjitvar = System.Environment.GetEnvironmentVariable("COMPlus_AltJit");
- if (!String.IsNullOrEmpty(altjitvar))
+ string jitnamevar = System.Environment.GetEnvironmentVariable("COMPlus_JitName");
+ if (!String.IsNullOrEmpty(jitnamevar))
{
- // Someone already has the COMPlus_AltJit variable set. We don't want to override
+ // Someone already has the COMPlus_JitName variable set. We don't want to override
// that. Perhaps someone is already doing a SuperPMI collection and invokes this
// program as part of a full test path in which this program exists.
- Console.WriteLine("COMPlus_AltJit already exists: skipping SuperPMI collection and returning success");
+ Console.WriteLine("COMPlus_JitName already exists: skipping SuperPMI collection and returning success");
return 100;
}