Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2007.02.25;
Скачать: CL | DM;

Вниз

Работа со строками приводит к ошибкам при выделении памяти   Найти похожие ветки 

 
MegaVolt ©   (2006-12-28 16:34) [0]

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

LogFile:TFileStream;

procedure TLog.StartF(Str: string);
var
 s:string;
begin
 if not Enabled then Exit;
 s:="<"+IntToStr(GetTickCount-StartTime)+":"+str+#13+#10;
 LogFile.Write(s[1],Length(s));
//  FlushFileBuffers(LogFile.Handle);
end;


Допускаю что дело не в этой функции а во вносимых ею задержках. Но как тогда искать в чём проблема?


 
Джо-со-смарта   (2006-12-28 16:43) [1]

Причем здесь какие-то задержки?


 
MegaVolt ©   (2006-12-28 16:53) [2]

>Причем здесь какие-то задержки?
Это была версия. В проге используется мультимедийный таймер возможно добавление задержек вызывает какие то эффекты. Если задержки не при чём тогда в чём дело? Как лечить?


 
Джо ©   (2006-12-28 17:29) [3]

> Как лечить?

Что лечить-то? Приведенный код вполне работоспособен. А «проблемы с выделением памяти и нестабильной работе программы» — не озвучены.


 
MegaVolt ©   (2006-12-28 17:37) [4]

К сожалению не могу точно описать потому что симптомов море. Прога падает с исключением. Иногда ругается на проблемы работы с памятью а именно в модуле getmem.inc. Иногда ругается на невозможность создания битмапа. Если же Enabled выставить в false все глюки пропадают. Может ли быть проблема с тем что данная функция вызывается очень часто (в каждой моей процедуре или функции) и возникают какие то проблемы при частом выделении памяти под стрококу.


 
Джо ©   (2006-12-28 17:44) [5]

> [4] MegaVolt ©   (28.12.06 17:37)
> К сожалению не могу точно описать потому что симптомов море.

Ну, и чем ты думаешь тебе смогут помочь в таком случае? Ясно одно — программа неверно написана :)


> Может ли быть проблема с тем что данная функция вызывается
> очень часто (в каждой моей процедуре или функции) и возникают
> какие то проблемы при частом выделении памяти под стрококу.

Я не слишком рискую, если предположу, что не может.


 
MegaVolt ©   (2006-12-28 17:52) [6]

>Я не слишком рискую, если предположу, что не может.
Я встречал глюк при частом выделении памяти маленькими кусками например в TMemoryStream почему не исключить такие же проблемы с выделением памяти под строки? Тем более если верить отладчику именно при этом и вознимкают ошибки (если судить по истории вызовов процедур)

Как ловить проблему если:
1. Место появления ошибки нестабильно
2. Строка с ошибкой находится в генофонде а не в моём коде
3. Добавление моего когда для записи логов способствуует появлению ошибок
4. Баг не повторяем. Т.е. действия приведшие к глюку при одном запуске не приводят к глюку во втором.


 
Anatoly Podgoretsky ©   (2006-12-28 17:57) [7]

> MegaVolt  (28.12.2006 17:52:06)  [6]

> 3. Добавление моего когда для записи логов способствуует появлению ошибок

Соотвественно ищи ошибку в другом месте.


 
MegaVolt ©   (2006-12-28 18:09) [8]

>Соотвественно ищи ошибку в другом месте.
Как? Что ловить какие характерные куски анализировать?


 
Sha ©   (2006-12-28 18:12) [9]

Т.к. мультимедийный таймер работает в отдельном потоке, то у тебя должно быть

IsMultiThread:=TRUE;


 
isasa ©   (2006-12-28 23:43) [10]

Попробуй
procedure TLog.StartF(Str: string);
var
s:string;
begin
if not Enabled then Exit;
<мультимедийный таймер>.Disable;
s:="<"+IntToStr(GetTickCount-StartTime)+":"+str+#13+#10;
LogFile.Write(s[1],Length(s));
//  FlushFileBuffers(LogFile.Handle);
<мультимедийный таймер>.Enable;
end;


 
SlymRO   (2006-12-29 04:33) [11]

procedure TLog.StartF(Str: string);
var
s:string;
begin
if not Enabled then Exit;
CriticalSection.Enter;
try
s:="<"+IntToStr(GetTickCount-StartTime)+":"+str+#13+#10;
LogFile.Write(s[1],Length(s));
//  FlushFileBuffers(LogFile.Handle);
finally
CriticalSection.Leave;
end;
end;


 
Slym ©   (2006-12-29 04:39) [12]

Вау! Новогодняя амнистия!


 
Sha ©   (2006-12-29 10:14) [13]

> SlymRO   (29.12.06 04:33) [11]

Припарки вряд ли помогут менеджеру.


 
MegaVolt ©   (2006-12-29 10:55) [14]

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


 
Джо ©   (2006-12-29 11:05) [15]

