DbgHelp.dll : calling SymGetModuleInfo64 from C#
I have quite strange behaviour calling SymGetModuleInfo64 from C# code.I always get ERROR_INVALID_PARAMETER (87) with Marshal.GetLastWin32Error().I have already read a lot of posts regarding problems with frequent updates of IMAGEHLP_MODULE64 struct and I just downloaded latest Debugging Tools For Windows (x86) , loaded dbghelp.dll from that location and I was quite sure it would work.Nevertheless I am getting the same error.Can anyone point me what is wrong here?
IMAGEHLP_MODULE64 struct is defined in my code as follows :
[StructLayout(LayoutKind.Sequential)]
public struct IMAGEHELP_MODULE64
{
//************************************************
public int SizeOfStruct;
public long BaseOfImage;
public int ImageSize;
public int TimeDateStamp;
public int CheckSum;
public int NumSyms;
public SymType SymType;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
public string ModuleName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
public string ImageName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
public string LoadedImageName;
//************************************************
//new elements v2
//*************************************************
[Ma开发者_如何学GorshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
public string LoadedPdbName;
public int CVSig;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 780)]
public string CVData;
public int PdbSig;
public GUID PdbSig70;
public int PdbAge;
public bool PdbUnmatched;
public bool DbgUnmatched;
public bool LineNumbers;
public bool GlobalSymbols;
public bool TypeInfo;
//************************************************
//new elements v3
//************************************************
public bool SourceIndexed;
public bool Publics;
//************************************************
//new elements v4
//************************************************
public int MachineType;
public int Reserved;
//************************************************
}
the piece of code that actually calls SymGetModuleInfo64 is like this :
public void GetSymbolInfo(IntPtr hProcess,long modBase64,out bool success)
{
success = false;
DbgHelp.IMAGEHELP_MODULE64 moduleInfo = new DbgHelp.IMAGEHELP_MODULE64();
moduleInfo.SizeOfStruct = Marshal.SizeOf(moduleInfo);
try
{
success = DbgHelp.SymGetModuleInfo64(hProcess, modBase64, out moduleInfo);
if (success)
{
//Do the stuff here
}
}
catch (Exception exc)
{
}
}
Im stuck here...always with error 87.Please someone points me to the right direction.
By the way modBase64 is value previously populated by :
modBase64 = DbgHelp.SymLoadModule64(_handle, IntPtr.Zero, fileName, null, baseAddress, size);
where _handle is process handle of process being debugged,fileName is path of current loaded module, baseAddress is address base of currently loaded module and size is of course the size of current loaded module.I call this code when I get LOAD_DLL_DEBUG_EVENT. Edit :
Sorry, I forgot to mention that SymGetModuleInfo64 signature is like this :
[DllImport("dbghelp.dll", SetLastError = true)]
public static extern bool SymGetModuleInfo64(IntPtr hProcess, long ModuleBase64, out IMAGEHELP_MODULE64 imgHelpModule);
First of all thank you for your answer.
1.Checked SymType and it's underlying type is really int. 2.Changed GUID struct to System.Guid 3.Added CharSet=CharSet.Auto in the definition of IMAGEHELP_MODULE64 struct. 4.Commented last two fields. 5.Checked the size of struct and it is 3264 bytes (Unicode) and 1672 bytes (Ansi) using Marshal.SizeOf(instance_of_the_struct).
dbghelp.dll is loaded from %windir%\system 32 folder, Im using windows server 2008 enterprise and still no success.Im still getting the same error - 87.
In second attempt I uncommented last two fields , and used dbghelp.dll from Debugging Tool For Windows (x86) directory since I downloaded newest version a couple of days ago and in SDK\inc there is dbghelp.h file which says that structure is using last two fields (v4) as like in this code snippet :
//
// module data structure
//
typedef struct _IMAGEHLP_MODULE64 {
DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_MODULE64)
DWORD64 BaseOfImage; // base load address of module
DWORD ImageSize; // virtual size of the loaded module
DWORD TimeDateStamp; // date/time stamp from pe header
DWORD CheckSum; // checksum from the pe header
DWORD NumSyms; // number of symbols in the symbol table
SYM_TYPE SymType; // type of symbols loaded
CHAR ModuleName[32]; // module name
CHAR ImageName[256]; // image name
CHAR LoadedImageName[256]; // symbol file name
// new elements: 07-Jun-2002
CHAR LoadedPdbName[256]; // pdb file name
DWORD CVSig; // Signature of the CV record in the debug directories
CHAR CVData[MAX_PATH * 3]; // Contents of the CV record
DWORD PdbSig; // Signature of PDB
GUID PdbSig70; // Signature of PDB (VC 7 and up)
DWORD PdbAge; // DBI age of pdb
BOOL PdbUnmatched; // loaded an unmatched pdb
BOOL DbgUnmatched; // loaded an unmatched dbg
BOOL LineNumbers; // we have line number information
BOOL GlobalSymbols; // we have internal symbol information
BOOL TypeInfo; // we have type information
// new elements: 17-Dec-2003
BOOL SourceIndexed; // pdb supports source server
BOOL Publics; // contains public symbols
// new element: 15-Jul-2009
DWORD MachineType; // IMAGE_FILE_MACHINE_XXX from ntimage.h and winnt.h
DWORD Reserved; // Padding - don't remove.
} IMAGEHLP_MODULE64, *PIMAGEHLP_MODULE64;
I didnt have any success using both of these versions of struct and I have no more ideas. As for address I am passing , Im pretty sure it is ok since I get it from SymLoadModule64 function as I stated before.
Hope someone will have idea what's going on here.
Try changing the last parameter (imgHelpModule) from out to ref. For an out parameter, the CLR will not marshal any data into the function, so the API will not see the value you put into SizeOfStruct.
精彩评论