Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "WinAPI";
Текущий архив: 2007.09.02;
Скачать: [xml.tar.bz2];

Вниз

WaitForMultipleObject, Event, ReadDirectoryChangesW, AV   Найти похожие ветки 

 
Анонимщик1   (2007-03-11 23:45) [0]

Я пытаюсь мониторить изменения в каталоге. Все, вроде бы, выходит, если бы не одно "но". Как только вызов функции оказывается
в блоке try, возникает AccessViolation. Не могу понять, с чем это может быть связано. Не может ли кто растолковать?
Для получения AV достаточно раскомментировать закомментированные строки.


unit main;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, StdCtrls;

type
 TForm1 = class(TForm)
   Button1: TButton;
   procedure FormCreate(Sender: TObject);
   procedure Button1Click(Sender: TObject);
 private
   { Private declarations }
   FhSpyDir: THandle;
   FhDirChangeEvent  : THandle;
   FSpyBufArray  : array[0..4096] of byte;
   function InitReadDirCh: boolean;
 public
   { Public declarations }
 end;

var
 Form1: TForm1;

implementation

{$R *.dfm}

const
 FILE_LIST_DIRECTORY = $0001;

procedure TForm1.FormCreate(Sender: TObject);
begin
 FhDirChangeEvent := CreateEvent(nil, false, false, nil);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
 rez : dword;
 pStpChgHandles : TWOHandleArray;
 i: Integer;
 last: Cardinal;
begin
 pStpChgHandles[0] := FhDirChangeEvent;

 FhSpyDir := CreateFile(PAnsiChar("C:\!TEST!"),
                        FILE_LIST_DIRECTORY,FILE_SHARE_READ or
                        FILE_SHARE_DELETE,
                        nil,
                        OPEN_EXISTING,
                        FILE_FLAG_BACKUP_SEMANTICS or FILE_FLAG_OVERLAPPED,
                        0);
 if FhSpyDir = INVALID_HANDLE_VALUE then
   Exit;

 if InitReadDirCh then
 begin
//    try
     rez := WaitForMultipleObjects(1, @pStpChgHandles, false, INFINITE);
     if rez = WAIT_OBJECT_0+1 then
     begin

     end;
//    finally
     last := GetLastError;
     OutputDebugString(PChar(SysErrorMessage(last)));
     ShowMessage(SysErrorMessage(last));
//    end;
 end;
end;

function TForm1.InitReadDirCh: boolean;
var
 I     : Integer;
 OVPD  : OVERLAPPED;
 p: Pointer;
begin
 result := true;
 OVPD.Internal := 0;
 OVPD.InternalHigh := 0;
 OVPD.Offset := 0;
 OVPD.OffsetHigh := 0;
 OVPD.hEvent := FhDirChangeEvent;
 if not ReadDirectoryChangesW(FhSpyDir, @FSpyBufArray,
                       SizeOf(FSpyBufArray),
                       false,
                       FILE_NOTIFY_CHANGE_LAST_WRITE,
                       nil,
                       @OVPD,
                       nil)  then
   Result := false;
end;

end.


 
Джо ©   (2007-03-12 03:18) [1]

Вообще, весь код какой-то странный.
1. Кто будет проверять возвращаемое значение CreateEvent в FormCreate?
2. GetLastError при отсутствии проверки возвращаемого значения WaitForMultipleObjects — нонсенс.
3. Остальных манипуляций, честно говоря, и касаться не хочу.


 
Сергей М. ©   (2007-03-12 09:20) [2]


> Анонимщик1   (11.03.07 23:45)


Что, прямо на строчке с вызовом WaitForMultipleObjects() возникает AV ?
Не верю ...


 
MBo ©   (2007-03-12 09:35) [3]

TWOHandleArray - что за тип?


 
Сергей М. ©   (2007-03-12 09:36) [4]


> MBo ©   (12.03.07 09:35) [3]


В Windows.pas он объявлен.
Массив из 64-х хэндлов.


 
Анонимщик1   (2007-03-12 09:50) [5]

> Джо
Сорри за несуразности, код я выдирал из готового проекта, поэтому упрощал где мог и кое-чего пропустил.
Что касается GetLastError, то не знаю, что за нонсенс Вы увидели.

> Сергей М.
Ошибка возникает не на WaitForMultipleObject (кстати, этот вызов можно заменить и на WaitForSingleObject), а при входе в блок finally, какэто ни странно. Если try-finally отсутствует, то и AV не возникает.

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


 
MBo ©   (2007-03-12 09:51) [6]

>В Windows.pas он объявлен.
А, ясно. Я подумал - вдруг динамический


 
Сергей М. ©   (2007-03-12 10:00) [7]


