![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
AV в ntdll.dll...?
istok © (2011-03-16 22:46:00)есть такой код для записи в файл:
CS: SyncObjs.TCriticalSection;
....
procedure WriteLog(Str: string; AFileName: string);
var
f: TextFile;
begin
CS.Enter;
try
AssignFile(f, AFileName);
try
if FileExists(AFileName) then
Append(f)
else
Rewrite(f);
Writeln(f, Format('[%s](%d): %s', [DateTimeToStr(Now), GetCurrentThreadId, str]));
finally
CloseFile(f);
end;
finally
CS.Leave;
end;
end;
при интенсивном использовании этого кода разными потоками иногда получаю вот это (eurekalog):
Access violation at address 00000000. Read of address 00000000.
---------------------------------------------------------------------------------------------------------------
|Address |Module |Unit |Class |Procedure/Method |Line |
---------------------------------------------------------------------------------------------------------------
|Running Thread: ID=10680; Priority=??; Class= |
|-------------------------------------------------------------------------------------------------------------|
|775E7760|ntdll.dll | | |RtlLeaveCriticalSection | |
|775E6A22|ntdll.dll | | |NtWaitForSingleObject | |
|775E7012|ntdll.dll | | |KiUserExceptionDispatcher | |
|0053F1CA|wecmsg.exe |WebFilterUnit.pas |TWebFilter |InStrings |2016[3] |
|0053F17C|wecmsg.exe |WebFilterUnit.pas |TWebFilter |InStrings |2013[0] |
|0053F655|wecmsg.exe |WebFilterUnit.pas |TWebFilter |CheckForBlockedUrl |2131[53]|
Метод InStrings через цепочку событий (синхронизируются) в итоге вызывает WriteLog:
function TWebFilter.InStrings(AStr: string; AStrings: TStrings): Boolean;
var
i: Integer;
begin
Result := False;
DoMessage('InStrings, AStr='+AStr+', AStrings.Text='+AStrings.Text);
procedure TWebFilter.DoMessage(AMessage: string; ADebugOnly: Boolean = True);
begin
if Assigned(FOnMessage) then
FOnMessage(Self, AMessage, ADebugOnly);
end;
procedure TWebFilterThread.DoOnThrdMessage(Sender: TObject;
AMessage: string; ADebugOnly: Boolean = True);
begin
DoSyncMessage(AMessage, ADebugOnly);
end;
procedure TWebFilterThread.DoSyncMessage(AMessage: string; ADebugOnly: Boolean = True);
begin
FMessage := AMessage;
FDebugOnly := ADebugOnly;
Synchronize(DoMessage);
end;
procedure TWebFilterThread.DoMessage;
begin
if Assigned(FOnThrdMessage) then
FOnThrdMessage(Self, FMessage, FDebugOnly);
end;
procedure TThreadedWebFilter.DoOnThrdMessage(Sender: TObject;
AMessage: string; ADebugOnly: Boolean = True);
begin
if Assigned(FOnMessage) then
FOnMessage(Sender, AMessage, ADebugOnly);
end;
procedure TweClientMessengerService.DoOnWebFilterMessage(Sender: TObject;
AMessage: string; ADebugOnly: Boolean = True);
begin
AddLog('WebFilter, DoOnMessage: '+AMessage, ADebugOnly);
end;
procedure TweClientMessengerService.AddLog(AStr: string; ADebugOnly: Boolean = True);
begin
if FDebugMode then
try
WriteLog(AStr, FweFolders.dirCurrent + 'weClientMessengerLog_DEBUG.txt');
except
end;
end;
я в нужном месте ищу баг? что может значить данный AV в ntdll.dll RtlLeaveCriticalSection ? Критич. секция не срабатывает почему-то или дело в чем-то другом?
sniknik (2011-03-17 08:07:00) [21]> идёт из одного потока..
из основного? а изменения с ним ты синхронизируешь? особенно в случае с DateTimeToStr где его настройки для него (из за которых "not ...") меняются в недрах VCL... внезапно.
p.s. если это логер, то логичнее было бы вынести его самого/работу с файлом в поток, а не пытаться синхронизироваться со всеми. а данные на запись ему посылать в сообщении. ИМХО конечно.
Германн (2011-03-17 02:37:00) [22]
> istok (17.03.11 00:57) [10]
Если Эврика лицензионная, рекомендую напрямую обратиться в суппорт Эврики. Помогут, чем смогут.
istok (2011-03-17 00:57:00) [23]хм.. логирование показывает что всё что касается класса TWebFilter, на который указывает eureka, идёт из одного потока..
а разные потоки пересекаются только в writelog, где и стоит cs...
можете подсказать, что есть RtlLeaveCriticalSection в ntdll.dl ? его как следствие вызывает моя критич. секция при leave или это могут быть еще какие-то не созданные мною cs ?
RWolf (2011-03-17 00:12:00) [24]
> я не понимаю, что тут криминального
AStrings.Text, видимо.
istok (2011-03-17 00:07:00) [25]в InStrings eureka указывает на строку
> DoMessage('InStrings, AStr='+AStr+', AStrings.Text='+AStrings.
> Text);
код этого метода и последовательность событий описаны.. я не понимаю, что тут криминального, кроме того что всё сводится к записи в лог..
а без записи в лог (та же цепочка событий, только writelog не делается) эксепшен и не ловится.
RWolf (2011-03-16 23:59:00) [26]
> Метод InStrings через цепочку событий (синхронизируются)
> в итоге вызывает WriteLog:
но эврика-то указывает на эксепшен в InStrings, при чём тут WriteLog?
sniknik (2011-03-16 23:57:00) [27]да, да, пусть у тебя 10 спасательных кругов, и ты их дома красиво по стенкам периодически развешиваешь... к чему это на море?
> я понимаю что она not thread-safe
а понимаешь почему?
istok (2011-03-16 23:30:00) [28]почему ж с основным.., судя по логам и значению GetCurrentThreadId, этот код вызывают разные потоки... значит и enter\leave делается разными потоками. нет?
sniknik (2011-03-16 23:22:00) [29]> критич секцию
с основным потоком?
> разве не спасает?
ну как сказать, само по себе, без логики, это как спасательный круг дома, когда тонешь на море.
istok (2011-03-16 23:04:00) [30]я понимаю что она not thread-safe, но я ж критич секцию юзю. разве не спасает?
sniknik (2011-03-16 22:58:00) [31]> этого кода разными потоками
почитай в хелпе про DateTimeToStr
istok (2011-03-16 22:47:00) [32]забыл добавить: в итоге в выводимом файле после эксепшена иногда остаются незавершенные строки или вообще случайные символы попадают..