Русский / Russian English / Английский

Сейчас на форуме: maksimmaksim_75, _MBK_ (+3 невидимых)
 · Начало · Статистика · Регистрация · Поиск · ПРАВИЛА ФОРУМА · Язык · RSS ·

 eXeL@B —› Основной форум —› Обработка исключения на Windows Server 2008
Посл.ответ Сообщение


Ранг: 391.8 (мудрец)
Статус: Участник
REVENGE сила, БеХоЦе могила

Создано: 27 ноября 2013 16:46 New!
Цитата · Личное сообщение · #1

Разбираюсь с программой версии bCAD 3.10
http://www.propro.ru/ru/Downloads/Install.aspx

Проблема следующая: программа отлично работает в Windows 7, но не работает на Windows Server

Начал разбираться почему. Оказывается Windows 7 и Windows Server по разному отрабатывают вот такой код:
Code:
  1. 7C424136  50             PUSH EAX                                         ; Arguments => OFFSET LOCAL.1
  2. 7C424137  6A 01          PUSH 1                                           ; ArgCount = 1
  3. 7C424139  6A 00          PUSH 0                                           ; Flags = EXCEPTION_CONTINUABLE
  4. 7C42413B  68 78563402    PUSH 2345678                                     ; Code = 2345678
  5. 7C424140  FF15 0C10407C  CALL DWORD PTR DS:[<&KERNEL32.RaiseException>]   ; KERNEL32.RaiseException


Если Windows 7 осталвяет это исключение в себе, то на серверной версии оси вылетает окошко:

Code:
  1. Сигнатура проблемы:
  2.   Имя события проблемы:    APPCRASH
  3.   Имя приложения: bcjsrv.exe
  4.   Версия приложения:       3.10.1.1168
  5.   Отметка времени приложения:       4c8f0b1a
  6.   Имя модуля с ошибкой:    KERNELBASE.dll
  7.   Версия модуля с ошибкой: 6.1.7601.18229
  8.   Отметка времени модуля с ошибкой: 51fb1116
  9.   Код исключения: 02345678
  10.   Смещение исключения:     0000c41f
  11.   Версия ОС:      6.1.7601.2.1.0.272.7
  12.   Код языка:      1049
  13.   Дополнительные сведения 1:        bb0e
  14.   Дополнительные сведения 2:        bb0efd916a17e3c0bf7af55e87d1fe92
  15.   Дополнительные сведения 3:        29a0
  16.   Дополнительные сведения 4:        29a0f0d23e28c6706a266b5d242f2020


Причем под Олькой это окошко не появляется. Проблема возникает только тогда, когда я работаю с программой в обычном режиме, не под отладкой.

Вопрос: Как мне заставить Windows Server обработать исключение по тихиму?
Можно ли как-то переловить и обработать это исключение своим встроенным кодом?


Ранг: 72.3 (постоянный)
Статус: Участник

Создано: 27 ноября 2013 17:47 New!
Цитата · Личное сообщение · #2

Можно, обычный фолт. VEH ставите и ловите его. Ну а если фолт возникает, значит где то что то пошло не так как надо. Надо лечить болезнь, а не устранять симптомы

| Сообщение посчитали полезным: ajax



Ранг: 391.8 (мудрец)
Статус: Участник
REVENGE сила, БеХоЦе могила

Создано: 27 ноября 2013 17:54 New!
Цитата · Личное сообщение · #3

Лечить симптомы должны разработчики приложения, которые имеют исходники, а не я ;)

>Можно, обычный фолт. VEH ставите и ловите его.

Где и как его ставить? Можно с примерами?


Ранг: 72.3 (постоянный)
Статус: Участник

Создано: 27 ноября 2013 17:57 New!
Цитата · Личное сообщение · #4

--> Link <--

| Сообщение посчитали полезным: Maximus



Ранг: 391.8 (мудрец)
Статус: Участник
REVENGE сила, БеХоЦе могила

