Skip to content

Commit

Permalink
Add "[createdump]" prefix to all createdump output and logging for VS…
Browse files Browse the repository at this point in the history
…4Mac (dotnet#65444)

* Add "[createdump]" prefix to all createdump for VS4Mac

To help diagnose and improve dump collection for VS4Mac, the createdump's messages and logging needed some kind of prefix.

* Add verbose createdump logging env var COMPlus_CreateDumpVerboseDiagnostics

* Code review feedback
  • Loading branch information
mikem8361 authored Mar 8, 2022
1 parent 1ec6f8e commit 3a14bd7
Show file tree
Hide file tree
Showing 15 changed files with 89 additions and 56 deletions.
16 changes: 9 additions & 7 deletions src/coreclr/debug/createdump/crashinfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ CrashInfo::~CrashInfo()
kern_return_t result = ::mach_port_deallocate(mach_task_self(), m_task);
if (result != KERN_SUCCESS)
{
fprintf(stderr, "~CrashInfo: mach_port_deallocate FAILED %x %s\n", result, mach_error_string(result));
printf_error("~CrashInfo: mach_port_deallocate FAILED %x %s\n", result, mach_error_string(result));
}
}
#endif
Expand Down Expand Up @@ -241,25 +241,25 @@ CrashInfo::InitializeDAC()
m_hdac = LoadLibraryA(dacPath.c_str());
if (m_hdac == nullptr)
{
fprintf(stderr, "LoadLibraryA(%s) FAILED %d\n", dacPath.c_str(), GetLastError());
printf_error("LoadLibraryA(%s) FAILED %d\n", dacPath.c_str(), GetLastError());
goto exit;
}
pfnCLRDataCreateInstance = (PFN_CLRDataCreateInstance)GetProcAddress(m_hdac, "CLRDataCreateInstance");
if (pfnCLRDataCreateInstance == nullptr)
{
fprintf(stderr, "GetProcAddress(CLRDataCreateInstance) FAILED %d\n", GetLastError());
printf_error("GetProcAddress(CLRDataCreateInstance) FAILED %d\n", GetLastError());
goto exit;
}
hr = pfnCLRDataCreateInstance(__uuidof(ICLRDataEnumMemoryRegions), dataTarget, (void**)&m_pClrDataEnumRegions);
if (FAILED(hr))
{
fprintf(stderr, "CLRDataCreateInstance(ICLRDataEnumMemoryRegions) FAILED %08x\n", hr);
printf_error("CLRDataCreateInstance(ICLRDataEnumMemoryRegions) FAILED %08x\n", hr);
goto exit;
}
hr = pfnCLRDataCreateInstance(__uuidof(IXCLRDataProcess), dataTarget, (void**)&m_pClrDataProcess);
if (FAILED(hr))
{
fprintf(stderr, "CLRDataCreateInstance(IXCLRDataProcess) FAILED %08x\n", hr);
printf_error("CLRDataCreateInstance(IXCLRDataProcess) FAILED %08x\n", hr);
goto exit;
}
}
Expand Down Expand Up @@ -302,7 +302,7 @@ CrashInfo::EnumerateMemoryRegionsWithDAC(MINIDUMP_TYPE minidumpType)
HRESULT hr = m_pClrDataEnumRegions->EnumMemoryRegions(this, minidumpType, CLRDATA_ENUM_MEM_DEFAULT);
if (FAILED(hr))
{
fprintf(stderr, "EnumMemoryRegions FAILED %08x\n", hr);
printf_error("EnumMemoryRegions FAILED %08x\n", hr);
return false;
}
TRACE("EnumerateMemoryRegionsWithDAC: Memory enumeration FINISHED\n");
Expand All @@ -324,7 +324,7 @@ CrashInfo::EnumerateManagedModules()
TRACE("EnumerateManagedModules: Module enumeration STARTED\n");

