Справочная информация:
Я написал многопоточное приложение в Win32, которое я запускаю из кода C #, используя Process
класс из System.Diagnostics
пространства имен.
Теперь вКод C #, я хочу получить имя / символ начального адреса каждого потока, созданного в приложении Win32, чтобы я мог записывать информацию, связанную с потоками, такую как использование процессора, в базу данных.По сути, код C # запускает несколько экземпляров приложения Win32, отслеживает их, убивает при необходимости, а затем записывает информацию / ошибки / исключения / причины / и т. Д. В базу данных.
Для этой цели я установил два Win32API, а именноSymInitialize
и SymFromAddr
в дружественном программисту API, написанном мной, как указано ниже:
extern "C"
{
//wraps SymInitialize
DllExport bool initialize_handler(HANDLE hModue);
//wraps SymFromAddr
DllExport bool get_function_symbol(HANDLE hModule, //in
void *address, //in
char *name); //out
}
И затем вызовите этот API из кода C #,используя pinvoke.Но это не работает, и GetLastError
выдает 126
код ошибки , что означает:
Указанный модуль не найден
IПередаю Process.Handle
как hModule
обеим функциям;initialize_handler
, кажется, работает, но get_function_symbol
не работает;это дает вышеуказанную ошибку.Я не уверен, что передал правильную ручку.Я попытался передать следующие дескрипторы:
Process.MainWindowHandle
Process.MainModule.BaseAddress
Оба сбоя на самом первом шаге (т. Е. При вызове initialize_handler
).Я передаю Process.Threads[i].StartAddress
в качестве второго аргумента, и это, кажется, является причиной сбоя, поскольку ProcessThread.StartAddress
, кажется, является адресом RtlUserThreadStart
функции, не адресом функции запуска, специфичной дляприложение. MSDN говорит об этом :
Каждый поток Windows фактически начинает выполнение с помощью функции, предоставляемой системой, а не функции, предоставляемой приложением.Следовательно, начальный адрес основного потока одинаков (поскольку он представляет адрес предоставляемой системой функции) для каждого процесса Windows в системе. Однако свойство StartAddress позволяет вам получить адрес начальной функции, специфичный для вашего приложения.
Но в нем не сказано, как получить адрес функции startinbg, специфичный дляприложение, использующее ProcessThread.StartAddress.
Вопрос:
Моя проблема сводится к получению начального адреса потока win32 из другого приложения (написанного на C #), как только я его получу,получить имя также, используя вышеупомянутые API.Итак, как получить начальный адрес?
Я проверил мой API поиска символов из кода C ++.Он прекрасно работает для преобразования адреса в символ, если ему дан правильный адрес для начала.
Вот мои объявления p / invoke:
[DllImport("UnmanagedSymbols.dll", SetLastError = true, CallingConvention= CallingConvention.Cdecl)]
static extern bool initialize_handler(IntPtr hModule);
[DllImport("UnmanagedSymbols.dll", SetLastError = true, CallingConvention = CallingConvention.Cdecl)]
static extern bool get_function_symbol(IntPtr hModule, IntPtr address, StringBuilder name);