Создано: 27 ноября 2013 18:02 · Поправил: Maximus New!
Цитата · Личное сообщение · #5

Какой из VEH мне нужен (continue, exception)?

Сработает ли фильтр если я буду его устанавливать через dll, внедренную в адресное пространство программы?

Что должна возращать моя процедура, чтобы программа не крашилась?


Ранг: 334.7 (мудрец)
Статус: Участник
born to be evil

Создано: 27 ноября 2013 18:28 · Поправил: ajax New!
Цитата · Личное сообщение · #6

Maximus
1. exception
2. должен
3. EXCEPTION_CONTINUE_EXECUTION
типа этого из и-нета. свои сырки сейчас не могу найти
Code:
  1. unit profs_win32exceptiontrap;
  2. {$mode objfpc}
  3. interface
  4.  
  5. // increase the reference count (install the handler it if it was zero)
  6. procedure AddHandler;
  7. // decrease the reference count and if reaching zero remove the handler
  8. procedure RemoveHandler;
  9.  
  10. implementation
  11.  
  12. uses
  13.   Windows, SysUtils;
  14.  
  15. var
  16.   ExceptionHandlerRefCount: Integer = 0;
  17.   ExHandle: Pointer;
  18.   ThisModuleHandle: THandle;
  19.   ThisModuleName: AnsiString;
  20.  
  21. threadvar
  22.   ExObject : EExternal;
  23.  
  24. function AddVectoredExceptionHandler(FirstHandler: DWORD; VectoredHandler: pointer): pointer; stdcall; external 'kernel32.dll' name 'AddVectoredExceptionHandler';
  25. function RemoveVectoredExceptionHandler(VectoredHandlerHandle: pointer): ULONG; stdcall; external 'kernel32.dll' name 'RemoveVectoredExceptionHandler';
  26.  
  27. function GetModuleByAddr(addr: pointer): THandle;
  28. var
  29.   Tmm: TMemoryBasicInformation;
  30. begin
  31.   if VirtualQuery(addr, @Tmm, SizeOf(Tmm)) <> sizeof(Tmm)
  32.     then Result := 0
  33.     {$hints off}
  34.     else Result := THandle(Tmm.AllocationBase);
  35.     {$hints on}
  36. end;
  37.  
  38. function ExceptionHandler(Info: PEXCEPTION_POINTERS): LongInt; stdcall;
  39. var
  40.   ExCode : DWORD;
  41.   ExAddr : Pointer;
  42.   ExModule : THandle;
  43. label
  44.   lblRaise;
  45. begin
  46.   ExCode := Info^.ExceptionRecord^.ExceptionCode;
  47.   if ExCode = $40010006 then // ignore debug print
  48.     exit(EXCEPTION_CONTINUE_SEARCH);
  49.  
  50.   ExAddr := Info^.ExceptionRecord^.ExceptionAddress;
  51.   ExModule := GetModuleByAddr(ExAddr);
  52.  
  53.   // did it happen in the same module where this handler resides?
  54.   if ExModule = ThisModuleHandle then begin
  55.  
  56.     // after preparing a native FPC exception object we will clear the
  57.     // Windows exception and manipulate the CPU instruction pointer to point
  58.     // exactly to the place where it will be raised with raise so it can
  59.     // then be properly caught by except. We can't just raise it directly
  60.     // from here because we are inside the Windows exception handler and
  61.     // windows expects this function to return and for Windows the exception
  62.     // is already finished when our FPC try/raise/except mechanism starts.
  63.     ExObject := EExternal.Create(Format('Exception %x at %p', [ExCode, ExAddr]));
  64.     {$hints off}
  65.     Info^.ContextRecord^.Eip := PtrUInt(@lblRaise);
  66.     {$hints on}
  67.     exit(EXCEPTION_CONTINUE_EXECUTION);
  68.  
  69.   end else begin
  70.  
  71.     // this exception happened somewhere else, we might not be able to handle it,
  72.     // so we will pass it on to the next handler but we still print a message
  73.     // because it might at least be interesting to know about it for debugging.
  74.     OutputDebugString(PChar(Format('exception %x at %p in %s -> EXCEPTION_CONTINUE_SEARCH', [ExCode, ExAddr, GetModuleName(ExModule)])));
  75.     exit(EXCEPTION_CONTINUE_SEARCH);
  76.   end;
  77.  
  78.   // the following will never be reached *during* this function call,
  79.   // instead it will be jumped to and executed *after* the handler has
  80.   // returned and windows restarts execution at the new position of eip.
  81.   lblRaise:
  82.   Raise ExObject; // this can be caught with try/except
  83. end;
  84.  
  85. procedure AddHandler;
  86. begin
  87.   if ExceptionHandlerRefCount = 0 then begin
  88.     ExHandle := AddVectoredExceptionHandler(1, @ExceptionHandler);
  89.     ThisModuleHandle := GetModuleByAddr(@ExceptionHandler);
  90.     ThisModuleName := GetModuleName(ThisModuleHandle);
  91.     OutputDebugString(PChar(Format('installed exception handler for %s', [ThisModuleName])));
  92.   end;
  93.   ExceptionHandlerRefCount += 1;
  94. end;
  95.  
  96. procedure RemoveHandler;
  97. begin
  98.   if ExceptionHandlerRefCount > 0 then begin
  99.     ExceptionHandlerRefCount -= 1;
  100.     if ExceptionHandlerRefCount = 0 then begin
  101.       RemoveVectoredExceptionHandler(ExHandle);
  102.       OutputDebugString(PChar(Format('removed exception handler for %s', [ThisModuleName])));
  103.     end;
  104.   end;
  105. end;
  106.  
  107. begin
  108.   // most non-FPC and non-Borland apps do not want FPU exceptions
  109.   // (they might crash) so we immediately undo FPC's FPU unmasking.
  110.   Set8087CW(Get8087CW or $3f);
  111. end.