> Анонимщик1   (12.03.07 09:50) [5]


А ты выполнил условия, необходимые для ожидаемой тобой функциональности в работе OutputDebugString ?

Закомментарь вызов OutputDebugString и удивись - AV исчез.

И вообще - код, вынесенный тобой в finally попросту лишен смысла.


 
Анонимщик1   (2007-03-12 10:09) [8]

> Сергей М.
> И вообще - код, вынесенный тобой в finally попросту лишен смысла.
Согласен

> Закомментарь вызов OutputDebugString и удивись - AV исчез
А вот этого не произошло - все по-прежнему. У меня WinXP, я администратор, никаких особенностей, препятствующих работе OutputDebugString нет, тем более, что в таком случае ошибка была бы связана с нарушением прав доступа.


 
Сергей М. ©   (2007-03-12 10:14) [9]


> Анонимщик1   (12.03.07 10:09) [8]


> Согласен


Ну а зачем тогда этот код, если "согласен" ?)


> этого не произошло - все по-прежнему


Отладчик тебе на что дан ?
Бери его в руки и выясняй конкретную строку, вызывающую исключение.


 
Анонимщик1   (2007-03-12 10:19) [10]

> Сергей М.
> Ну а зачем тогда этот код, если "согласен" ?)
Если спрашиваете, отвечу: да просто потому, что глюк странный, боюсь, если в finally ничего не написать, то оптимизатор сделает что-то такое, что ошибка не проявится.

>Отладчик тебе на что дан ?
>Бери его в руки и выясняй конкретную строку, вызывающую исключение.
Я прошу прощения, но этим я уже два дня позанимался. Кроме того, что это какой-то глюк компилятора, ничего придумать не могу. Меня не устраивает, что AV вызывает именно охраняемый блок. Я вижу в этом некую странность и поэтому попросил вас (и Вас лично, Сергей) помочь разобраться.


 
Сергей М. ©   (2007-03-12 10:20) [11]


> if rez = WAIT_OBJECT_0+1 then


Эта строчка тоже лишена смысла - в твоем случае if-выражение никогда не примет True-значение, потому что ты ожидаешь всего один объект, сигнал которого определяется по WAIT_OBJECT_0, а не WAIT_OBJECT_0+1


 
Сергей М. ©   (2007-03-12 10:23) [12]


> боюсь, если в finally ничего не написать, то оптимизатор
> сделает что-то такое, что ошибка не проявится


Какая ошибка-то ? И как она должна, по-твоему, "проявиться" ?


 
Сергей М. ©   (2007-03-12 10:27) [13]


> Меня не устраивает, что AV вызывает именно охраняемый блок


А может и не он вовсе ?
Как ты определил, что AV возникает именно в finally-блоке, если не с помощью пошаговой трассировки кода средствами встр.отладчика ?

И кстати, код в блоке finally - точно такой же обычный код, что и в любом ином месте программы, и исключения в этом блоке точно так же возможны.


 
Сергей М. ©   (2007-03-12 10:29) [14]

Более того, я подозреваю, что ты неверно понимаешь назначение и логику работы finally-конструкций.


 
Анонимщик1   (2007-03-12 10:31) [15]

> А может и не он вовсе ?
Может, и не он. Но только если этот охраняемый блок не вводить, то и AV не возникает. А возникает он и с отладчиком, и без отладчика.

> И кстати, код в блоке finally - точно такой же обычный код, что и в любом ином месте программы, и исключения в этом блоке точно так же возможны.

Да, да только вызов ShowMessage приводит к возниконовению AV крайне редко (хотя и не буду настаивать, что никогда; для оправдания скажу, что я пробовал в разных конфигурациях).


 
Анонимщик1   (2007-03-12 10:33) [16]

> Более того, я подозреваю, что ты неверно понимаешь назначение и логику работы finally-конструкций.

Пусть даже так. Но вопрос этим не снимается.
Возникновение ошибки было замечено случайно (try-finally в этом месте действительно не нужен), но все же непонятна причина, из-за которой она возникает.


 
Сергей М. ©   (2007-03-12 10:36) [17]


> Анонимщик1   (12.03.07 10:31) [15]


Вот ты получил сообщение об исключении "... Access Violation at XXXXXXXX ....".

В меню Search - > Find Error ..  вводишь этот самый адрес XXXXXXXX и отладчик покажет тебе строку текста твоей программы, выполнение которой привело к искл-ю.


 
Анонимщик1   (2007-03-12 10:36) [18]

Да, при замене finally на except поведение не меняется


 
Сергей М. ©   (2007-03-12 10:37) [19]


