Abnormal Termination Firebird 1.5.3.4870
Abnormal Termination Firebird 1.5.3.4870
Есть база на firebird 1.5.3.4870 и прога-клиент; одна из процедур базы использует функцию, реализованную в dll; естестенно dll лежит в папке UDF и все параметры функции описаны, а именно:
DECLARE EXTERNAL FUNCTION CALCPRICE
VARCHAR(255),
DOUBLE PRECISION,
DOUBLE PRECISION,
DOUBLE PRECISION,
DOUBLE PRECISION,
DOUBLE PRECISION,
DOUBLE PRECISION,
INTEGER
RETURNS DOUBLE PRECISION FREE_IT
ENTRY_POINT 'CalcPrice' MODULE_NAME 'MyDLL.dll'.
На моем компе или если подключаться с других компов, вызов вышеупомянутой процедуры проходит корректно. Но на серваке клиентов, время от времени при вызове процедуры сервак firebird сваливается.
В логах firebird написано следующее:
ARCTURUS (Server) Thu Sep 07 14:47:22 2006
Access violation.
The code attempted to access a virtual
address without privilege to do so.
This exception will cause the Firebird server
to terminate abnormally.
ARCTURUS (Client) Thu Sep 07 14:47:22 2006
C:\Program Files\Firebird\Firebird_1_5\bin\fbserver.exe: terminated abnormally (4294967295)
В журнале событий винды такоесообщение:
The description for Event ID ( 281 ) in Source ( FirebirdGuardianDefaultInstance ) cannot be found. The local computer
may not have the necessary registry information or message DLL files to display messages from a remote computer. You may
be able to use the /AUXSOURCE= flag to retrieve this description; see Help and Support for details. The following
information is part of the event: Abnormal Termination: C:\Program Files\Firebird\Firebird_1_5\bin\fbserver.exe:
terminated abnormally (4294967295)r.exe
При чем заметили такую особенность, при первом вызове процедуры с клиента, почти 100%, что сервак свалиться, если потом сделать на клиенте реконект, то процедура с теми же параметрами выполняется без ошибок, и дальнейшие вызовы проходят нормально. Потом, если отключиться клиентом от базы, подождать какое-то время и подключится и снова выполнить процедуру снова ошибка.
Пожет кто подсказать в чем дело? Вобще впечатление, что винда или фаерволы/антивири, время от времени не дают firebird получить доступ к dll или самой dll не дают нормально работать с ыделением памяти.
DECLARE EXTERNAL FUNCTION CALCPRICE
VARCHAR(255),
DOUBLE PRECISION,
DOUBLE PRECISION,
DOUBLE PRECISION,
DOUBLE PRECISION,
DOUBLE PRECISION,
DOUBLE PRECISION,
INTEGER
RETURNS DOUBLE PRECISION FREE_IT
ENTRY_POINT 'CalcPrice' MODULE_NAME 'MyDLL.dll'.
На моем компе или если подключаться с других компов, вызов вышеупомянутой процедуры проходит корректно. Но на серваке клиентов, время от времени при вызове процедуры сервак firebird сваливается.
В логах firebird написано следующее:
ARCTURUS (Server) Thu Sep 07 14:47:22 2006
Access violation.
The code attempted to access a virtual
address without privilege to do so.
This exception will cause the Firebird server
to terminate abnormally.
ARCTURUS (Client) Thu Sep 07 14:47:22 2006
C:\Program Files\Firebird\Firebird_1_5\bin\fbserver.exe: terminated abnormally (4294967295)
В журнале событий винды такоесообщение:
The description for Event ID ( 281 ) in Source ( FirebirdGuardianDefaultInstance ) cannot be found. The local computer
may not have the necessary registry information or message DLL files to display messages from a remote computer. You may
be able to use the /AUXSOURCE= flag to retrieve this description; see Help and Support for details. The following
information is part of the event: Abnormal Termination: C:\Program Files\Firebird\Firebird_1_5\bin\fbserver.exe:
terminated abnormally (4294967295)r.exe
При чем заметили такую особенность, при первом вызове процедуры с клиента, почти 100%, что сервак свалиться, если потом сделать на клиенте реконект, то процедура с теми же параметрами выполняется без ошибок, и дальнейшие вызовы проходят нормально. Потом, если отключиться клиентом от базы, подождать какое-то время и подключится и снова выполнить процедуру снова ошибка.
Пожет кто подсказать в чем дело? Вобще впечатление, что винда или фаерволы/антивири, время от времени не дают firebird получить доступ к dll или самой dll не дают нормально работать с ыделением памяти.
Re: Abnormal Termination Firebird 1.5.3.4870
это шутка такая?Valmir писал(а):RETURNS DOUBLE PRECISION FREE_IT
Может я чего-то недопонимаю...
Заголовок в функции dll следующий:
когда возвращал просто Double, то выдавалось левое число.
free it сдела так как PDouble, а не Double.
даже если допустить, что dll написана криво, почему тогда на моем компе все нормально работает и ничего не падает. а на другом падает, но только иногда?
Заголовок в функции dll следующий:
Код: Выделить всё
function CalcPrice(Formula: PChar; var PriceDiler, PriceIn, RateDiler,
RateIn, RateOut, Coef: double; var PriceType: integer): PDouble; cdecl; export;
free it сдела так как PDouble, а не Double.
даже если допустить, что dll написана криво, почему тогда на моем компе все нормально работает и ничего не падает. а на другом падает, но только иногда?
конечно выделяю:dimitr писал(а):ты в своей UDF память для результата выделяешь? Если нет, то нафига тогда FREE_IT? Если да, то показывай, как именно.
Код: Выделить всё
New(Result);
...
Result^ := RoundReal(Result^/RateOut, 2);
там прямо написано
Код: Выделить всё
function Add_B(var iSmall: SmallInt; var iLong: Integer): PInteger; cdecl; export;
замечание: с серверами архитектуры SuperServer нельзя использовать такие udf. потому что udf будет вызываться в контексте одного процесса для разных пользователей (threads), и соответственно в глобальной переменной ResultInteger будет мешанина из конкурентных значений. В SuperServer значения можно возвращать только по значению, по FREE_IT, или через входной параметр
код восстановить можно, но говорю ж возвращалось левое числоkdv писал(а):этот код восстановить нельзя?когда возвращал просто Double, то выдавалось левое число.
статью ты видно НЕ ЧИТАЛ. Какой еще new для free_it ???New(Result);
NEW(result) - выделяет память под PDouble и делает result ссылкой на этот адрес памяти, да в статье сделана глобальная переменная, а значение функции становится ссылкой на эту переменную, только какой смысл, чем плох New ?
может я недопонимаю смысл Free_it? в статье не описано, что реально происходит....
это понятно, но тогда пожалуйста дайте ответ на встречные вопросыdimitr писал(а):в том, что память выделена в дельфовой куче, а сервер ее освобождает через сишную free().
1. допустим делаем так: функция dll возвращает тип Double, тогда можно ложить значение прямо в Result функции или необходимо делать глобальную переменную?
2. Если делать глобальную переменную, то как будет работать в многопоточности? т.к. в статье как-то неоднозначно сказано:
Код: Выделить всё
с серверами архитектуры SuperServer нельзя использовать такие udf. потому что udf будет вызываться в контексте одного процесса для разных пользователей (threads), и соответственно в глобальной переменной ResultInteger будет мешанина из конкурентных значений. В SuperServer значения можно возвращать только по значению, по FREE_IT, или через входной параметр
3. если вобще не делать Free_it, то тогда как будет освобождаться память из дэлфевой кучи после многократного вызова функции из dll
Наверное уже достал, но надеюсь посдледний вопрос:
будет ли корректно работать в многопоточности и корректно выделяться/освобождаться память если делать так:
в теле функции не делаем никакого выделения памяти, и значение ложим прямо в результат.
в базе делаем возврат byValue и не делаем Free_if?
такой вариант корректный во всех ракурсах?
будет ли корректно работать в многопоточности и корректно выделяться/освобождаться память если делать так:
Код: Выделить всё
function CalcPrice(Formula: PChar; var PriceDiler, PriceIn, RateDiler,
RateIn, RateOut, Coef: double; var PriceType: integer): Double; cdecl; export;
в базе делаем возврат byValue и не делаем Free_if?
такой вариант корректный во всех ракурсах?
-
- Заслуженный разработчик
- Сообщения: 1436
- Зарегистрирован: 15 сен 2005, 09:05
про free_it дополнительно написано в faq.
www.ibase.ru/ibfaq.htm#free_it
но в данном случае тебе free_it не нужен.
www.ibase.ru/ibfaq.htm#free_it
но в данном случае тебе free_it не нужен.
а сервак все равно продолжает падать
текст функции в dll:
память если и выделяется дэлфей, то тут же освобождается
в базе функция определена так:
при первом вызове сервак падает, после реконекта все хорошо работает. если отключится выждать время 1-4 мин, то опять при первом обращении падает. такая ситуация именно на серваке клиентов. при тестировании на наших компах все нормально. в чем же все таки дело?
текст функции в dll:
Код: Выделить всё
function CalcPrice(Formula: PChar; var PriceDiler, PriceIn, RateDiler,
RateIn, RateOut, Coef: double; var PriceType: integer): Double;
var
i, j: integer;
KeyLen: Word absolute Formula;
KeyStr: PChar;
s: String;
begin
PriceDiler := PriceDiler*RateDiler;
PriceIn := PriceIn*RateIn;
case PriceType of
-2: Result := PriceDiler*Coef;
-3: Result := PriceIn*Coef;
else
begin
KeyStr := AllocMem(KeyLen + 1);
Move((Formula + 2)^, KeyStr^, KeyLen);
s := KeyStr;
s := AnsiReplaceText(AnsiLowerCase(s), '[pricediler]', FloatToStr(PriceDiler));
s := AnsiReplaceText(s, '[pricein]', FloatToStr(PriceIn));
s := AnsiReplaceText(s, ',', '.');
Result := CalcFunction(s, 0, 0, 0);
FreeMem(KeyStr, KeyLen+1);
end;
end;
Result := RoundReal(Result/RateOut, 2);
end;
в базе функция определена так:
Код: Выделить всё
DECLARE EXTERNAL FUNCTION CALCPRICE
VARCHAR(255),
DOUBLE PRECISION,
DOUBLE PRECISION,
DOUBLE PRECISION,
DOUBLE PRECISION,
DOUBLE PRECISION,
DOUBLE PRECISION,
INTEGER
RETURNS DOUBLE PRECISION BY VALUE
ENTRY_POINT 'CalcPrice' MODULE_NAME 'MyDll.dll'
cdecl ты из вредности убрал?Valmir писал(а):текст функции в dll:Код: Выделить всё
function CalcPrice(Formula: PChar; var PriceDiler, PriceIn, RateDiler, RateIn, RateOut, Coef: double; var PriceType: integer): Double;
в конце статьи www.ibase.ru/devinfo/udf_ok.htm есть описание как отлаживать UDF в Delphi. Тем более, если сервак валится при первом же вызове.при первом вызове сервак падает
Кстати, а зачем вот это AllocMem, Move и т.п. ? Да еще блин с такими опасными древностями типа word absolute formula...
To dimitr: cdecl есть в заголовке процедуры в начале юнита, я запостил код реализации потому и нету cdecl и export;
To kdv:
1. может и древности, но работающие корректно или вы хотите сказат что такая реализация некорректная?
2. читайте внимательно я же четко написал: на моем компьютере все работает корректно, ничего не сваливается, функция возвращает правильный результат. Но когда тестируем программу на серваке клиентов, то только тогда сервак firebird падает, при чем только первый раз, после реконекта все работает нормально. Я именно это не могу понять, если предположить что dll написана криво, то почему у меня ничего не падает, а у них падает но иногда?
To kdv:
1. может и древности, но работающие корректно или вы хотите сказат что такая реализация некорректная?
2. читайте внимательно я же четко написал: на моем компьютере все работает корректно, ничего не сваливается, функция возвращает правильный результат. Но когда тестируем программу на серваке клиентов, то только тогда сервак firebird падает, при чем только первый раз, после реконекта все работает нормально. Я именно это не могу понять, если предположить что dll написана криво, то почему у меня ничего не падает, а у них падает но иногда?
Valmir. ТАК уже никто не пишет. Так когда-то писали под досом, где шансов получить AV почти не было, и утечки памяти никого не интересовали.
читать внимательно нужно вам - я объяснил, как отлаживать udf, что настоятельно рекомендую сделать, как и переписать этот странный и местами лишний код. Именно потому что у вас на сервере эта udf падает.
не хотите чинить - это ваша проблема.
И кривые udf именно так и ведут себя. они могут глючить при первом запуске, при десятом, или вообще на специфических данных.
читать внимательно нужно вам - я объяснил, как отлаживать udf, что настоятельно рекомендую сделать, как и переписать этот странный и местами лишний код. Именно потому что у вас на сервере эта udf падает.
не хотите чинить - это ваша проблема.
не надо ничего тут понимать. Возьмите программу с утечками памяти и неверной адресацией, и она будет глючить на двух компьютерах по разному.Я именно это не могу понять, если предположить что dll написана криво, то почему у меня ничего не падает, а у них падает но иногда?
И кривые udf именно так и ведут себя. они могут глючить при первом запуске, при десятом, или вообще на специфических данных.