if (FAILED(hr = m_pClrDataProcess->StartEnumModules(&enumModules))) {
fprintf(stderr, "StartEnumModules FAILED %08x\n", hr);
printf_error("StartEnumModules FAILED %08x\n", hr);
return false;
}

Expand Down Expand Up @@ -775,6 +775,7 @@ CrashInfo::Trace(const char* format, ...)
{
va_list args;
va_start(args, format);
fprintf(stdout, "[createdump] ");
vfprintf(stdout, format, args);
fflush(stdout);
va_end(args);
Expand All @@ -788,6 +789,7 @@ CrashInfo::TraceVerbose(const char* format, ...)
{
va_list args;
va_start(args, format);
fprintf(stdout, "[createdump] ");
vfprintf(stdout, format, args);
fflush(stdout);
va_end(args);
Expand Down
6 changes: 3 additions & 3 deletions src/coreclr/debug/createdump/crashinfomac.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ CrashInfo::Initialize()
kern_return_t result = ::task_for_pid(mach_task_self(), m_pid, &m_task);
if (result != KERN_SUCCESS)
{
fprintf(stderr, "task_for_pid(%d) FAILED %x %s\n", m_pid, result, mach_error_string(result));
printf_error("task_for_pid(%d) FAILED %x %s\n", m_pid, result, mach_error_string(result));
return false;
}
return true;
Expand All @@ -37,14 +37,14 @@ CrashInfo::EnumerateAndSuspendThreads()
kern_return_t result = ::task_suspend(Task());
if (result != KERN_SUCCESS)
{
fprintf(stderr, "task_suspend(%d) FAILED %x %s\n", m_pid, result, mach_error_string(result));
printf_error("task_suspend(%d) FAILED %x %s\n", m_pid, result, mach_error_string(result));
return false;
}

result = ::task_threads(Task(), &threadList, &threadCount);
if (result != KERN_SUCCESS)
{
fprintf(stderr, "task_threads(%d) FAILED %x %s\n", m_pid, result, mach_error_string(result));
printf_error("task_threads(%d) FAILED %x %s\n", m_pid, result, mach_error_string(result));
return false;
}

Expand Down
12 changes: 6 additions & 6 deletions src/coreclr/debug/createdump/crashinfounix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ CrashInfo::Initialize()
m_fd = open(memPath, O_RDONLY);
if (m_fd == -1)
{
fprintf(stderr, "open(%s) FAILED %d (%s)\n", memPath, errno, strerror(errno));
printf_error("open(%s) FAILED %d (%s)\n", memPath, errno, strerror(errno));
return false;
}
// Get the process info
Expand Down Expand Up @@ -58,7 +58,7 @@ CrashInfo::EnumerateAndSuspendThreads()
DIR* taskDir = opendir(taskPath);
if (taskDir == nullptr)
{
fprintf(stderr, "opendir(%s) FAILED %s\n", taskPath, strerror(errno));
printf_error("opendir(%s) FAILED %s\n", taskPath, strerror(errno));
return false;
}

Expand All @@ -76,7 +76,7 @@ CrashInfo::EnumerateAndSuspendThreads()
}
else
{
fprintf(stderr, "ptrace(ATTACH, %d) FAILED %s\n", tid, strerror(errno));
printf_error("ptrace(ATTACH, %d) FAILED %s\n", tid, strerror(errno));
closedir(taskDir);
return false;
}
Expand All @@ -102,7 +102,7 @@ CrashInfo::GetAuxvEntries()
int fd = open(auxvPath, O_RDONLY, 0);
if (fd == -1)
{
fprintf(stderr, "open(%s) FAILED %s\n", auxvPath, strerror(errno));
printf_error("open(%s) FAILED %s\n", auxvPath, strerror(errno));
return false;
}
bool result = false;
Expand Down Expand Up @@ -159,7 +159,7 @@ CrashInfo::EnumerateModuleMappings()
FILE* mapsFile = fopen(mapPath, "r");
if (mapsFile == nullptr)
{
fprintf(stderr, "fopen(%s) FAILED %s\n", mapPath, strerror(errno));
printf_error("fopen(%s) FAILED %s\n", mapPath, strerror(errno));
return false;
}
// linuxGateAddress is the beginning of the kernel's mapping of
Expand Down Expand Up @@ -377,7 +377,7 @@ GetStatus(pid_t pid, pid_t* ppid, pid_t* tgid, std::string* name)
FILE *statusFile = fopen(statusPath, "r");
if (statusFile == nullptr)
{
fprintf(stderr, "GetStatus fopen(%s) FAILED\n", statusPath);
printf_error("GetStatus fopen(%s) FAILED\n", statusPath);
return false;
}

Expand Down
6 changes: 3 additions & 3 deletions src/coreclr/debug/createdump/crashreportwriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ CrashReportWriter::WriteCrashReport(const std::string& dumpFileName)
{
std::string crashReportFile(dumpFileName);
crashReportFile.append(".crashreport.json");
printf("Writing crash report to file %s\n", crashReportFile.c_str());
printf_status("Writing crash report to file %s\n", crashReportFile.c_str());
try
{
if (!OpenWriter(crashReportFile.c_str())) {
Expand All @@ -44,7 +44,7 @@ CrashReportWriter::WriteCrashReport(const std::string& dumpFileName)
}
catch (const std::exception& e)
{
fprintf(stderr, "Writing the crash report file FAILED\n");
printf_error("Writing the crash report file FAILED\n");

// Delete the partial json file on error
remove(crashReportFile.c_str());
Expand Down Expand Up @@ -271,7 +271,7 @@ CrashReportWriter::OpenWriter(const char* fileName)
m_fd = open(fileName, O_WRONLY|O_CREAT|O_TRUNC, S_IWUSR | S_IRUSR);
if (m_fd == -1)
{
fprintf(stderr, "Could not create json file %s: %d %s\n", fileName, errno, strerror(errno));
printf_error("Could not create json file %s: %d %s\n", fileName, errno, strerror(errno));
return false;
}
Write("{\n");
Expand Down
2 changes: 2 additions & 0 deletions src/coreclr/debug/createdump/createdump.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,3 +111,5 @@ typedef int T_CONTEXT;
bool FormatDumpName(std::string& name, const char* pattern, const char* exename, int pid);
bool CreateDump(const char* dumpPathTemplate, int pid, const char* dumpType, MINIDUMP_TYPE minidumpType, bool crashReport, int crashThread, int signal);

extern void printf_status(const char* format, ...);
extern void printf_error(const char* format, ...);
8 changes: 4 additions & 4 deletions src/coreclr/debug/createdump/createdumpunix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ CreateDump(const char* dumpPathTemplate, int pid, const char* dumpType, MINIDUMP
{
goto exit;
}
printf("Gathering state for process %d %s\n", pid, crashInfo->Name().c_str());
printf_status("Gathering state for process %d %s\n", pid, crashInfo->Name().c_str());

if (signal != 0 || crashThread != 0)
{
printf("Crashing thread %08x signal %08x\n", crashThread, signal);
printf_status("Crashing thread %08x signal %08x\n", crashThread, signal);
}

// Suspend all the threads in the target process and build the list of threads
Expand Down Expand Up @@ -52,7 +52,7 @@ CreateDump(const char* dumpPathTemplate, int pid, const char* dumpType, MINIDUMP
{
goto exit;
}
fprintf(stdout, "Writing %s to file %s\n", dumpType, dumpPath.c_str());
printf_status("Writing %s to file %s\n", dumpType, dumpPath.c_str());

// Write the actual dump file
if (!dumpWriter.OpenDump(dumpPath.c_str()))
Expand All @@ -61,7 +61,7 @@ CreateDump(const char* dumpPathTemplate, int pid, const char* dumpType, MINIDUMP
}
if (!dumpWriter.WriteDump())
{
fprintf(stderr, "Writing dump FAILED\n");
printf_error( "Writing dump FAILED\n");

// Delete the partial dump file on error
remove(dumpPath.c_str());
Expand Down
10 changes: 5 additions & 5 deletions src/coreclr/debug/createdump/createdumpwindows.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,24 +20,24 @@ CreateDump(const char* dumpPathTemplate, int pid, const char* dumpType, MINIDUMP
hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid);
if (hProcess == NULL)
{
fprintf(stderr, "Invalid process id '%d' error %d\n", pid, GetLastError());
printf_error("Invalid process id '%d' error %d\n", pid, GetLastError());
goto exit;
}
if (GetModuleBaseNameA(hProcess, NULL, pszName, MAX_LONGPATH) <= 0)
{
fprintf(stderr, "Get process name FAILED %d\n", GetLastError());
printf_error("Get process name FAILED %d\n", GetLastError());
goto exit;
}
if (!FormatDumpName(dumpPath, dumpPathTemplate, pszName, pid))
{
goto exit;
}
printf("Writing %s to file %s\n", dumpType, dumpPath.c_str());
printf_status("Writing %s to file %s\n", dumpType, dumpPath.c_str());

hFile = CreateFileA(dumpPath.c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
fprintf(stderr, "Invalid dump path '%s' error %d\n", dumpPath.c_str(), GetLastError());
printf_error("Invalid dump path '%s' error %d\n", dumpPath.c_str(), GetLastError());
goto exit;
}

Expand All @@ -54,7 +54,7 @@ CreateDump(const char* dumpPathTemplate, int pid, const char* dumpType, MINIDUMP
int err = GetLastError();
if (err != HRESULT_FROM_WIN32(ERROR_PARTIAL_COPY))
{
fprintf(stderr, "Write dump FAILED 0x%08x\n", err);
printf_error("Write dump FAILED 0x%08x\n", err);
break;
}
}
Expand Down
6 changes: 3 additions & 3 deletions src/coreclr/debug/createdump/dumpname.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ FormatDumpName(std::string& name, const char* pattern, const char* exename, int
const char* p = pattern;
if (*p == '|')
{
fprintf(stderr, "Pipe syntax in dump name not supported\n");
printf_error("Pipe syntax in dump name not supported\n");
return false;
}

Expand Down Expand Up @@ -81,7 +81,7 @@ FormatDumpName(std::string& name, const char* pattern, const char* exename, int
ArrayHolder<char> buffer = new char[MAX_LONGPATH + 1];
if (gethostname(buffer, MAX_LONGPATH) != 0)
{
fprintf(stderr, "Could not get the host name for dump name: %d\n",
printf_error("Could not get the host name for dump name: %d\n",
#ifdef HOST_WINDOWS
WSAGetLastError());
#else
Expand Down Expand Up @@ -114,7 +114,7 @@ FormatDumpName(std::string& name, const char* pattern, const char* exename, int
// pid of dumped process
case 'P':
default:
fprintf(stderr, "Invalid dump name format char '%c'\n", *p);
printf_error("Invalid dump name format char '%c'\n", *p);
return false;
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/coreclr/debug/createdump/dumpwriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ DumpWriter::OpenDump(const char* dumpFileName)
m_fd = open(dumpFileName, O_WRONLY|O_CREAT|O_TRUNC, S_IWUSR | S_IRUSR);
if (m_fd == -1)
{
fprintf(stderr, "Could not open output %s: %d %s\n", dumpFileName, errno, strerror(errno));
printf_error("Could not open output %s: %d %s\n", dumpFileName, errno, strerror(errno));
return false;
}
return true;
Expand All @@ -46,7 +46,7 @@ DumpWriter::WriteData(int fd, const void* buffer, size_t length)
} while (written == -1 && errno == EINTR);

if (written < 1) {
fprintf(stderr, "WriteData FAILED %d %s\n", errno, strerror(errno));
printf_error("WriteData FAILED %d %s\n", errno, strerror(errno));
return false;
}
done += written;
Expand Down
9 changes: 4 additions & 5 deletions src/coreclr/debug/createdump/dumpwriterelf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ DumpWriter::WriteDump()
// and then laydown the memory blocks
if (finalNoteAlignment > 0) {
if (finalNoteAlignment > sizeof(m_tempBuffer)) {
fprintf(stderr, "finalNoteAlignment %zu > sizeof(m_tempBuffer)\n", finalNoteAlignment);
printf_error("finalNoteAlignment %zu > sizeof(m_tempBuffer)\n", finalNoteAlignment);
return false;
}
memset(m_tempBuffer, 0, finalNoteAlignment);
Expand Down Expand Up @@ -189,13 +189,13 @@ DumpWriter::WriteDump()
size_t read = 0;

if (!m_crashInfo.ReadProcessMemory((void*)address, m_tempBuffer, bytesToRead, &read)) {
fprintf(stderr, "ReadProcessMemory(%" PRIA PRIx64 ", %08zx) FAILED\n", address, bytesToRead);
printf_error("ReadProcessMemory(%" PRIA PRIx64 ", %08zx) FAILED\n", address, bytesToRead);
return false;
}

// This can happen if the target process dies before createdump is finished
if (read == 0) {
fprintf(stderr, "ReadProcessMemory(%" PRIA PRIx64 ", %08zx) returned 0 bytes read\n", address, bytesToRead);
printf_error("ReadProcessMemory(%" PRIA PRIx64 ", %08zx) returned 0 bytes read\n", address, bytesToRead);
return false;
}

Expand All @@ -209,8 +209,7 @@ DumpWriter::WriteDump()
}
}

printf("Written %" PRId64 " bytes (%" PRId64 " pages) to core file\n", total, total / PAGE_SIZE);

printf_status("Written %" PRId64 " bytes (%" PRId64 " pages) to core file\n", total, total / PAGE_SIZE);
return true;
}

Expand Down
8 changes: 4 additions & 4 deletions src/coreclr/debug/createdump/dumpwritermacho.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ DumpWriter::WriteDump()
if (alignment > 0)
{
if (alignment > sizeof(m_tempBuffer)) {
fprintf(stderr, "Segment alignment %llu > sizeof(m_tempBuffer)\n", alignment);
printf_error("Segment alignment %llu > sizeof(m_tempBuffer)\n", alignment);
return false;
}
memset(m_tempBuffer, 0, alignment);
Expand Down Expand Up @@ -264,13 +264,13 @@ DumpWriter::WriteSegments()
size_t read = 0;

if (!m_crashInfo.ReadProcessMemory((void*)address, m_tempBuffer, bytesToRead, &read)) {
fprintf(stderr, "ReadProcessMemory(%" PRIA PRIx64 ", %08zx) FAILED\n", address, bytesToRead);
printf_error("ReadProcessMemory(%" PRIA PRIx64 ", %08zx) FAILED\n", address, bytesToRead);
return false;
}

// This can happen if the target process dies before createdump is finished
if (read == 0) {
fprintf(stderr, "ReadProcessMemory(%" PRIA PRIx64 ", %08zx) returned 0 bytes read\n", address, bytesToRead);
printf_error("ReadProcessMemory(%" PRIA PRIx64 ", %08zx) returned 0 bytes read\n", address, bytesToRead);
return false;
}

Expand All @@ -284,6 +284,6 @@ DumpWriter::WriteSegments()
}
}

printf("Written %" PRId64 " bytes (%" PRId64 " pages) to core file\n", total, total / PAGE_SIZE);
printf_status("Written %" PRId64 " bytes (%" PRId64 " pages) to core file\n", total, total / PAGE_SIZE);
return true;
}
Loading

0 comments on commit 3a14bd7

Please sign in to comment.