> непонятна причина, из-за которой она возникает


Бессмысленно искать причину, не зная источника проблемы (конкретной строки кода, вызвавшей исключение)


 
Анонимщик1   (2007-03-12 10:50) [20]

Адрес нулевой, такого пункта меню у меня нет (Delphi 2006), но AV происходит уже после выхода из функции.


 
Сергей М. ©   (2007-03-12 10:56) [21]


> такого пункта меню у меня нет (Delphi 2006)


В D7 есть.
Глубоко сомневаюсь, что его нет в D2006.


> AV происходит уже после выхода из функции


Как определил ? Без пошаговой трассировки-то ?


 
Анонимщик1   (2007-03-12 11:00) [22]

> Глубоко сомневаюсь, что его нет в D2006.
Вы имели в виду отладчик, а не главное меню?

> Как определил ? Без пошаговой трассировки-то ?
Я никак не могу понять, почему Вы решили, что я не делаю пошаговой трассировки? Из чего Вы вывели такое заключение?


 
Сергей М. ©   (2007-03-12 11:16) [23]


> Вы имели в виду отладчик, а не главное меню?


Я имер ввиду главное меню окна самого IDE.

В нем есть пункт Search, в котором д.б. подпункт Find Error ...


> почему Вы решили, что я не делаю пошаговой трассировки?


Потому что именно пошаговая трассировка и покажет конкретную проблемную строку. Из твоих путаных объяснений она до сих пор не известна.


 
Анонимщик1   (2007-03-12 11:23) [24]

Сергей, у меня такого пункта меню нет, сколько бы Вы не сомневались. Заранее согласен, что я олух.
Я готов даже пойти на то, чтобы признать, что мои объяснения путаные, хотя они самые что ни есть конкретные, т.е. точные и детально описывающие картину происходящего.
Несмотря на Ваш довольно нетерпеливый и грубый тон, все-таки прошу загрузить код в редактор и проверить, насколько я неправ.


 
Сергей М. ©   (2007-03-12 12:05) [25]

Переменная OVPD  : OVERLAPPED д.б. статическкой !


 
Сергей М. ©   (2007-03-12 12:11) [26]

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


 
Анонимщик1   (2007-03-12 12:36) [27]

Большое спасибо.
Да, облажался я, признаю. Хотя то, что время жизни должно быть не меньше времени ожидания, должно было быть очевидным.
Но согласитесь, что, не зная этого, нельзя было лучше описать проблему.


 
Анонимщик1   (2007-03-12 12:41) [28]

Сергей, Вы бы написали номер вашего кошелька, я бы Вам счет при случае пополнил бы.


 
Сергей М. ©   (2007-03-12 12:42) [29]


> не зная этого, нельзя было лучше описать проблему


Но проблема эта никак не связана ни с наличием ни с отсутствием упомянутого тобой блока try..finally/except. Что он есть, что его нет - исключение по упомянутой причине будет возбуждено в любом случае.


 
Анонимщик1   (2007-03-12 12:47) [30]

В любом случае была ошибка, а почему не возникало исключения - другой вопрос.


 
Сергей М. ©   (2007-03-12 13:02) [31]


> Анонимщик1   (12.03.07 12:41) [28]

R276617073300
Z776774471136


 
Сергей М. ©   (2007-03-12 13:05) [32]


> Анонимщик1   (12.03.07 12:47) [30]


> почему не возникало исключения


Это уж как повезет)


 
Анонимщик1   (2007-03-12 13:10) [33]

Спасибо, я записал


 
Сергей М. ©   (2007-03-12 14:47) [34]


> Анонимщик1   (12.03.07 13:10) [33]


И ?)


 
tesseract ©   (2007-03-12 17:58) [35]


> И ?)


Баланс уже отрицательный.


 
Анонимщик1   (2007-03-12 18:13) [36]

Пардоньте, я же сказал: "при случае".



Страницы: 1 вся ветка

Форум: "WinAPI";
Текущий архив: 2007.09.02;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.55 MB
Время: 0.045 c
15-1186401509
de.
2007-08-06 15:58
2007.09.02
Acer 5100


2-1186384703
DmitryFox
2007-08-06 11:18
2007.09.02
Локализация приложения для Китая


15-1186483370
Галинка
2007-08-07 14:42
2007.09.02
.tar чем разархивировать?


15-1186456745
molerss
2007-08-07 07:19
2007.09.02
кто нибудь знает -где найти такое?


8-1164182824
DancerMan
2006-11-22 11:07
2007.09.02
*.JPEG true color -> 256 grays





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский