|
подтекает память ( из UDF ? )
|
|||
---|---|---|---|
#18+
Стоит на линуксе firebird2.5-super-server 2.5.0.26054 - текущая последняя версия из дистрибутива дебиан 7. Некоторое время назад размер процессов начал расти. Подтекает весьма интенсивно. В сутки 1-1.5 гб. Так что уже приходится перезапускать процесс. Конфиг firebird.conf почти не трогался даже. Там только насчет UDF изменения. Про то, что можно для каждой базы поменять настройки памяти никто в этой инсталляции не знает даже. То есть, все дефолтное. Очевидная причина - самописные UDF. Как бы определить утекает она из-за особенностей UDF или просто растет потому что так и должно быть ? В базе всегда были UDF . библиотечка называлась ibu.c и меня уверяют, что все написано по канонам. Код, вероятно, общеизвестный . Есть выделение памяти : Код: plaintext 1. 2. 3. 4.
и такого рода несколько процедур, где этот malloc потом используется: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14.
Однако мне не понятно каким образом эта память должна освобождаться. FB получает результат, использует, а дальше что ? Это вообще правильно написано ? допустим, я нашел примеры написания udf, там в том же ключе функции написаны. например такое : Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31.
Но кто обещал что примеры udf правильные ? какие еще могут быть причины ? Куда теперь копать ? ... |
|||
:
Нравится:
Не нравится:
|
|||
08.06.2016, 22:20 |
|
подтекает память ( из UDF ? )
|
|||
---|---|---|---|
#18+
netwindЕсть выделение памяти : Я очень надеюсь, что эта функция не в той самой библиотеке... Posted via ActualForum NNTP Server 1.5 ... |
|||
:
Нравится:
Не нравится:
|
|||
08.06.2016, 22:36 |
|
подтекает память ( из UDF ? )
|
|||
---|---|---|---|
#18+
netwind, дело не только в написании функции, но и в ее объявлении в SQL. У меня на сайте есть пример http://www.ibase.ru/files/download/safeudf.zip на pascal, с тремя вариантами объявления функций с возвращаемыми параметрами. Так вот, если ты хочешь, чтобы функция аллокировала память под результат внутри себя, а ФБ его освобождал, то - функция должна содержать вызов ib_util_malloc - функция должна быть объявлена с возвращаемым параметром по FREE_IT. Если же память аллокируется не под возвращаемый результат, то она должна освобождаться в этой же функции. Причем, аллокировать (и освобождать) память в этом случае можно любыми способами. То есть, FREE_IT это как бы "дайте мне функцию, результат которой аллокирован известным мне способом, и я смогу эту память освободить". Поэтому использовать нужно только ib_util_malloc из ib_util, который скомпилирован тем же рантаймом, что и ФБ. Если использовать просто malloc, то рантаймы могут не совпадать, и память может быть освобождена ФБ некорректно. Кроме того, А в твоем коде (я не силен в С, могу ошибаться) Код: plaintext 1. 2.
никакого аллокирования не происходит. Что будет в результате при попытке ФБ освободить возвращаемый результат, я не знаю (не помню уже). netwindКод, вероятно, общеизвестный . Есть выделение памяти : это чушь какая-то. См. выше - ib_util_malloc вызывается из либы ib_util, и в дистрибутиве ФБ есть как эта либа, так и ее заголовок ib_util.h. netwindКуда теперь копать ? исправить самодеятельность в ib_util_malloc. ну напиши процедуру, которая вызывает такую функцию с рандомным (и пустым) результатом, миллионов 5-10 раз, и смотри на потребление памяти ФБ. Если утечка есть, значит дело табак. ... |
|||
:
Нравится:
Не нравится:
|
|||
08.06.2016, 22:38 |
|
подтекает память ( из UDF ? )
|
|||
---|---|---|---|
#18+
netwindтам в том же ключе функции написаны. например такое : В оригинальном udflib.c написано вот так Код: plaintext 1. 2. 3. 4. 5. 6.
и ib_util_malloc именно тот, который из ib_util.dll/ib_util.so. Если даже брать udflib.c от IB4, то там код другой (free_it еще не было). А в ИБ5 уже free_it. ... |
|||
:
Нравится:
Не нравится:
|
|||
08.06.2016, 22:45 |
|
подтекает память ( из UDF ? )
|
|||
---|---|---|---|
#18+
kdv, тесты отлично подтверждают ваше предположение. Однако, другая версия библиотеки теперь валится. В логах /usr/sbin/fbguard: /usr/sbin/fbserver terminated abnormally (127) Что же тут не так ? Поставил пакет, все чистенько скомпилировалось вот такой последовательностью команд : gcc -fPIC -c ibu.c -o ibu.o gcc -shared -oibu.so ibu.o я код сократил, привел только одну падающую udf. они все падают одинаково. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41.
тут понятно что эта странная функция для windows-1251 работает только. Декларация в SQL такая DECLARE EXTERNAL FUNCTION UPCASE2000 CSTRING(2000) RETURNS CSTRING(2000) ENTRY_POINT 'upcase' MODULE_NAME 'ibu'; free_it ставили и не ставили - без разницы падает. Что теперь не так ? Откуда взялась эта манера передекларировать malloc - не понятно. Библиотека долго мигрировала между версиями. Потери памяти ведь небольшие и годами этого не замечали. Надо думать, неспроста такие декларации были сделаны - пакеты не смогли поставить, например. ... |
|||
:
Нравится:
Не нравится:
|
|||
09.06.2016, 00:26 |
|
подтекает память ( из UDF ? )
|
|||
---|---|---|---|
#18+
netwindchar* buf = (char *) ib_util_malloc(strlen(s) + 1); RETURNS CSTRING(2000) free-it тут нет, а память под возврат аллокируется в функции, и фактически замещает то, что ожидает получить ФБ. Вы почитайте safeudf.dpr из файла по ссылке выше. Я там все расписал предельно просто и понятно. В этой вашей upcase при такой декларации (без free_it) нужно модифицировать входную переменную, и ее же возвращать. netwindНадо думать, неспроста такие декларации были сделаны - пакеты не смогли поставить, например. какие еще пакеты? А насчет того, почему падает - у вас объявление функции кривое, как мне кажется. Например udflib.c - char* EXPORT fn_lower_c(char* s) fbudf.c - FBUDF_API void getExactTimestamp(ISC_TIMESTAMP* rc) где #define FBUDF_API __declspec(dllexport) а у вас - просто char * upcase(const char *s) и все. где явное указание типа вызова? ... |
|||
:
Нравится:
Не нравится:
|
|||
09.06.2016, 01:03 |
|
подтекает память ( из UDF ? )
|
|||
---|---|---|---|
#18+
netwindОткуда взялась эта манера передекларировать malloc - не понятно. откуда вообще взялась манера писать отсебятину в udf. :-) Есть же правила, которые давным-давно написаны. Если правила непонятны, то надо использовать готовые примеры (официальные или однозначно рабочие) как болванки. ... |
|||
:
Нравится:
Не нравится:
|
|||
09.06.2016, 01:06 |
|
подтекает память ( из UDF ? )
|
|||
---|---|---|---|
#18+
netwindБиблиотека долго мигрировала между версиями. Потери памяти ведь небольшие и годами этого не замечали. еще добавлю - такая ситуация как у вас, встречается не впервые. Например, кривой тип вызова (stdcall вместо cdecl) в udf на delphi мог не приводить ни к каким фатальным результатам. А начиная с определенного момента - переезд сервера на другую ОС или на новую версию ФБ, или даже просто на сервер добавили памяти или поставили другой софт - хлоп, и или сервер начинает падать, или функция возвращает мусор из памяти. ... |
|||
:
Нравится:
Не нравится:
|
|||
09.06.2016, 01:10 |
|
подтекает память ( из UDF ? )
|
|||
---|---|---|---|
#18+
kdvnetwindchar* buf = (char *) ib_util_malloc(strlen(s) + 1); RETURNS CSTRING(2000) free-it тут нет, а память под возврат аллокируется в функции, и фактически замещает то, что ожидает получить ФБ. Вы почитайте safeudf.dpr из файла по ссылке выше. Я там все расписал предельно просто и понятно. Да, все понятно. Это я неверное объявление скопировал. Падает не зависимо от наличия free_it. авторВ этой вашей upcase при такой декларации (без free_it) нужно модифицировать входную переменную, и ее же возвращать. совсем нет, мне это не нужно. netwindНадо думать, неспроста такие декларации были сделаны - пакеты не смогли поставить, например. какие еще пакеты? Пакеты в линуксе. Люди не могут поставить их, найти все заголовки .h и выдумывают что попало. Однако, я поискал и обнаружил старую версию в ветке 2.5 . Там тот самый malloc ! Это не фантазия разработчика, а официальный пример для 2.5 https://github.com/FirebirdSQL/firebird/blob/B2_5_Release/examples/udf/udflib.c А в ветке 3.0 уже поновее код. От него попытаюсь отталкиваться. авторА насчет того, почему падает - у вас объявление функции кривое, как мне кажется. Например udflib.c - char* EXPORT fn_lower_c(char* s) fbudf.c - FBUDF_API void getExactTimestamp(ISC_TIMESTAMP* rc) где #define FBUDF_API __declspec(dllexport) а у вас - просто char * upcase(const char *s) и все. где явное указание типа вызова? Пробовал и EXPORT определять. Но ведь он пустой теперь у меня следующий код по мотивам Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11.
EXPORT из example.h весьма банален ( https://raw.githubusercontent.com/FirebirdSQL/firebird/B3_0_Release/examples/include/example.h) Код: plaintext 1. 2. 3. 4. 5.
То есть, объявление типа бессмысленно продолжает падать. Какие современные примеры на C лучше посмотреть ? ... |
|||
:
Нравится:
Не нравится:
|
|||
09.06.2016, 01:15 |
|
подтекает память ( из UDF ? )
|
|||
---|---|---|---|
#18+
netwindОднако, я поискал и обнаружил старую версию в ветке 2.5 . Там тот самый malloc ! Это не фантазия разработчика, а официальный пример для 2.5 кстати, да, подтверждаю, у меня в дистре 2.5 тот же ужас в udflib.c. Это кто-то проехался search/replace. netwindТо есть, объявление типа бессмысленно тогда не знаю. Вот другой пример, из ib_util.h Код: plaintext 1. 2. 3. 4. 5.
netwindКакие современные примеры на C лучше посмотреть ? fbudf, rfunc. ... |
|||
:
Нравится:
Не нравится:
|
|||
09.06.2016, 01:25 |
|
подтекает память ( из UDF ? )
|
|||
---|---|---|---|
#18+
netwindЧто же тут не так ? Поставил пакет, все чистенько скомпилировалось вот такой последовательностью команд : gcc -fPIC -c ibu.c -o ibu.o gcc -shared -oibu.so ibu.oГде линковка с ib_util ? ... |
|||
:
Нравится:
Не нравится:
|
|||
09.06.2016, 01:42 |
|
подтекает память ( из UDF ? )
|
|||
---|---|---|---|
#18+
hvlad, вот это отличное замечание. Компилить мне надо так : gcc -c -O -fpic ibu.c ld -G ibu.o -lm -lc -lib_util -o ibu.so Все заработало, память не течет ! Почему же диагностика firebird не могла эту ситуацию распознать и выдать какие-нибудь наводящие ошибки ? ... |
|||
:
Нравится:
Не нравится:
|
|||
09.06.2016, 02:08 |
|
подтекает память ( из UDF ? )
|
|||
---|---|---|---|
#18+
Все переписали, но память продолжает течь хотя и с меньшей в 3 раза скоростью. сделал с помощью gdb core dump по-живому и пытаюсь смотреть на память как файл - буфер напоминает набор 32битных указателей. Ну типа стек или что-то связанное. А прошлый раз тем же способом я увидел характерные строки. Один раз я все-таки увидел на графике самопроизвольное уменьшение памяти, но это нечасто происходит. Что же еще не так и что еще проверить ? Приложение (не смейтесь) на дельфи. ... |
|||
:
Нравится:
Не нравится:
|
|||
03.07.2016, 21:21 |
|
подтекает память ( из UDF ? )
|
|||
---|---|---|---|
#18+
netwindПриложение (не смейтесь) на дельфи. Значит все утечки памяти способен обнаружить FastMM. Posted via ActualForum NNTP Server 1.5 ... |
|||
:
Нравится:
Не нравится:
|
|||
03.07.2016, 22:25 |
|
подтекает память ( из UDF ? )
|
|||
---|---|---|---|
#18+
Dimitry Sibiryakov, судя по описанию, это для клиентской стороны особый менеджер памяти. но как он обнаружит утечки на сервере firebird ? ... |
|||
:
Нравится:
Не нравится:
|
|||
03.07.2016, 22:41 |
|
подтекает память ( из UDF ? )
|
|||
---|---|---|---|
#18+
Ну да, сам он их не обнаружит. Для этого к нему нужен ещё и программист. Posted via ActualForum NNTP Server 1.5 ... |
|||
:
Нравится:
Не нравится:
|
|||
03.07.2016, 22:45 |
|
подтекает память ( из UDF ? )
|
|||
---|---|---|---|
#18+
Dimitry Sibiryakov, или вы меня вообще не понимаете или эта чудо-программа умудряется проверять всевозможные забытые в клиентском приложение дескрипторы FB, подтверждение чего я не нахожу. ... |
|||
:
Нравится:
Не нравится:
|
|||
03.07.2016, 22:51 |
|
подтекает память ( из UDF ? )
|
|||
---|---|---|---|
#18+
netwindэта чудо-программа умудряется проверять всевозможные забытые в клиентском приложение дескрипторы FB Большинство "забытых в клиентском приложении дескрипторов" светится в соответствующих таблицах мониторинга. Но тут уже нужен DBA. Posted via ActualForum NNTP Server 1.5 ... |
|||
:
Нравится:
Не нравится:
|
|||
03.07.2016, 22:59 |
|
подтекает память ( из UDF ? )
|
|||
---|---|---|---|
#18+
Dimitry Sibiryakov, уже лучше. Вызываю вертолет с DBA :) ... |
|||
:
Нравится:
Не нравится:
|
|||
04.07.2016, 00:12 |
|
подтекает память ( из UDF ? )
|
|||
---|---|---|---|
#18+
netwindПриложение (не смейтесь) на дельфи. Приложение или udf на дельфи? ... |
|||
:
Нравится:
Не нравится:
|
|||
04.07.2016, 09:12 |
|
подтекает память ( из UDF ? )
|
|||
---|---|---|---|
#18+
netwindDimitry Sibiryakov, судя по описанию, это для клиентской стороны особый менеджер памяти. но как он обнаружит утечки на сервере firebird ?Этот shared менеджер памяти не обнаруживает никаких утечек. Если функция объявлена с FREE_IT, для сервера Firebird это "сигнал", что буфер под результат был выделен через ib_util_malloc и что его необходимо очистить соответствующим образом. Всё! Если в udf'ке, для каких-либо иных нужд, необходимо выделить буфер, этот буфер должен выделяться обычным си-библиотечным std::malloc (ib_util_malloc ИСКЛЮЧИТЕЛЬНО для возврата серверу результата из udf). ... |
|||
:
Нравится:
Не нравится:
|
|||
04.07.2016, 09:14 |
|
подтекает память ( из UDF ? )
|
|||
---|---|---|---|
#18+
wadman, udf на классическом C и тексты функций я даже приводил некоторые. Сейчас в тексте udf нет левых malloc, так что я не представляю как еще можно создать утечку. Есть другие способы ? Видимо, теперь мне надо сосредоточиться на изучении служебных таблиц чтобы понять что еще не освобождает приложение. ... |
|||
:
Нравится:
Не нравится:
|
|||
04.07.2016, 11:12 |
|
подтекает память ( из UDF ? )
|
|||
---|---|---|---|
#18+
netwindСейчас в тексте udf нет левых malloc, так что я не представляю как еще можно создать утечку. Есть другие способы ? Утечку можно создать и правыми malloc(). Posted via ActualForum NNTP Server 1.5 ... |
|||
:
Нравится:
Не нравится:
|
|||
04.07.2016, 11:22 |
|
подтекает память ( из UDF ? )
|
|||
---|---|---|---|
#18+
netwindСейчас в тексте udf нет левых malloc, так что я не представляю как еще можно создать утечку. Есть другие способы ?Забыть написать FREE_IT в декларации UDF ... |
|||
:
Нравится:
Не нравится:
|
|||
04.07.2016, 11:36 |
|
подтекает память ( из UDF ? )
|
|||
---|---|---|---|
#18+
netwindСейчас в тексте udf нет левых malloc, так что я не представляю как еще можно создать утечку. Есть другие способы ? Видимо, теперь мне надо сосредоточиться на изучении служебных таблиц чтобы понять что еще не освобождает приложение.Полно! Есть, к примеру, "способ" выделить через std::malloc память, проинициализировать её адресом указатель - член класса в экземпляре класса и забыть прописать в деструкторе освобождение этой памяти через std::free. ... |
|||
:
Нравится:
Не нравится:
|
|||
04.07.2016, 13:00 |
|
|
start [/forum/topic.php?fid=40&msg=39267269&tid=1562095]: |
0ms |
get settings: |
11ms |
get forum list: |
14ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
38ms |
get topic data: |
8ms |
get forum data: |
2ms |
get page messages: |
58ms |
get tp. blocked users: |
1ms |
others: | 15ms |
total: | 155ms |
0 / 0 |