未验证 提交 d8eefc93 编写于 作者: M Mike McLaughlin 提交者: GitHub

Remove the pid argument on Windows createdump only take dumps of the parent process (#68877)

Issue: https://github.com/dotnet/runtime/issues/42646
上级 2f38fb55
......@@ -30,6 +30,7 @@ if(CLR_CMAKE_HOST_WIN32)
version.lib
dbghelp.lib
ws2_32.lib
ntdll.lib
)
else(CLR_CMAKE_HOST_WIN32)
......
......@@ -2,7 +2,17 @@
// The .NET Foundation licenses this file to you under the MIT license.
#include "createdump.h"
#include "psapi.h"
#include <psapi.h>
// The Windows SDK (winternl.h) we use doesn't have the necessary field (InheritedFromUniqueProcessId)
typedef struct _PROCESS_BASIC_INFORMATION_ {
NTSTATUS ExitStatus;
PPEB PebBaseAddress;
ULONG_PTR AffinityMask;
KPRIORITY BasePriority;
ULONG_PTR UniqueProcessId;
ULONG_PTR InheritedFromUniqueProcessId;
} PROCESS_BASIC_INFORMATION_;
//
// The Windows create dump code
......@@ -17,6 +27,16 @@ CreateDump(const char* dumpPathTemplate, int pid, const char* dumpType, MINIDUMP
ArrayHolder<char> pszName = new char[MAX_LONGPATH + 1];
std::string dumpPath;
// On Windows, createdump is restricted for security reasons to only the .NET process (parent process) that launched createdump
PROCESS_BASIC_INFORMATION_ processInformation;
NTSTATUS status = NtQueryInformationProcess(GetCurrentProcess(), PROCESSINFOCLASS::ProcessBasicInformation, &processInformation, sizeof(processInformation), NULL);
if (status != 0)
{
printf_error("Failed to get parent process id status %d\n", status);
goto exit;
}
pid = (int)processInformation.InheritedFromUniqueProcessId;
hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid);
if (hProcess == NULL)
{
......@@ -32,7 +52,7 @@ CreateDump(const char* dumpPathTemplate, int pid, const char* dumpType, MINIDUMP
{
goto exit;
}
printf_status("Writing %s to file %s\n", dumpType, dumpPath.c_str());
printf_status("Writing %s for process %d to file %s\n", dumpType, pid, 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)
......
......@@ -11,7 +11,11 @@
#define DEFAULT_DUMP_TEMPLATE "coredump.%p"
#endif
#ifdef HOST_UNIX
const char* g_help = "createdump [options] pid\n"
#else
const char* g_help = "createdump [options]\n"
#endif
"-f, --name - dump path and file name. The default is '" DEFAULT_DUMP_PATH DEFAULT_DUMP_TEMPLATE "'. These specifiers are substituted with following values:\n"
" %p PID of dumped process.\n"
" %e The process executable filename.\n"
......@@ -57,6 +61,7 @@ int __cdecl main(const int argc, const char* argv[])
const char* dumpType = "minidump with heap";
const char* dumpPathTemplate = nullptr;
bool crashReport = false;
bool help = false;
int signal = 0;
int crashThread = 0;
int exitCode = 0;
......@@ -161,61 +166,72 @@ int __cdecl main(const int argc, const char* argv[])
}
g_stdout = g_logfile;
}
else {
else if ((strcmp(*argv, "-?") == 0) || (strcmp(*argv, "--help") == 0))
{
help = true;
}
else
{
#ifdef HOST_UNIX
pid = atoi(*argv);
#else
printf_error("The pid argument is no longer supported\n");
return -1;
#endif
}
argv++;
}
}
#ifdef HOST_UNIX
if (pid == 0)
{
help = true;
}
g_ticksPerMS = GetTickFrequency() / 1000000UL;
TRACE("TickFrequency: %d ticks per ms\n", g_ticksPerMS);
#endif
if (pid != 0)
if (help)
{
ArrayHolder<char> tmpPath = new char[MAX_LONGPATH];
if (dumpPathTemplate == nullptr)
{
if (::GetTempPathA(MAX_LONGPATH, tmpPath) == 0)
{
printf_error("GetTempPath failed %s", GetLastErrorString().c_str());
return -1;
}
exitCode = strcat_s(tmpPath, MAX_LONGPATH, DEFAULT_DUMP_TEMPLATE);
if (exitCode != 0)
{
printf_error("strcat_s failed (%d)", exitCode);
return exitCode;
}
dumpPathTemplate = tmpPath;
}
// if no pid or invalid command line option
printf_error("%s", g_help);
return -1;
}
if (CreateDump(dumpPathTemplate, pid, dumpType, minidumpType, crashReport, crashThread, signal))
ArrayHolder<char> tmpPath = new char[MAX_LONGPATH];
if (dumpPathTemplate == nullptr)
{
if (::GetTempPathA(MAX_LONGPATH, tmpPath) == 0)
{
printf_status("Dump successfully written\n");
printf_error("GetTempPath failed %s", GetLastErrorString().c_str());
return ::GetLastError();
}
else
exitCode = strcat_s(tmpPath, MAX_LONGPATH, DEFAULT_DUMP_TEMPLATE);
if (exitCode != 0)
{
exitCode = -1;
printf_error("strcat_s failed (%d)", exitCode);
return exitCode;
}
dumpPathTemplate = tmpPath;
}
fflush(g_stdout);
if (g_logfile != nullptr)
{
fflush(g_logfile);
fclose(g_logfile);
}
if (CreateDump(dumpPathTemplate, pid, dumpType, minidumpType, crashReport, crashThread, signal))
{
printf_status("Dump successfully written\n");
}
else
{
// if no pid or invalid command line option
printf_error("%s", g_help);
exitCode = -1;
}
fflush(g_stdout);
if (g_logfile != nullptr)
{
fflush(g_logfile);
fclose(g_logfile);
}
#ifdef HOST_UNIX
PAL_TerminateEx(exitCode);
#endif
......
......@@ -4047,7 +4047,7 @@ BuildCreateDumpCommandLine(
}
}
commandLine.AppendPrintf("%s %d", DumpGeneratorName, GetCurrentProcessId());
commandLine.AppendASCII(DumpGeneratorName);
if (dumpName != nullptr)
{
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册