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

Вниз

Тихо умирающее приложение   Найти похожие ветки 

 
AlexNe   (2008-07-05 18:41) [0]

Уважаемые эксперты! Похоже я своими стараниями попал
в ситуацию из которой пока не вижу выхода.
Суть проблемы:
Имеется приложение, работающее с различными удаленными серверами через TSocketConnection, c базой данных Interbase, и с сервером реального времени, который крутится на DOS машине - соотв. через синхронный сокет TIdTCPClient.
Для работы с каждым сервером имеется отдельный поток,
причем поток сокета TIdTCPClient имеет наивысший приоритет.
Приложение работает под WinXP,  работает без замечаний иногда 9 часов, иногда 3, затем элегантно, без каких либо сообщений схлопывается (а следом закрываются сервера).
Отслеживание возникающих исключений
(посылка сообщений из Application.OnException другой программе) не дало ничего - все чисто до самого схлопывания.
Запустить программу надолго под отладчиком Delphi я не имею возможности.
Безуспешные попытки найти причину доводят меня до отчаяния.
Уже вырубил на всех TSocketConnection  свойство SupportCallBacks в False. Во всех Еxecute потоков защитил в
try-except все что только возможно - не помогает!

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


 
Loginov Dmitry ©   (2008-07-05 18:59) [1]

> или подскажет хотябы в какую сторону искать.


Копать следует путем записи в лог всего и вся (все действия приложения, все сообщения об ошибках с указанием ID потока), а потом часами сидеть и анализировать зависимости между записанными в лог строчками.

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


 
Сергей М. ©   (2008-07-05 19:20) [2]


> приложение, работающее с различными удаленными серверами .. схлопывается


> следом закрываются сервера


Полный трындец - рухнул кривой самопальный клиент, и в солидарность ему тут же рухнул сервер-бренд)

Или нет ? Или совсем не так дело обстоит ?)


 
AlexNe   (2008-07-05 19:38) [3]

Одна из возможных причин схлопывания, как мне думалось, возникновение Exceptions внутри execute потока.
Действительно, когда снабдил потоки механизмом передачи логов - что-то вроде

procedure TMainTread.Execure;
var Hwnd: THandle;
 Txt: string;
 cds: CopyDataStruct;
begin
..........
 try
 .....
 except
   Txt := "Интересующие параметры";
   cds.cbData := length (Txt);
   cds.lpData := PChar (Txt);
   SendMessage (hwnd, wm_CopyData, 0, Integer (@cds));
 end;
.........
end;

обнаружил, что в потоке образуется за секунду куча исключений, которые
не выводятся на экран! Ну и через некоторое время операционка очевидно
убивает приложение.
Фишка в том, что эти ошибки я выловил и убрал, а проблема осталась!

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


 
AlexNe   (2008-07-05 19:41) [4]

to Сергей М.
не, сервера тоже самопальные :)  
они и должны в случае пропадания всех клиентов закрываться.
А трындец действительно полный.


 
Loginov Dmitry ©   (2008-07-05 19:41) [5]

> except
>   Txt := "Интересующие параметры";
>   cds.cbData := length (Txt);
>   cds.lpData := PChar (Txt);
>   SendMessage (hwnd, wm_CopyData, 0, Integer (@cds));
> end;


А оригинальный текст сообщения об ошибке разве не интересует?


 
AlexNe   (2008-07-05 19:56) [6]

Нет, ну конечно, там стоит Exception.Message когда оно есть, плюс номер тика, когда случилось. Или я чего-то не понял? В смысле засунуть туда HandleException?


 
AlexNe   (2008-07-05 20:03) [7]

Просмотр системного журнала показал наличие серии ошибок Source="Application Error"   Category= "None" Event=1000 но с моментами вылетов эти серии слабо кореллируют


 
Loginov Dmitry ©   (2008-07-05 20:19) [8]

> Или я чего-то не понял?


да фик тебя знает. Я имел ввиду следующее:

try

except
 on E: Exception do
   WriteToLog(E.Message);
end;


 
Сергей М. ©   (2008-07-05 21:03) [9]


> не, сервера тоже самопальные


Не, тады твоим потугам точно трындец)

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

Ты отладчик-то пользуешь, чудо ?)
Или на бубен уповаешь ?)


 
AlexNe   (2008-07-05 21:10) [10]

