void LoadSos(LLDBServices *services) { if (m_sosHandle == NULL) { if (g_coreclrDirectory == NULL) { const char *coreclrModule = MAKEDLLNAME_A("coreclr"); const char *directory = services->GetModuleDirectory(coreclrModule); if (directory != NULL) { std::string path(directory); path.append("/"); g_coreclrDirectory = strdup(path.c_str()); } else { services->Output(DEBUG_OUTPUT_WARNING, "The %s module is not loaded yet in the target process\n", coreclrModule); } } if (g_coreclrDirectory != NULL) { // Load the DAC module first explicitly because SOS and DBI // have implicit references to the DAC's PAL. LoadModule(services, MAKEDLLNAME_A("mscordaccore")); m_sosHandle = LoadModule(services, MAKEDLLNAME_A("sos")); } } }
void CommandLine::DumpHelp(const char* program) { printf("%s\n", g_SuperPMIUsageFirstLine); printf("\n"); printf("Usage: %s [options] jitname [jitname2] filename.mc\n", program); printf(" jitname" PLATFORM_SHARED_LIB_SUFFIX_A " - path of jit to be tested\n"); printf(" jitname2" PLATFORM_SHARED_LIB_SUFFIX_A " - optional path of second jit to be tested\n"); printf(" filename.mc - load method contexts from filename.mc\n"); printf(" -j[it] Name - optionally -jit can be used to specify jits\n"); printf(" -l[oad] filename - optionally -load can be used to specify method contexts\n"); printf("\n"); printf("Options:\n"); printf("\n"); printf(" -boe\n"); printf(" Break on error return from compileMethod\n"); printf("\n"); printf(" -boa\n"); printf(" Break on assert from the JIT\n"); printf("\n"); printf(" -v[erbosity] messagetypes\n"); printf(" Controls which types of messages SuperPMI logs. Specify a string of\n"); printf(" characters representing message categories to enable, where:\n"); printf(" e - errors (internal fatal errors that are non-recoverable)\n"); printf(" w - warnings (internal conditions that are unusual, but not serious)\n"); printf(" m - missing (failures due to missing JIT-EE interface details)\n"); printf(" i - issues (issues found with the JIT, e.g. asm diffs, asserts)\n"); printf(" n - information (notifications/summaries, e.g. 'Loaded 5 Jitted 4 FailedCompile 1')\n"); printf(" v - verbose (status messages, e.g. 'Jit startup took '151.12ms')\n"); printf(" d - debug (lots of detailed output)\n"); printf(" a - all (enable all message types; overrides other enable message types)\n"); printf(" q - quiet (disable all output; overrides all others)\n"); printf(" e.g. '-v ew' only writes error and warning messages to the console.\n"); printf(" 'q' takes precedence over any other message type specified.\n"); printf(" Default set of messages enabled is 'ewminv'.\n"); printf("\n"); printf(" -w[riteLogFile] logfile\n"); printf(" Write log messages to the specified file.\n"); printf("\n"); printf(" -c[ompile] <indices>\n"); printf(" Compile only those method contexts whose indices are specified.\n"); printf(" Indices can be either a single index, comma separated values,\n"); printf(" a range, or the name of a .MCL file with newline delimited indices.\n"); printf(" e.g. -compile 20\n"); printf(" e.g. -compile 20,25,30,32\n"); printf(" e.g. -compile 10-99\n"); printf(" e.g. -compile 5,10-99,101,201-300\n"); printf(" e.g. -compile failed.mcl\n"); printf("\n"); printf(" -m[atchHash] <MD5 Hash>\n"); printf(" Compile only method context with specific MD5 hash\n"); printf("\n"); printf(" -e[mitMethodStats] <stats-types>\n"); printf(" Emit method statistics in CSV format to filename.mc.stats.\n"); printf(" Specify a string of characters representing statistics to emit, where:\n"); printf(" i - method IL code size\n"); printf(" a - method compiled ASM code size\n"); printf(" h - method hash to uniquely identify a method across MCH files\n"); printf(" n - method number inside the source MCH\n"); printf(" t - method throughput time\n"); printf(" * - all available method stats\n"); printf("\n"); printf(" -a[pplyDiff]\n"); printf(" Compare the compile result generated from the provided JIT with the\n"); printf(" compile result stored with the MC. If two JITs are provided, this\n"); printf(" compares the compile results generated by the two JITs.\n"); printf("\n"); printf(" -r[eproName] prefix\n"); printf(" Write out failing methods to prefix-n.mc\n"); printf("\n"); printf(" -f[ailingMCList] mclfilename\n"); printf(" Write out failing methods to mclfilename.\n"); printf(" If using -applyDiff and no -diffMCList is specified,\n"); printf(" comparison failures also get written to mclfilename.\n"); printf("\n"); printf(" -diffMCList diffMCLfilename\n"); printf(" Write out methods that differ between compilations to diffMCLfilename.\n"); printf(" This only works with -applyDiff.\n"); printf("\n"); printf(" -p[arallel] [workerCount]\n"); printf(" Run in parallel mode by spawning 'workerCount' processes to do processing.\n"); printf(" If 'workerCount' is not specified, the number of workers used is\n"); printf(" the number of processors on the machine.\n"); printf("\n"); printf(" -skipCleanup\n"); printf(" Skip deletion of temporary files created by child SuperPMI processes with -parallel.\n"); printf("\n"); printf(" -target <target>\n"); printf(" Used by the assembly differences calculator. This specifies the target\n"); printf(" architecture for cross-compilation. Currently allowed <target> value: arm64\n"); printf("\n"); #ifdef USE_COREDISTOOLS printf(" -coredistools\n"); printf(" Use disassembly tools from the CoreDisTools library\n"); printf("\n"); #endif // USE_COREDISTOOLS printf("Inputs are case sensitive.\n"); printf("\n"); printf("SuperPMI method contexts are stored in files with extension .MC, implying\n"); printf("a single method context, or .MCH, implying a set of method contexts. Either\n"); printf("extension works equivalently.\n"); printf("\n"); printf("Exit codes:\n"); printf("0 : success\n"); printf("-1 : general fatal error (e.g., failed to initialize, failed to read files)\n"); printf("-2 : JIT failed to initialize\n"); printf("1 : there were compilation failures\n"); printf("2 : there were assembly diffs\n"); printf("\n"); printf("Examples:\n"); printf(" %s " MAKEDLLNAME_A("clrjit") " test.mch\n", program); printf(" ; compile all functions in test.mch using " MAKEDLLNAME_A("clrjit") "\n"); printf(" %s -p " MAKEDLLNAME_A("clrjit") " test.mch\n", program); printf(" ; same as above, but use all available processors to compile in parallel\n"); printf(" %s -f fail.mcl " MAKEDLLNAME_A("clrjit") " test.mch\n", program); printf(" ; if there are any failures, record their MC numbers in the file fail.mcl\n"); }
bool CrashInfo::EnumerateMemoryRegionsWithDAC(const char *pszExePath, MINIDUMP_TYPE minidumpType) { PFN_CLRDataCreateInstance pfnCLRDataCreateInstance = nullptr; ICLRDataEnumMemoryRegions *clrDataEnumRegions = nullptr; HMODULE hdac = nullptr; HRESULT hr = S_OK; bool result = false; // We assume that the DAC is in the same location as this createdump exe ArrayHolder<char> dacPath = new char[MAX_LONGPATH]; strcpy_s(dacPath, MAX_LONGPATH, pszExePath); char *last = strrchr(dacPath, '/'); if (last != nullptr) { *(last + 1) = '\0'; } else { dacPath[0] = '\0'; } strcat_s(dacPath, MAX_LONGPATH, MAKEDLLNAME_A("mscordaccore")); // Load and initialize the DAC hdac = LoadLibraryA(dacPath); if (hdac == nullptr) { fprintf(stderr, "LoadLibraryA(%s) FAILED %d\n", (char*)dacPath, GetLastError()); goto exit; } pfnCLRDataCreateInstance = (PFN_CLRDataCreateInstance)GetProcAddress(hdac, "CLRDataCreateInstance"); if (pfnCLRDataCreateInstance == nullptr) { fprintf(stderr, "GetProcAddress(CLRDataCreateInstance) FAILED %d\n", GetLastError()); goto exit; } hr = pfnCLRDataCreateInstance(__uuidof(ICLRDataEnumMemoryRegions), &m_dataTarget, (void**)&clrDataEnumRegions); if (FAILED(hr)) { fprintf(stderr, "CLRDataCreateInstance(ICLRDataEnumMemoryRegions) FAILED %08x\n", hr); goto exit; } // Calls CrashInfo::EnumMemoryRegion for each memory region found by the DAC hr = clrDataEnumRegions->EnumMemoryRegions(this, minidumpType, CLRDATA_ENUM_MEM_DEFAULT); if (FAILED(hr)) { fprintf(stderr, "EnumMemoryRegions FAILED %08x\n", hr); goto exit; } result = true; exit: if (clrDataEnumRegions != nullptr) { clrDataEnumRegions->Release(); } if (hdac != nullptr) { FreeLibrary(hdac); } return result; }