> Я не вижу ничего криминального в том что этот кусок кода
> будет выполнятся одновременно из нескольких мест.

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


 
Sha ©   (2006-12-29 12:06) [16]

> Джо ©   (29.12.06 11:05) [15]
> А критические секции этому воспрепятствуют.


Нет. Они нисколько не препятствуют параллельным обращениям к менеджеру памяти.


 
MegaVolt ©   (2006-12-29 12:07) [17]

Т.е. проблема в множественном обращении к FileStream?


 
Sha ©   (2006-12-29 12:17) [18]

> MegaVolt ©   (29.12.06 12:07) [17]

Проблема может быть, например, в таком безобидном операторе:

s:="<"+IntToStr(GetTickCount-StartTime)+":"+str+#13+#10;

т.к. он требует перераспределения памяти, если параллельному потоку в
тоже самое время потребуются услуги менеджера.


 
Джо ©   (2006-12-29 12:22) [19]

> [16] Sha ©   (29.12.06 12:06)
> > Джо ©   (29.12.06 11:05) [15]
> > А критические секции этому воспрепятствуют.
>
> Нет. Они нисколько не препятствуют параллельным обращениям
> к менеджеру памяти.

В метод StartF нельзя будет «войти» из разных потоков. Поэтому и не будет никаких «параллельных обращений к менеджеру памяти». Разве не так?


 
MegaVolt ©   (2006-12-29 12:22) [20]

>Проблема может быть, например, в таком безобидном операторе
А похоже так и есть. Как тогда правильно делать ведение логов?


 
Sha ©   (2006-12-29 12:31) [21]

> Джо ©   (29.12.06 12:22) [19]
> В метод StartF нельзя будет «войти» из разных потоков

Согласен.

> Поэтому и не будет никаких «параллельных обращений к менеджеру памяти».

Не согласен.
Другой поток имеет полное право в это время создать какой-нить объект.


 
evvcom ©   (2006-12-29 12:42) [22]

Что-то я вас не пойму. Вы хотите сказать, что дельфовый менеджер памяти не потокобезопасен?


 
Sha ©   (2006-12-29 12:43) [23]

> MegaVolt ©   (29.12.06 12:22) [20]
> Как тогда правильно делать ведение логов?

Если поток всего один, то ничего дополнительно делать не надо.
Если 2 и больше - установить IsMultiThread=TRUE, например при помощи BeginThread
Если пишущих в лог 2 и больше - защитить процедуру записи крит секцией.


 
Sha ©   (2006-12-29 12:44) [24]

> evvcom ©   (29.12.06 12:42) [22]
> Что-то я вас не пойму. Вы хотите сказать, что дельфовый менеджер памяти не потокобезопасен?

Потокобезопасен, если потоки создавать средствами Делфи.


 
evvcom ©   (2006-12-29 12:47) [25]

> [23] Sha ©   (29.12.06 12:43)
> IsMultiThread=TRUE

А... Уже забыл, что раньше об этом говорилось.


 
AgainSlymRO   (2006-12-29 13:02) [26]

Сабрались старые бухарики под новый год и спорять по IsMultiThread...
CriticalSection на разделяемом несколькими потоками объекте должен быть априори, всегда!


 
AgainSlymRO   (2006-12-29 13:04) [27]

Я тут с одним уже спорил, так этот "один" втирал мне что строки string потокобезопасны! я ему на пальцах нарисовал что даже 1 байт не может быть потокобезопасным


 
evvcom ©   (2006-12-29 13:09) [28]

> [26] AgainSlymRO   (29.12.06 13:02)
> Сабрались старые бухарики под новый год

Гы, а ты вечный нарушитель? :)))


 
Sha ©   (2006-12-29 13:21) [29]

> AgainSlymRO   (29.12.06 13:02) [26]
> Сабрались старые бухарики под новый год и спорять по IsMultiThread...
> CriticalSection на разделяемом несколькими потоками объекте должен быть априори, всегда!

Ну да, конечно, на CriticalSection свет клином сошелся


 
MegaVolt ©   (2006-12-29 16:21) [30]

>я ему на пальцах нарисовал что даже 1 байт не может быть потокобезопасным
А можно ссылочку? Или повторить вывод? (я надеюсь нерассматривался случай побитового исправления байта?)



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

Текущий архив: 2007.02.25;
Скачать: CL | DM;

Наверх




Память: 0.54 MB
Время: 0.031 c
15-1170297594
hmmm
2007-02-01 05:39
2007.02.25
опять куки


3-1165249048
DelphiLexx
2006-12-04 19:17
2007.02.25
Проблема с интерфейсов OK и Отмена, Commit и Rollback


2-1170738550
Lapushka-dochka
2007-02-06 08:09
2007.02.25
Где моя ошибка, кодскажите, плз.


2-1171029853
sat
2007-02-09 17:04
2007.02.25
DLL


2-1170879979
niil
2007-02-07 23:26
2007.02.25
Событие onMouseDown для создаваемого в ран-тайме TTabSheet