to Loginov Dmitry
прошу прощения, у меня уже из-за этой проблемы фокус сбивается...
Может быть стоит. Только это ничего не даст - в програме после
каждого  try except стоят WriteToLog (т.е SendMessage) , и еще
тестировалось с обработчиком Application.OnException, который как раз
записывал в лог E.Message. Так вот, за ночь ни одной записи об исключительных ситуациях и при этом два схлопывания. То есть, когда начинается разрушение, либо SendMessage не работает, либо черт знает вообще что....


 
AlexNe   (2008-07-05 21:12) [11]

to Сергей М.
на бубен, на бубен


 
Сергей М. ©   (2008-07-05 21:17) [12]

Ну тады тряси)
Авось само рассосется)

Небеса, панимаишь ..


 
Дмитрий Белькевич ©   (2008-07-05 21:17) [13]

Удалённую отладку используй. Гарантированно Excpeption"ы покажет, да еще и потрассировать даст. Очень помогает, бывает. Особенно, когда клиент на другой стороне шарика ;)


 
AlexNe   (2008-07-05 21:21) [14]

Собственно проблема возникла после замены асинхронного, но кривого TClientSocket на не кривой, но синхронный  TIdTCPClient для работы с сервером под DOS. Соответственно пришлось засунуть TIdTCPClient  в отдельный поток, а потом и все остальные обращения к серверам рассовать по потокам. И в общем все стало работать много лучше, но в отместку этот глюк!


 
Дмитрий Белькевич ©   (2008-07-05 21:21) [15]

Даже мёртвый поток, кстати, после exception"а может OnTerminate вызвать, если его обработать, конечно. А (Sender as TThread).FatalException иногда интересные данные отдаёт.


 
Дмитрий Белькевич ©   (2008-07-05 21:23) [16]

Можно еще попробовать Indy обновить до актуальных.


 
Сергей М. ©   (2008-07-05 21:30) [17]


> кривого TClientSocket на не кривой, но синхронный  TIdTCPClient


Эдаких клоунов, зафиксировавших сей факт,  - пруд пруди)


 
AlexNe   (2008-07-05 21:38) [18]

to Дмитрий Белькевич
Спасибо, попробую. Насколько понял из хелпа это для серверов под виндой. Есть еще Interbase, но он не падал и ничего особенного не ругался. Досовский сервер пишет подробный лог, пойду его копать.
Про OnTerminate и (Sender as TThread).FatalException напиши завтра, т.к. систему забрали а работу и поэкспериментировать до утра не смогу.


 
Дмитрий Белькевич ©   (2008-07-05 21:39) [19]

Угу, всё в потоках замечательно работает. Сотни потоков.


 
AlexNe   (2008-07-05 21:40) [20]

не напиши завтра а напишу завтра, конечно...


 
Германн ©   (2008-07-06 02:34) [21]


> AlexNe   (05.07.08 21:21) [14]
>
> Собственно проблема возникла после замены асинхронного,
> но кривого TClientSocket на не кривой, но синхронный  TIdTCPClient

Есть ещё ICS. Асинхронный и не очень кривой.


 
AlexNe   (2008-07-06 11:15) [22]

to Германн
Спасибо. Буду иметь в виду на будущее.


 
Slym ©   (2008-07-07 05:15) [23]

AlexNe   (05.07.08 21:21) [14]
TClientSocket

Самый прямой из простых оберток на WinSock... и не только асинхронный, но синхронный см ClientType:=ctBlocking;


 
AlexNe   (2008-07-08 11:58) [24]

to Slym
Cвязь через TClientSocket с сервером реального времени (на машине под DOS) у меня работала устойчиво только при условии установки наивысшего приоритета для всего клиентского Win приложения. Засунуть в специальный  поток его проблематично. При этом, если загрузить сильно клиента, например перерисовкой интерфейса, то часть приходящих с сервера пакетов TClientSocket просто терял...  
TIdTCPClient в отдельном потоке теряет ничего.


 
Slym ©   (2008-07-08 12:18) [25]

AlexNe   (08.07.08 11:58) [24]
Cвязь через TClientSocket

покажи как делал
AlexNe   (08.07.08 11:58) [24]
Засунуть в специальный  поток его проблематично

ничего проблемного:
unit Unit2;
interface
uses
 Classes,Scktcomp,winsock;

type
 TSockThread = class(TThread)
 private
 protected
   procedure Execute; override;
 end;

implementation

function SockWaitForData(ASocket:TSocket; ATimeout: Longint): Boolean;
var
 FDSet: TFDSet;
 TimeVal: TTimeVal;
begin
 TimeVal.tv_sec := ATimeout div 1000;
 TimeVal.tv_usec := (ATimeout mod 1000) * 1000;
 FD_ZERO(FDSet);
 FD_SET(ASocket, FDSet);
 Result := select(0, @FDSet, nil, nil, @TimeVal) > 0;
