diff --git a/src/coreclr/debug/createdump/crashinfounix.cpp b/src/coreclr/debug/createdump/crashinfounix.cpp index b0bcb0b8c2d3b8..e4ac6bcd55905e 100644 --- a/src/coreclr/debug/createdump/crashinfounix.cpp +++ b/src/coreclr/debug/createdump/crashinfounix.cpp @@ -12,7 +12,7 @@ extern uint8_t g_debugHeaderCookie[4]; int g_readProcessMemoryErrno = 0; -bool GetStatus(pid_t pid, pid_t* ppid, pid_t* tgid, std::string* name); +bool GetProcessInfo(pid_t pid, pid_t* ppid, pid_t* tgid, std::string* name); bool CrashInfo::Initialize() @@ -65,8 +65,7 @@ CrashInfo::Initialize() m_fdPagemap = -1; } - // Get the process info - if (!GetStatus(m_pid, &m_ppid, &m_tgid, &m_name)) + if (!GetProcessInfo(m_pid, &m_ppid, &m_tgid, &m_name)) { return false; } @@ -600,6 +599,42 @@ GetStatus(pid_t pid, pid_t* ppid, pid_t* tgid, std::string* name) return true; } +bool +GetProcessInfo(pid_t pid, pid_t* ppid, pid_t* tgid, std::string* name) +{ + if(!GetStatus(pid, ppid, tgid, name)) + { + return false; + } + + // Try reading the executable name from the /proc//exe link. Prefer this name to the + // one reported by status if it is available because the status name is often truncated + char exePath[128]; + int chars = snprintf(exePath, sizeof(exePath), "/proc/%d/exe", pid); + if (chars > 0 && (size_t)chars < sizeof(exePath)) + { + struct stat sb; + if (lstat(exePath, &sb) != -1) + { + ssize_t bufSize = sb.st_size == 0 ? 4096 : sb.st_size + 1; + char *buf = static_cast(malloc(bufSize)); + if (buf != nullptr) + { + ssize_t nbytes = readlink(exePath, buf, bufSize - 1); + if (nbytes != -1) + { + buf[nbytes] = '\0'; + char* executableName = strrchr(buf, '/'); + *name = (executableName != nullptr) ? (executableName + 1) : buf; + } + free(buf); + } + } + } + + return true; +} + void ModuleInfo::LoadModule() {