Форум: "Система";
Поиск по всему сайту: delphimaster.net;
Текущий архив: 2002.02.07;
Скачать: [xml.tar.bz2];




Вниз

Подскажите, пожалуйста, как перехватить сообщение о том, что программа выполнила недопустимую операцию и будет закрыта. 


Poroh   (2001-10-24 02:57) [0]

На мой взгляд в любую серьёзную программу стоило бы добавить возможность сохранения изменений при возникновении такой ошибки.



Digitman   (2001-10-24 08:47) [1]

>Poroh
Ты, видимо, слабо представляешь себе, что такое "недопустимая операция", и что происходит в ОС и CPU при ее возникновении.



Cold -= AYS =-   (2001-10-24 11:01) [2]

помогите, как перехватить зависание виндов :)

используй try...except, try...finally



Digitman   (2001-10-24 11:03) [3]

>Cold -= AYS =-
try...except, try...finally и сабж - совершенно разные вещи.



Вольный Стрелок   (2001-10-24 11:17) [4]

2 Digitman ©
а где можно почитать про эту самую недопустимую. и как она может возникнуть, если компилятор не может сгенерить процу команду, которой нет.



Yevhen Bilevych   (2001-10-24 11:26) [5]

В правильно и грамотно написанной программе недопустимых операций не бывает.
А сабж - нормальный процесс самосохранения ОС. Лучше пожертвовать одной
программой, чем завалить всю работу на машине. Языки высокого уровня (в т.ч.
Object Pascal и C++) а также сама Win предусматривают блоки типа try...except,
try...finally. Если у тебя в программе есть опасное место, поставь туда охранные блоки.
Если тебя интересует не твоя программа, то все вопросы к разработчику.



Digitman   (2001-10-24 11:34) [6]

>Вольный Стрелок
Почитать про это можно в любом справочнике по системе команд CPU. Любая команда, не относящаяся к этойсистеме команд



Digitman   (2001-10-24 11:39) [7]

>Вольный Стрелок
Почитать про это можно в любом справочнике по системе команд CPU. Любая команда, не относящаяся к этой системе команд, считается недопустимой.
Возникнуть она может, например, если сегмент кода/стека в процессе выполнения задачи был тем или иным образом некорректно модифицирован, в рез-те чего в нем появились инструкции/данные, выполнить/обработать которые CPU не в состоянии, поскольку он просто не знает как это сделать и что в результате получится)

Компилятор не может "сгенерить процу команду, которой нет", если не применяются спец.трюки, основанные на возможности иниц-вать фрагмент кодового сегмента как статические данные .



Anatoly Podgoretsky   (2001-10-24 14:03) [8]

Может

asm
db XXX
end



Anatoly Podgoretsky   (2001-10-24 14:06) [9]

Да зачем ставить знак равенства между "недопустимая операция" и "недопустимая команда"



Someone   (2001-10-25 05:17) [10]

2 Digitman
Если разрешите еще один вопрос. Некоторое время назад встретил ситуацию, при которой вылетала такая же ошибка о программе, но некоторые потоки ее продолжали работу нормально. Так вот - можно ли в этих потоках узнать о происшедшем?
Долго пытался вспомнить что же это было, но увы :) Поэтому могу и ошибаться. Может быть продолжали работать не потоки, а процессы запущенные этой программой. В таком случае заранее извиняюсь.



Alien   (2001-10-25 07:16) [11]

>Someone
Когда завершается процесс освобождаются ВСЕ ресурсы, которые он когда-либо захватывал. И в том числе потоки. Причём не важно как этот процесс завершается корректно или нет. Так что ситуация, которую вы описали невозможна в принципе.



Digitman   (2001-10-25 08:56) [12]

>Someone
<Alien> совершенно верно говорит - если процесс завершается (в дан. случае - принудительно, по инициативе ОС из-за попытки выполнения недопустимой операции), то с выполнения снимаются ВСЕ потоки - основной (собственно поток процесса) и дополнительные (если они были созданы в контексте процесса). Да по иному и быть не может, потому что все потоки разделяют один и тот же кодовый сегмент (т.е., в них выполняются одни и те же инструкции CPU), и, если в исп.коде встретилась некая инструкция, интерпретируемая CPU при попытке ее выполнения как ошибочная, эта инструкция В ПРИНЦИПЕ не может быть выполнена НИ В ОДНОМ потоке (неважно - в осн. или доп.), и дальнейшее выполнение задачи бессмысленно - ОС аварийно снимает процесс с выполнения, освобождая ресурсы, ассоциированные со всеми работавшими потоками процесса.
Так что узнать ничего нельзя (потоков-то уже нет !)... за исключением лаконичной информации, любезно выдаваемой ОС в виде состояния регистров CPU, точки в сегменте кода, вызвавшей коллизию и (в ряде случаев) имени субмодуля задачи, в контексте которого коллизия и приключилась.

