I am currently developing a C# application that is used to monitor few other processes. I want to take the dumps of these processes occasionally. For this, currently I am PInvoking MiniDumpWriteDump()
function. I have both a command line utility and a graphical utility, which PInvokes the MiniDumpWriteDump()
function. The problem I am currently facing is that I get perfect memory dumps when using the command line utility, but from the graphical utility that calls the same function, it creates an empty file every time( even when run as administrator ).
The GetLastWin32Error()
gives 0x80000057
- Parameter is invalid
, but I am passing exactly the same values to my PInvoked function in both cases. So I am suspecting the invalid value error is from some call the MiniDumpWriteDump()
is making internally and my best guess is that this is a process privilege issue. I would like to know a few things here :
SE_DEBUG_NAME
privilege from my utility using C# ( without PInvoking AdjustTokenPrivileges()
and associated functions ) ?Here is My PInvoke declaration :
public enum Typ : uint
{
// From dbghelp.h:
MiniDumpNormal = 0x00000000,
MiniDumpWithDataSegs = 0x00000001,
MiniDumpWithFullMemory = 0x00000002,
MiniDumpWithHandleData = 0x00000004,
MiniDumpFilterMemory = 0x00000008,
MiniDumpScanMemory = 0x00000010,
MiniDumpWithUnloadedModules = 0x00000020,
MiniDumpWithIndirectlyReferencedMemory = 0x00000040,
MiniDumpFilterModulePaths = 0x00000080,
MiniDumpWithProcessThreadData = 0x00000100,
MiniDumpWithPrivateReadWriteMemory = 0x00000200,
MiniDumpWithoutOptionalData = 0x00000400,
MiniDumpWithFullMemoryInfo = 0x00000800,
MiniDumpWithThreadInfo = 0x00001000,
MiniDumpWithCodeSegs = 0x00002000,
MiniDumpWithoutAuxiliaryState = 0x00004000,
MiniDumpWithFullAuxiliaryState = 0x00008000,
MiniDumpWithPrivateWriteCopyMemory = 0x00010000,
MiniDumpIgnoreInaccessibleMemory = 0x00020000,
MiniDumpWithTokenInformation = 0x00040000,
MiniDumpValidTypeFlags = 0x0003ffff,
};
[DllImport("dbghelp.dll",
EntryPoint = "MiniDumpWriteDump",
CallingConvention = CallingConvention.StdCall,
CharSet = CharSet.Unicode,
ExactSpelling = true, SetLastError = true)]
static extern bool MiniDumpWriteDump(
IntPtr hProcess,
uint processId,
IntPtr hFile,
uint dumpType,
IntPtr expParam,
IntPtr userStreamParam,
IntPtr callbackParam);
public static bool Write(string fileName, IntPtr prochandle, uint procid)
{
return Write(fileName, (Typ.MiniDumpWithFullMemory|Typ.MiniDumpWithDataSegs|Typ.MiniDumpWithHandleData|Typ.MiniDumpWithThreadInfo|Typ.MiniDumpWithTokenInformation), prochandle, procid);
}
public static bool Write(string fileName, Typ dumpTyp, IntPtr prochandle, uint procid)
{
using (var fs = new System.IO.FileStream(fileName, System.IO.FileMode.Create, System.IO.FileAccess.Write, System.IO.FileShare.None))
{
bool bRet = MiniDumpWriteDump(
prochandle,
procid,
fs.SafeFileHandle.DangerousGetHandle(),
(uint)dumpTyp,
IntPtr.Zero,
IntPtr.Zero,
IntPtr.Zero);
if (!bRet)
{
throw new System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error());
}
return bRet;
}
}
}
Here is how I call it (using the same function dump() from both console and GUI application):
void dump(procId, filePath)
{
Process p = Process.GetProcessById(procId);
MiniDumper.Write(filePath, p.Handle, (uint)p.Id);
}
User contributions licensed under CC BY-SA 3.0