Сейчас на форуме: tyns777 (+4 невидимых)

 eXeL@B —› Программирование —› Асинхронный вызов VEH.
Посл.ответ Сообщение

Ранг: 255.8 (наставник), 19thx
Активность: 0.150.01
Статус: Участник
vx

Создано: 24 сентября 2010 23:53 · Поправил: Clerk
· Личное сообщение · #1

Здрасте.
VEH вызывается синхронно, тоесть остальные потоки будут ждать возврат текущего потока из хэндлера. Это реализовано посредством критической секции RtlpCalloutEntryLock. Необходимо выполнить такую манипуляцию, дабы потоки входящие в эту кс не ожидали на ней, тоесть открыть возможность параллельной обработки исключений. Вход в кс посредством RtlEnterCriticalSection().

Главное требование - недетект антируткитами. Тоесть патч юзать нельзя.



Ранг: 369.8 (мудрец), 400thx
Активность: 0.390
Статус: Участник

Создано: 25 сентября 2010 00:27
· Личное сообщение · #2

Может лучше в нужном нам обработчике скопировать EXCEPTION_POINTERS, поправить eip на адрес асинхронного обработчика и обрабатывать исключение там?
Если обработчики лочатся критической секцией, то это явно не зря сделано, а значит не нужно это ломать.

-----
PGP key <0x1B6A24550F33E44A>




Ранг: 255.8 (наставник), 19thx
Активность: 0.150.01
Статус: Участник
vx

Создано: 25 сентября 2010 08:27
· Личное сообщение · #3

ntldr
Управление до нашего хэндлера не дойдёт, так как остальные потоки будут ждать на кс.



Ранг: 369.8 (мудрец), 400thx
Активность: 0.390
Статус: Участник

Создано: 25 сентября 2010 09:43
· Личное сообщение · #4

Clerk
Не знаю с чего ты взял, что VEH вызываются синхронно, простейший тест показывает, что это не так.

Code:
  1. #include <windows.h>
  2. #include <stdio.h>
  3.  
  4. static DWORD WINAPI test_thread(LPVOID lpThreadParameter)
  5. {
  6.          *((char *)0) = 0;
  7.  
  8.          return 0;
  9. }
  10.  
  11. static LONG CALLBACK VectoredHandler(PEXCEPTION_POINTERS ExceptionInfo)
  12. {
  13.          printf("VectoredHandler\n");
  14.  
  15.          Sleep(INFINITE);
  16.  
  17.          return EXCEPTION_CONTINUE_EXECUTION;
  18. }
  19.  
  20.  
  21. int main(int argc, char* argv[])
  22. {
  23.          int i;
  24.  
  25.          AddVectoredExceptionHandler(1, VectoredHandler);
  26.  
  27.          for (= 0; i < 100; i++) {
  28.                  CreateThread(NULL, 0, test_thread, NULL, 0, NULL);
  29.          }
  30.          Sleep(INFINITE);
  31.          return 0;
  32. }

Эта программа выводит 100 сообщений, а не одно, как ожидалось бы при последовательной обработке исключений.

-----
PGP key <0x1B6A24550F33E44A>




Ранг: 255.8 (наставник), 19thx
Активность: 0.150.01
Статус: Участник
vx

Создано: 25 сентября 2010 12:14
· Личное сообщение · #5

ntldr
В старших версиях оси эта кс не используется, поэтому у вас нет блокировки.



Ранг: 162.2 (ветеран)
Активность: 0.090
Статус: Участник

Создано: 25 сентября 2010 17:17 · Поправил: asd
· Личное сообщение · #6

Del. Сори, туплю, про eip уже написали во 2-ом посте.



Ранг: 369.8 (мудрец), 400thx
Активность: 0.390
Статус: Участник

Создано: 25 сентября 2010 17:42
· Личное сообщение · #7

Clerk пишет:
ntldrУправление до нашего хэндлера не дойдёт, так как остальные потоки будут ждать на кс.

Допустим будут ждать. Ну так VectoredHandler не будет там долго задерживаться, читай мой пост.

-----
PGP key <0x1B6A24550F33E44A>




Ранг: 255.8 (наставник), 19thx
Активность: 0.150.01
Статус: Участник
vx

Создано: 25 сентября 2010 18:14
· Личное сообщение · #8

ntldr
> в нужном нам обработчике скопировать EXCEPTION_POINTERS, поправить eip на адрес асинхронного обработчика и обрабатывать исключение там
Не понятно. Хэндлер только один, но вызывается он из разных потоков.



Ранг: 369.8 (мудрец), 400thx
Активность: 0.390
Статус: Участник

Создано: 25 сентября 2010 18:21
· Личное сообщение · #9

Code:
  1. #include <windows.h>
  2. #include <stdio.h>
  3.  
  4. static DWORD WINAPI test_thread(LPVOID lpThreadParameter)
  5. {
  6.          *((char *)0) = 0;
  7.  
  8.     return 0;
  9. }
  10.  
  11. static void async_handler()
  12. {
  13.          printf("async_handler\n");
  14.          Sleep(INFINITE);
  15. }
  16.  
  17. static LONG CALLBACK VectoredHandler(PEXCEPTION_POINTERS ExceptionInfo)
  18. {
  19.          ExceptionInfo->ContextRecord->Eip = (DWORD)async_handler;
  20.          
  21.          return EXCEPTION_CONTINUE_EXECUTION;
  22. }
  23.  
  24.  
  25. int main(int argc, char* argv[])
  26. {
  27.          int i;
  28.  
  29.          AddVectoredExceptionHandler(1, VectoredHandler);
  30.  
  31.     for (= 0; i < 100; i++) {
  32.             CreateThread(NULL, 0, test_thread, NULL, 0, NULL);
  33.     }
  34.     Sleep(INFINITE);
  35.     return 0;
  36. }

Вот что я имел ввиду. Всю долгую обработку помещаем в async_handler, который будет работать асинхронно.

-----
PGP key <0x1B6A24550F33E44A>




Ранг: 255.8 (наставник), 19thx
Активность: 0.150.01
Статус: Участник
vx

Создано: 25 сентября 2010 18:54 · Поправил: Clerk
· Личное сообщение · #10

ntldr
Тоесть предлогаете использовать спин-блокировку(SpinCount) - норм. способ, спасибо.


 eXeL@B —› Программирование —› Асинхронный вызов VEH.
:: Ваш ответ
Жирный  Курсив  Подчеркнутый  Перечеркнутый  {mpf5}  Код  Вставить ссылку 
:s1: :s2: :s3: :s4: :s5: :s6: :s7: :s8: :s9: :s10: :s11: :s12: :s13: :s14: :s15: :s16:


Максимальный размер аттача: 500KB.
Ваш логин: german1505 » Выход » ЛС
   Для печати Для печати