А вот порожденный процесс в о многих случаях действительно может продолжать свое существование даже после краха родительского процесса. Так что, скорее всего, ты ошибочно принял "деятельность" порожденного процесса за "деятельность" некоего незавершенного доп. потока "безвременно умершего" родительского процесса.



y-soft   (2001-10-25 22:28) [13]

>Digitman
Сказанное Вами абсолютно верно при принудительном завершении процесса.
А что будет в случае, если первичный поток завершился, а хотя бы один из дополнительных продолжает работать, не провоцируя ОС на решительные действия (понятно, что процесс в этом случае продолжает существовать, не подавая внешних признаков, т.к. вся прорисовка, обработка оконных сообщений и т.п. обычно производится именно в первичном потоке)? Наверное Someone такой случай и имел в виду

Под Win9X довольно типичное явление, особенно для продуктов одной известной фирмы :)



Alien   (2001-10-26 01:45) [14]

> y-soft ©
Опять неувязочка. Когда завершается первичноый поток, завершается процесс. По другому не бывает. Так что учите мат часть :)



Someone   (2001-10-26 05:09) [15]

2 Alien & Digitman
Спасибо за ответ. Требует только уточнения тот факт, что "ПРОЦЕСС" (и все, что "иже с ним") завершается ДО сообщения юзеру об ошибке, а не после того, как оный нажмет ОК.
Но, память - ужастная штука. То, что я забыл, кажется мне совершенно другим. И не дает жить спокойно, несмотря на логику.



y-soft   (2001-10-27 18:31) [16]

>Alien

За совет относительно матчасти спасибо. Только IMHO все-таки ее лучше не заучивать, а изучать

Привожу маленький пример, демонстрирующий сказанное мной ранее. Понаблюдайте за его поведением в любом внешнем отладчике (можно даже в TaskManager из NT).

program LifeAfterDeath;
{$APPTYPE CONSOLE}
uses
Windows,SysUtils;
var
AddID : Cardinal;
const
PAUSE = 5000;
PRIMARY_EXIT_CODE = 1;
ADDITIONAL_EXIT_CODE = 2;
function AddThreadFunc(Data : pointer) : integer;
begin
Result := ADDITIONAL_EXIT_CODE;
Writeln("The additional thread began work... [#", GetCurrentThreadID,"]");
Sleep(PAUSE * 2);
Writeln("Additional stream together with this process will be finished in 5 seconds...");
Sleep(PAUSE);
//Дополнительный поток завершается обычным образом
end;
begin
Writeln("Primary thread began work...[#",GetCurrentThreadID,"]");
Sleep(PAUSE);
//Запускаем дополнительный поток нерекомендуемым способом
CreateThread(nil,0,@AddThreadFunc,nil,0,AddID);
Sleep(PAUSE);
//Вызываем неожиданное завершение первичного потока
Writeln("Now primary thread will be finished...");
ExitThread(PRIMARY_EXIT_CODE);
end.

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



Alien   (2001-10-28 01:29) [17]

> y-soft ©
Во фразе про мат часть было больше юмора, чем реального предложения, надеюсь этим я вас не зацепил :).

Тут Вы правы, что завершение первичного потока "ненормальным" образом не приводит к завершению процесса. Как говорится в одной известной сказке "признаю свою вину, меру, степень, глубину..." :).



y-soft   (2001-10-28 21:02) [18]

>Alien

:)

Еще забыл про одно условие сказать - не должно быть внешних ссылок на процесс



Dimanych   (2001-10-30 09:49) [19]

Ребят... Вы, конечно, все хорошо объясняли, но! Программа CorelDRAW 9 периодически показывает мне это фигу, причем, после кнопки Закрыть прекрасно продолжает работать. Проверял, других coreldrw.exe в памяти не было ;))



Digitman   (2001-10-30 10:54) [20]

Я не знаю, Corel там или не Corel, но прерывание по исключению, связанному с выполнением недопустимой операции, приложение теоретически (в Win9x/Me - практически) может перехватить, имея на то соотв.привелегии. И обработать по своему. Только - бессмсысленно это : после выполнения "непонятно чего" идти дальше "не зная куда" и делать "не зная что"



Anthon   (2001-11-05 02:27) [21]

В среде Windows NT можно использовать Debugging API.




Форум: "Система";
Поиск по всему сайту: delphimaster.net;
Текущий архив: 2002.02.07;
Скачать: [xml.tar.bz2];




Наверх





Память: 0.77 MB
Время: 0.023 c
1-18886           sd                    2002-01-23 13:51  2002.02.07  
TAction


1-18903           Ольга                 2002-01-22 17:18  2002.02.07  
Delphi 6


3-18700           dymka                 2002-01-09 14:01  2002.02.07  
TQuery в Runtime


4-19022           Snake2000             2001-12-11 13:14  2002.02.07  
Как сделатьмагнит?


3-18698           saviola               2002-01-09 13:32  2002.02.07  
Удалить запись в DBGrid e