DbgHelp.dll: вызов SymGetModuleInfo64 из C#
У меня довольно странное поведение при вызове SymGetModuleInfo64 из кода C#. Я всегда получаю ERROR_INVALID_PARAMETER (87) с Marshal.GetLastWin32Error(). Я уже прочитал много сообщений о проблемах с частыми обновлениями структуры IMAGEHLP_MODULE64 и только что скачал последние инструменты отладки для Windows (x86), загрузил dbghelp.dll из этого места, и я был совершенно уверен, что он будет работать. Тем не менее, я получаю ту же ошибку. Может кто-нибудь указать мне, что здесь не так?
Структура IMAGEHLP_MODULE64 определена в моем коде следующим образом:
[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
//*************************************************
[MarshalAs(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;
//************************************************
}
фрагмент кода, который фактически вызывает SymGetModuleInfo64, выглядит следующим образом:
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)
{
}
}
Я застрял здесь... всегда с ошибкой 87. Пожалуйста, кто-то указывает мне в правильном направлении.
Кстати, modBase64 - это значение, ранее заполненное:
modBase64 = DbgHelp.SymLoadModule64(_handle, IntPtr.Zero, fileName, null, baseAddress, size);
где _handle - дескриптор процесса отлаживаемого процесса, fileName - путь текущего загруженного модуля, baseAddress - адресная база текущего загруженного модуля, а размер - конечно же размер текущего загруженного модуля. Я вызываю этот код, когда получаю LOAD_DLL_DEBUG_EVENT. Редактировать:
Извините, я забыл упомянуть, что подпись SymGetModuleInfo64 выглядит следующим образом:
[DllImport("dbghelp.dll", SetLastError = true)]
public static extern bool SymGetModuleInfo64(IntPtr hProcess, long ModuleBase64, out IMAGEHELP_MODULE64 imgHelpModule);
Прежде всего, спасибо за ваш ответ.
1. Проверено SymType и его базовый тип действительно int. 2. Изменена структура GUID в System.Guid. 3. Добавлено определение CharSet=CharSet.Auto в определении структуры IMAGEHELP_MODULE64. 4.Скомментировал два последних поля. 5.Проверил размер структуры, он составляет 3264 байта (Unicode) и 1672 байта (Ansi), используя Marshal.SizeOf(instance_of_the_struct).
Файл dbghelp.dll загружен из папки%windir%\system 32, я использую Windows Server 2008 Enterprise и все еще безуспешно. По-прежнему появляется та же ошибка - 87.
Во второй попытке я раскомментировал последние два поля и использовал dbghelp.dll из каталога Debugging Tool For Windows (x86), так как я скачал последнюю версию пару дней назад, а в SDK\inc есть файл dbghelp.h, в котором говорится, что структура использует последние два поля (v4) как в этом фрагменте кода:
//
// 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;
Я не имел никакого успеха, используя обе эти версии struct, и у меня больше нет идей. Что касается адреса, который я передаю, я почти уверен, что все в порядке, поскольку я получаю его из функции SymLoadModule64, как я уже говорил ранее.
Надеюсь, кто-нибудь поймет, что здесь происходит.
1 ответ
Попробуйте изменить последний параметр (imgHelpModule) с out на ref. Для параметра out CLR не будет маршалировать какие-либо данные в функцию, поэтому API не увидит значение, которое вы поместили в SizeOfStruct.