end;

function SockReadLn(ASocket:TSocket;ATerminator:char;AMaxLineLength:integer;ATimeOut:Long int):string;
var
 Buf:array[byte] of char;
 SizeBuf:integer;
 r,i:integer;
 s:string;
begin
 SizeBuf:=SizeOf(Buf);
 result:="";
 while SockWaitForData(ASocket,ATimeOut) do
 begin
   r:=recv(ASocket, Buf, SizeBuf, MSG_PEEK);
   if r=SOCKET_ERROR then RaiseSocketError(WSAGetLastError, "recv");
   i:=LCharPos(@Buf,ATerminator,r);
   if i<>0 then r:=i;
   r:=recv(ASocket, Buf, r, 0);
   if r=SOCKET_ERROR then RaiseSocketError(WSAGetLastError, "recv");
   SetString(s,Buf,r);
   result:=result+s;
   if i<>0 then Break;
 end;
 if length(result)=0 then exit;
 i:=length(result)-1;
 if (ATerminator=LF) and (result[i]=CR) then Dec(i);
 SetLength(result,i);
end;

{ TSockThread }

procedure TSockThread.Execute;
var
 Socket:TClientWinSocket;
 s:string;
 Code:integer;
begin
 Socket:=TClientWinSocket.Create(-1);
 try
   Socket.ClientType:=ctBlocking;
   Socket.Open("192.168.14.2","","",3128);
   Socket.SendText("CONNECT hostname HTTP/1.0"#13#10);
   Socket.SendText(#13#10);
   s:=SockReadLn(Socket.SocketHandle);
   Fetch(s," ");
   Code:=StrToIntDef(Fetch(s," "),200);
   if Code<>200 then raise Exception.CreateFmt("Bad HTTP status code: %d %s",[Code,s]);
   repeat until
     SockReadLn(PeerSocket.SocketHandle) = "";
   ...
 finally
   Socket.Free;
 end;
end;

end.


 
Дмитрий Белькевич ©   (2008-07-08 12:25) [26]

Что-то мне кажется, что решение задачи слишком усложнено. Какую проблему решает система?


 
Slym ©   (2008-07-08 12:27) [27]

Дмитрий Белькевич ©   (08.07.08 12:25) [26]
Какую проблему решает система?

2. что за DOS сервер, не порали найти/сделать win аналог?


 
Eraser ©   (2008-07-08 15:02) [28]

> [0] AlexNe   (05.07.08 18:41)


> причем поток сокета TIdTCPClient имеет наивысший приоритет.

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


 
AlexNe   (2008-07-08 16:36) [29]

Извиняюсь за задержку - у меня последний день командировки и рвут на части.
to Slym ©  
Возможно, что-то было с  TClientSocket в потоке сделано не так, нужно рыть старый исходник. Но сокет с DOS машиной через несколько минут 10Гц обмена вис, причем ситуация решалась только перезагрузкой DOS

to Дмитрий Белькевич ©  
Нет, не усложнено. Система решает задачу управления научным оборудованием, которое разбросано в радиусе 50 м и имеет ограничения по длине проводов связи - отсюда наличие множества серверов на разлинух компах.

to Slym ©  
>2. что за DOS сервер, не порали найти/сделать win аналог?
Найти нельзя. Сделать - во- первых нужна система жесткого реального времени, тут скорее QNX. Но главное, то кол-во самодельных железок, для которых по мере развития системы писались дрова - все переписть в обночасье никак не получится, а останавливать ради этого систему никто не даст. Так что живем как живем.

to Eraser ©
? - если кто-то приостановит обмен с DOS машиной на 0.5 с., сработает защита, которая останавливает плавное движение конструкции весом 3.5т.
> Если приложение падает и даже исключение не вылетает, то скорее всего > где-то неверная работа с памятью
что-то похожее на конфликт реентерабельности наблюдается по логам, - два раза произошел вылет при входе в Timer.OnTimer (там ничего нет, кроме обновления интерфейсных элементов).
Поставил на тестирование - до вечера, последний шанс отловить барабашку.


 
Сергей М. ©   (2008-07-08 17:25) [30]


> синхронный  TIdTCPClient для работы с сервером под DOS


Клиенту глубоко фиолетово, под какой ОС работает сервер.
Равно как и наоборот.
И синхронность или асинхронность тут совершенно ни причем.


 
AlexNe   (2008-07-08 19:18) [31]

>Сетевая часть думаю особо не при чем.


 
AlexNe   (2008-07-08 19:22) [32]

to Eraser ©
Предположение появилось из-за чрезвычайной редкости события - 1-2 раза за сутки, при том что старая версия с теми же серверам, оборудованием и в том же режиме не падает (хотя и теряет иногда важную информацию)


 
Сергей М. ©   (2008-07-08 19:26) [33]


> AlexNe   (08.07.08 19:18) [31]


Смотря что ты подразумеваешь под "сетевой частью".

Подозреваю, что ты не имеешь ни малейшего представления о модели OSI.


 
AlexNe   (2008-07-08 22:10) [34]

Случилось! Дебаггер указал на ошибку в потоке, в котором сидит IdTCPClient. Лог застопорился перед чтением свойства объекта-наследника соотв. потока. Т.е. какая-то аномалия при работе сокета DOS-Windows.
К сожалению проверить и уточнить получится нескоро, командировка кончилась. Поскольку моя работа с системой прерывается, тему считаю временно закрытой. Всем спасибо за потраченное время и ценную информацию.


 
Дмитрий Белькевич ©   (2008-07-08 22:37) [35]

>Т.е. какая-то аномалия при работе сокета DOS-Windows.

Наиболее вероятная аномалия - доступ к обломкам разрушенного объекта. Объектам после разрушения присваивай nil, может ошибку удастся "проявить". По AV доступа к 00000000.

Еще немного информации. Если нужен хороший реалтайм, разумно выбросить весь дос и вообще все лишние писюки и, по возможности, самодельные железки вместе с дровами. Сделать промежуточный приём на однокристалках, постараться все данные собирать только ими, благо сейчас их разных есть, можно и абсолютный аналог, и дифференциальный, и цифру забирать, и по многим каналам сразу. Объединить их в сеть (есть железки с готовым железячным tcp стёком), и сливать информацию по мере доступности на писюк.

Сделать единый движок для "пропихивания" инфы в компьютер. И несколько разных драйверов для разных входных данных.

Я, конечно, всех особенностей не знаю, но, скорее всего, должно работать без проблем.


 
SergeyIT ©   (2008-07-09 00:02) [36]


> Дмитрий Белькевич ©   (08.07.08 22:37) [35]
> разумно выбросить весь дос и вообще все лишние писюки

Легко говорить. А кто заплатит за такую переделку?
Как говортся - хорошо быть здоровым и богатым.;)


 
Anatoly Podgoretsky ©   (2008-07-09 00:31) [37]

> Дмитрий Белькевич  (08.07.2008 22:37:35)  [35]

Не надо nil, лучше $80808080


 
Дмитрий Белькевич ©   (2008-07-09 12:24) [38]

>Легко говорить. А кто заплатит за такую переделку?
>Как говортся - хорошо быть здоровым и богатым.;)