| Сообщение посчитали полезным: Maximus, tihiy_grom



Ранг: 72.3 (постоянный)
Статус: Участник

Создано: 28 ноября 2013 02:07 · Поправил: Dr0p New!
Цитата · Личное сообщение · #7

Maximus

> Сработает ли фильтр если я буду его устанавливать через dll, внедренную в адресное пространство программы?

VEH в отличие от SEH ничем не защищён. Не имеет значения где расположен хэндлер.

> Что должна возращать моя процедура, чтобы программа не крашилась?

Для этого нужно знать причину фолта. Полагаю что следует просто вернуть управление(EXCEPTION_CONTINUE_EXECUTION), раз в других версиях робит. Да и вообще, вы не туда копаете. Не нужна никакая обработка, достаточно занопить кидающий фолт код ну или поправить его.


Ранг: 391.8 (мудрец)
Статус: Участник
REVENGE сила, БеХоЦе могила

Создано: 28 ноября 2013 09:56 · Поправил: Maximus New!
Цитата · Личное сообщение · #8

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

DrOp, занопил участок, который я кинул первым в листинге. Программа заработала. Тестирую результат.
Code:
  1. 7C424136     RET


Более глубоко копать могут только разработчики, тем более причина такого поведения программы яcна:
http://www.voyce.com/index.php/2008/10/01/troubleshooting-an-invalidprogramexception/

Но им видимо лениво это делать:
http://www.propro.ru/forum/viewtopic.php?f=6&t=6510&view=next


Ранг: 391.8 (мудрец)
Статус: Участник
REVENGE сила, БеХоЦе могила

Создано: 12 декабря 2013 17:05 New!
Цитата · Личное сообщение · #9

В итоге написал dll-ку, которая отвязывает прогу от железяки и дает возможность запускать прогу на серверных осях. Тему закрываю.
 eXeL@B —› Основной форум —› Обработка исключения на Windows Server 2008
Эта тема закрыта. Ответы больше не принимаются.

Видеокурс ВЗЛОМ