![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Как подменить обработчик исключений? [D6, D7, Win95/98, WinXP]
Lin7 © (2004-07-27 10:57:00)Есть функция SetUnhandledExceptionFilter, с помощью которой можно подменить обработчик исключений.
Делаю:
type
P_EXCEPTION_POINTERS = ^EXCEPTION_POINTERS;
function MainFilter(P: P_EXCEPTION_POINTERS): integer; stdcall;
begin
Result := 0; // показывать системный диалог
// обработка возникших исключений
case P.ExceptionRecord.ExceptionCode of
EXCEPTION_ACCESS_VIOLATION:
begin
end;
EXCEPTION_DATATYPE_MISALIGNMENT:
begin
end;
else
begin
MessageBox(0, 'MainFilter','Error', MB_OK );
Result := 1; // не показывать системный диалог
end;
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
SetUnhandledExceptionFilter(@MainFilter);
end;
Пример взят из Инета... и не работает :(
Кто-нибудь может мне растолковать, как правильно подменить обработчик исключений всего приложения?
У самого разобраться не получается.
Примерчик бы...
Спасибо.
Игорь Шевченко (2004-07-27 17:29:00) [1]Lin7 (27.07.04 17:08) [22]
> 1. Как правильно использовать функцию SetUnhandledExceptionFilter?
Я полагаю, что в данном случае - никак.
> 2. Как можно (если это в принципе возможно) перехватить
> и обработать в одной процедуре все исключения (как обработанные
> так и не обработанные блоками try/except и try/finaly) возникающие
> в процессе?
Скорее всего, невозможно, так как исключения, возникающие в блоках initialization/finalization программы отловить в самой программе (скорее всего) не получится.
> 3. Какой методикой нужно воспользоваться, чтобы выловить
> баг в программе, если баг возникает на чужом компьютере
> и разработчик не имеет возможности отладить программу на
> этом компьютере?
Например, использовать unit JCLDebug из Jedi Library, взять его можно по адресу http://www.delphi-jedi.org, скачав оттуда библиотеку JCL - этот unit формирует log при падении программы на любом компьютере, с указанием адреса, где была ошибка и трассировкой стека.
> И так же понимаю, что врятли кто-то захочет анализировать
> несколько тысяч строк кода в поисках нестабильно появляющейся
> ошибки.
Лично я в таких случая тестирую программу по кускам, до тех пор, пока не убеждаюсь, что каждый кусок работает нормально по отдельности и куски корректно взаимодействуют между собой.
Удачи!
Lin7 (2004-07-27 17:08:00) [2]
> По какой теме давать дельный совет?
1. Как правильно использовать функцию SetUnhandledExceptionFilter?
2. Как можно (если это в принципе возможно) перехватить и обработать в одной процедуре все исключения (как обработанные так и не обработанные блоками try/except и try/finaly) возникающие в процессе?
3. Какой методикой нужно воспользоваться, чтобы выловить баг в программе, если баг возникает на чужом компьютере и разработчик не имеет возможности отладить программу на этом компьютере?
> Но я надеюсь, ты понимаешь, что не видя программы, не видя
> кода, не зная условий ее запуска (кроме того, что "на других"),
> не зная, как падает программа, трудно давать какой-либо
> дельный совет, кроме [19].
Понимаю. И так же понимаю, что врятли кто-то захочет анализировать несколько тысяч строк кода в поисках нестабильно появляющейся ошибки. :)
И на дальнейшее хотелось бы иметь возможность писать программы, формирующие отчёт о своих ошибках - над этим и работаю.
> Кроме того, ошибка может быть и не в программе, а в одной
> из DLL
Теоретически - конечно. Но в конкретном случае я этот вариант по ряду причин отбрасываю, считая, что dll написана корректно.
Игорь Шевченко (2004-07-27 16:39:00) [3]Lin7 (27.07.04 16:33)
> В смысле - намёк, что надо поучиться программы писать?
Можно и так расценивать.
> Собственно, любой создавший здесь топик, хочет чтобы БОЛЕЕ
> опытные люди дали ДЕЛЬНЫЙ совет по теме.
По какой теме давать дельный совет? По такой:
> Ситуация:
> Сделал програмку (несколько форм + пара dll + глобальный
> хук на грызуна). На моём компе ошибки не выскакивают и прога
> прекрасно работает. На других вылазят редко, но метко -
> прога иногда даже падает. Выловить ошибки не могу, т.к.
> у меня они не появляются. Утечки ресурсов MemProof не находит.
?
Но я надеюсь, ты понимаешь, что не видя программы, не видя кода, не зная условий ее запуска (кроме того, что "на других"), не зная, как падает программа, трудно давать какой-либо дельный совет, кроме [19].
Кроме того, ошибка может быть и не в программе, а в одной из DLL
Lin7 (2004-07-27 16:33:00) [4]
> ? Может, в консерватории чего-то поправить ?
??!
В смысле - намёк, что надо поучиться программы писать?
Опыт - дело наживное. Если бы я сам мог справится с проблемой я не создавал бы топика. Собственно, любой создавший здесь топик, хочет чтобы БОЛЕЕ опытные люди дали ДЕЛЬНЫЙ совет по теме.
Со своей стороны я постарался поконкретнее задать вопрос и дополнение [5].
Игорь Шевченко (2004-07-27 16:07:00) [5]
> Дык не получается ведь!
? Может, в консерватории чего-то поправить ?
Lin7 (2004-07-27 16:05:00) [6]
> Игорь Шевченко © (27.07.04 14:44) [17]
>
> try
> .....Код твоей программы
> except
> Выдача красивого сообщения
> end;
Дык не получается ведь!
Смотри здесь же выше мой пост Lin7 (27.07.04 11:38) [5]
> Для более продвинутых -
> Есть такой ключик в реестре - Image File Execution Options
> (HKLM\Software\Microsoft\Windows NT\CurrentVersion\Image
> File Execution Options) - в нем, в параметре Debugger указывается
> программа, получающая управление при всех ошибках в заданном
> приложении.
Моя программа не ориентирована на продвинутых юзеров, которые в состоянии её отладить. :)
В дополнение: я поспешил с выводами - мой код
unit SEHDebug;...
почему-то подменяет обработчик только для секций initialization/finalization отдельных модулей, а исключения возникающие в модуле формы (VCL) приходится ловить с помощью TApplicationEvents.OnException.
Эта ситуация мне не понятна - при создании формы делфя ставит свой обработчик что-ли?
Это происходит даже если на форме нет TApplicationEvents.
В программе есть пара нитей - вот что с ними делать пока не знаю.
Игорь Шевченко (2004-07-27 14:44:00) [7]
> Наоборот я хочу сам обрабатывать баги в своей проге, выдавать
> пользователю своё окно с информацией об ошибке и с чеком
> "Отправить информацию об ошибке разработчику" - отсылать
> bug-report на мой e-mail.
try
.....Код твоей программы
except
Выдача красивого сообщения
end;
Для более продвинутых -
Есть такой ключик в реестре - Image File Execution Options (HKLM\Software\Microsoft\Windows NT\CurrentVersion\Image File Execution Options) - в нем, в параметре Debugger указывается программа, получающая управление при всех ошибках в заданном приложении.
Lin7 (2004-07-27 13:54:00) [8]
> Я не совсем понимаю, что за задача стоит - чтобы глючные
> программы не сообщали о сових глюках или что ?
Вовсе нет. - Это некорректно по отношению к пользователю. Наоборот я хочу сам обрабатывать баги в своей проге, выдавать пользователю своё окно с информацией об ошибке и с чеком "Отправить информацию об ошибке разработчику" - отсылать bug-report на мой e-mail.
Не хотелось бы переводить топик в флуд.
Всем спасибо.
Думаю топик можно закрыть.
По крайней мере пока... :)
Игорь Шевченко (2004-07-27 13:42:00) [9]Lin7 (27.07.04 13:37) [14]
> Имелось ввиду: как предотвратить вывод этой мессаги.
Очевидно, переписать Run-time Library.
Я не совсем понимаю, что за задача стоит - чтобы глючные программы не сообщали о сових глюках или что ?
Lin7 (2004-07-27 13:37:00) [10]
> Игорь Шевченко © (27.07.04 13:13) [13]
>
> > Что можно/нужно сделать, что она не вылетала?
>
>
> Найти причину ее возникновения и устранить.
:)))
Некорректно выразился.
Имелось ввиду: как предотвратить вывод этой мессаги.
Хотя впрочем это не очень-то и надо...
Скажем так: желательно, но не обязательно.
Игорь Шевченко (2004-07-27 13:13:00) [11]
> Что можно/нужно сделать, что она не вылетала?
Найти причину ее возникновения и устранить.
Lin7 (2004-07-27 13:06:00) [12]
> Игорь Шевченко © (27.07.04 12:49) [11]
>
> > 1. Всё равно выскакивает "Run-time error 216..." (Delph'овая
>
> > мессага)
>
>
> к SEH не имеющая никакого отношения...
Что можно/нужно сделать, что она не вылетала?
Игорь Шевченко (2004-07-27 12:49:00) [13]
> 1. Всё равно выскакивает "Run-time error 216..." (Delph'овая
> мессага)
к SEH не имеющая никакого отношения...
Lin7 (2004-07-27 12:45:00) [14]Ага. Что-то получается...
Сделал модуль:
unit SEHDebug;
interface
uses Windows;
type
P_EXCEPTION_POINTERS = ^EXCEPTION_POINTERS;
function MainFilter(P: P_EXCEPTION_POINTERS): integer; stdcall;
implementation
function MainFilter(P: P_EXCEPTION_POINTERS): integer; stdcall;
begin
Result := 1; // Не показывать системный диалог
//Result := 0; // Показывать системный диалог
end;
procedure aa;
var
p:^integer;
begin
P := Pointer(3);
P^ := 321;
MessageBox(0,'111','2222',0);
end;
initialization
SetUnhandledExceptionFilter(@MainFilter);
aa;
end.
Похоже в таком варианте обработчик подменяется (системная мессага не вылетает), но:
1. Всё равно выскакивает "Run-time error 216..." (Delph'овая мессага)
2. Не удаётся продолжить выполнение программы.
Lin7 (2004-07-27 11:57:00) [15]
> Digitman © (27.07.04 11:48) [7]
MSDN:
The SetUnhandledExceptionFilter function enables an application to supersede the top-level exception handler of each thread and process.
Lin7 (2004-07-27 11:55:00) [16]
> Digitman © (27.07.04 11:48) [7]
>
> кто ж спорит ?
>
> но в дан.случае я на другом авторское внимание заостряю
> - установка обработчика исключения индивидуальна для каждого
> трэда в отдельности
Я правильно понял: SetUnhandledExceptionFilter - ставится на отдельные потоки??!
Вы не ошиблись?
Digitman (2004-07-27 11:48:00) [17]
> Игорь Шевченко © (27.07.04 11:31) [4]
кто ж спорит ?
но в дан.случае я на другом авторское внимание заостряю - установка обработчика исключения индивидуальна для каждого трэда в отдельности
Lin7 (2004-07-27 11:43:00) [18]
> Subdigger © (27.07.04 11:24) [3]
> public
> { Public declarations }
> procedure ExceptionHandler(Sender: TObject; E: Exception);
> end;
>
> Application.OnException := ExceptionHandler;
Часть кода моей проги расположена в секциях initialization отдельных модулей, поэтому это не сработает... (не перехватит).
Lin7 (2004-07-27 11:38:00) [19]>>VMcL © (27.07.04 11:04) [1]
Этот вопрос напрямую связан с моей проблемой, описанной в топике:
http://www.delphimaster.ru/cgi-bin/forum.pl?id=1090508016&n=0
Ситуация:
Сделал програмку (несколько форм + пара dll + глобальный хук на грызуна). На моём компе ошибки не выскакивают и прога прекрасно работает. На других вылазят редко, но метко - прога иногда даже падает. Выловить ошибки не могу, т.к. у меня они не появляются. Утечки ресурсов MemProof не находит.
Решение:
Сделать debug'овую версию, в которой будет вестись лог-файл работы проги и попробовать выловить баг так.
Вопросы:
1. Можно ли организовать try - except таким образом, чтобы ВСЕ возникающие исключения сначала обрабатывались этим блоком? - т.е. на except навесить запись в лог-файл.
2. Если кто-то сталкивался (ну наверняка сталкивались!!!) с такой проблемой - поделитесь опытом, как лучше поступить.
Есть ли какие-то особенности в организации/ведении такого лог-файла?
Может быть удастся решить мою проблему с помощью SetUnhandledExceptionFilter.
Только вопрос уже относится к WinAPI - поэтому и был задан в этой ветке.
Игорь Шевченко (2004-07-27 11:31:00) [20]Digitman © (27.07.04 11:22)
> исключения перехватываются/обрабатываются не на уровне приложения,
> а на уровнях каждого из кодовых потоков процесса приложения
Таки сложный вопрос - при необработанном исключении в одном из потоков убивается весь процесс :)