Лишние писюки - продать, купить однокристалок. Разницу (если останется) - пропить ;)
Вообще, всё равно придётся им что-то менять, просто "закопаются" со временем. Хотя, может быть я и не прав. Все обстоятельства мне неизвестны.

>Не надо nil, лучше $80808080

Почему, кстати? Нашел только, что FastMM в FullDebugMode атоматом забивает память разрушенных объектов и строк этим значением.

Вот, кстати, еще одна идея: поставить FastMM в FullDebugMode.


 
Anatoly Podgoretsky ©   (2008-07-09 13:02) [39]

> Дмитрий Белькевич  (09.07.2008 12:24:38)  [38]

Для того что бы отличить не инициализированое, от уничтоженого.
Методика из FastMM


 
Сергей М. ©   (2008-07-09 14:14) [40]


> аномалия при работе сокета DOS-Windows


Что это за сокет такой "DOS-Windows" ?

Какое тебе вообще дело до сокета на другом конце соединения ?

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



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

Форум: "Основная";
Текущий архив: 2009.09.20;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.57 MB
Время: 0.005 c
2-1248162543
lewka
2009-07-21 11:49
2009.09.20
нажатие на ссылку в TWebbrowser


2-1247574008
worldmen
2009-07-14 16:20
2009.09.20
Активация другой программы программно (вывести на первый план).


2-1247662840
dmitry_12_08_73
2009-07-15 17:00
2009.09.20
Подключение компонентаTWebBrowser к Internet Explorer


15-1248114719
Mike Kouzmine
2009-07-20 22:31
2009.09.20
Управление питанием


1-1215965666
dmitry_12_08_73
2008-07-13 20:14
2009.09.20
Диалоговое окно не должно перекрываться другими окнами





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский