LINUX.ORG.RU

Есть ли способ отловить, где течет С?

 ,


1

3

Приветствую.

Есть С-код: https://github.com/derickr/pecl-dbus/blob/master/dbus.c

Если вкратце, этот код - биндинг полутора функций для работы с d-bus.

И этот код течет аки решето.

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

Вопрос: есть ли какой-нибудь изящный способ вывести все переменные объекта или иным способом отдебажить где жор?

Благодарю.

★★★★★

Последнее исправление: Dimez (всего исправлений: 2)

Ответ на: комментарий от windows10

Судя по документации, valgrind можно использовать для отладки плагинов или библиотек. Для этого нужно запустить под ним основное приложение, которое эти библиотеки подгрузит.

Werenter ★★★
()
Ответ на: комментарий от anonymous

собери php с дебагом и суй в valgrind

Fatal error: Arginfo / zpp mismatch during call of

Короче надо пол-кода перелопатить, уж проще тогда в каждую функцию free() понапихивать.

windows10 ★★★★★
() автор топика
Ответ на: комментарий от Werenter

Судя по документации, valgrind можно использовать для отладки плагинов или библиотек. Для этого нужно запустить под ним основное приложение, которое эти библиотеки подгрузит.

Не. Как я и предполагал - не подходит.

Оно же дебажжит общий код, куда входит и код пыха, и код zend'а с его собственными вызовами.

==224393== 520 bytes in 13 blocks are definitely lost in loss record 67 of 70
==224393==    at 0x4841828: malloc (vg_replace_malloc.c:442)
==224393==    by 0x7597248: ???
==224393==    by 0x758B84C: ???
==224393==    by 0x75796B6: ???
==224393==    by 0x485F6A6: ???
==224393==    by 0x6091AA: ZEND_DO_FCALL_SPEC_RETVAL_UNUSED_HANDLER (zend_vm_execute.h:1761)
==224393==    by 0x6091AA: execute_ex (zend_vm_execute.h:55803)
==224393==    by 0x609803: zend_execute (zend_vm_execute.h:60147)
==224393==    by 0x59D9F9: zend_execute_scripts (zend.c:1799)
==224393==    by 0x539D29: php_execute_script (main.c:2541)
==224393==    by 0x67E85D: do_cli (php_cli.c:965)
==224393==    by 0x3407D1: main (php_cli.c:1367)
windows10 ★★★★★
() автор топика

Предлагаю собрать pecl-dbus с address sanitizer. Что то в духе:

phpize
CFLAGS=" -fsanitize=address -static-libasan -g " ./configure
make && make install

Возможно надо уточнить как CFLAGS передать в configure.

Потом можно позапускать примеры из https://github.com/derickr/pecl-dbus/tree/master/examples

и посмотреть как они текут.

imatveev13
()
Ответ на: комментарий от windows10

Короче надо пол-кода перелопатить

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

i-rinat ★★★★★
()
Ответ на: комментарий от i-rinat

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

Нет, я думал что есть в С волшебная функция которая может распечатать все объекты или все переменные объекта. А что, разве нет ?

windows10 ★★★★★
() автор топика

Вопрос: есть ли какой-нибудь изящный способ вывести все переменные объекта или иным способом отдебажить где жор ?

вы-же как-то выяснили что «тикёт» и уверены что именно там ?

соотв. вариант - писать пачку тест-кейсов, вылавливая где течёт особенно сильно и сужая «полторы функции» до одной и минимальных сценариев.

Дальше -g , attach gdb и неделя незабываемого секса :-) более волшебных способов нет

MKuznetsov ★★★★★
()

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

условно говоря некая функция навроде

some_type* create_something(…)

тогда код создает обьект и отдает его тебе, но ты должен этот обьект каким-то образом уничтожить, если он тебе уже не нужен.

но для этого надо читать доки, и понимать логику программы, а не «распечатывать переменные». то есть понимать, где тебе отдали новый обьект и поручили его в последствии уничтожить тем или иным способом.

alysnix ★★★
()
Ответ на: комментарий от windows10

думал что есть в С волшебная функция которая может распечатать все объекты или все переменные объекта

В Си нет интроспекции. Так что придётся самому такие писать, под каждую структуру отдельно, ручками.

i-rinat ★★★★★
()
Ответ на: комментарий от windows10

Это я еще давно увидел, но увы и ах.

Там внизу есть ссылка на другую проблему, а именно - отказ от zval в php8 и фикс, также там есть комментарий что на 8й версии все работает без утечек. Этой информации вполне достаточно чтобы отловить проблему или использовать php8.

Obezyan
()
Ответ на: комментарий от Obezyan

Там внизу есть ссылка на другую проблему, а именно - отказ от zval в php8 и фикс, также там есть комментарий что на 8й версии все работает без утечек.

Не, я использую его репу, там все по старому, и PHP соответственно 8.1.

https://ibb.co/JpDrWSN

Он кстати пишет что «Still looking into the memory leaks as noted in».

windows10 ★★★★★
() автор топика
Ответ на: комментарий от cumvillain

Ты можешь взять bpf и отследить места аллокаций, но valgrind действительно лучше.

Я с нуля уже половину обертки написал, мне там немного функций надо на самом деле.

windows10 ★★★★★
() автор топика
Ответ на: комментарий от cumvillain

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

token_polyak ★★★★
()
Последнее исправление: token_polyak (всего исправлений: 3)

Приношу свои извинения наСИльникам. Дырявым оказался не C, а предсказуемо GTK, точнее GObject.

GTK позволяет привязать к объекту событие с обработчиком, например к кнопке событие нажатия на нее.

Фишка в том, что удаление объекта GTK оказывается удаляет все дочерние объекты, но не удаляет привязанные события.

Т.е. создали мы 100 кнопок с обработчиком нажатия, например по килобайту на кнопку, затратили 100 Кб. Потом удалили 100 кнопок, но при этом освободилось не 100 Кб, а только 80 Кб.

Notabug зарепорчен в 2003 году, и на серьезных щщах обсуждался до 2012 года, но так и не был пофикшен, а вместо этого введена доп. фишка которая как бы удаляет обработчик вручную, правда для этого нужно хранить не только объект (кнопку) а и ID события, ассоциированного с этим объектом.

К чему это приводит.

Допустим у нас есть динамично изменяющееся поле, в моем случае это системный трей. Трейнулось приложение - создалась иконка, создался обработчик нажатия на нее. Закрыли приложение, иконку прибили, но событие так и осталось висеть. Изменило приложение свою конфигурацию, перерисовали трей или иконку, и теперь на это приложение у нас два события, при том одно из них никогда не будет обработано, ибо висит уже на несуществующем объекте. Зомби-обработчик без родителя, мать его. Оверхед небольшой, примерно килобайт-полтора на событие, и как я понял после перелопачивания кодов трех ДЕ - им пренебрегают.

Теоретически, при долгом аптайме и активном использовании Гнома\Крысы\ЛХДЕ, они будут потреблять больше и больше памяти, если только не используют какой-нибудь самопальный костыль для очистки мусора.

Что сказать. Очередное разочарование GTK и еще больше понимания, почему оно столько жрет и так тормозит.

windows10 ★★★★★
() автор топика
Последнее исправление: windows10 (всего исправлений: 1)
Ответ на: комментарий от windows10

ни разу не лазил в gtk, но из общих соображений сказать имею.

система не может автоматом «удалить» этот ваш обработчик, поскольку он может быть статическим, а не на куче.

также, если один обработчик привязан к разным «ивентам» или этим прости господи гэ-обьектам, то его тоже удалять нельзя.

но там какой-то механизм для решения этой проблемы быть обязан.

alysnix ★★★
()
Последнее исправление: alysnix (всего исправлений: 1)
Ответ на: комментарий от windows10

Приношу свои извинения наСИльникам. Дырявым оказался не C, а предсказуемо GTK, точнее GObject.

GTK позволяет привязать к объекту событие с обработчиком, например к кнопке событие нажатия на нее.

Фишка в том, что удаление объекта GTK оказывается удаляет все дочерние объекты, но не удаляет привязанные события.

Т.е. создали мы 100 кнопок с обработчиком нажатия, например по килобайту на кнопку, затратили 100 Кб. Потом удалили 100 кнопок, но при этом освободилось не 100 Кб, а только 80 Кб.

А можно вопросик: что в 2024 году заставляет писать на этом? Я понимаю 20 лет назад, когда это все Мигелем пилилось, не было по сути нихрена в открытом доступе. Да и у конкурентов было тоже самое винформс/с/с++ и обж-с. И тогда этот гдк, а тем более гтк 2, выглядел, как откровение. Но щас то людям дали моно/джаву. У той же джавы под капотом от коллекций и шифрования до вебкита и гстримера в стандартной библиотеке. И все это будет работать, как минимум на венде, линуксе и маке. Зачем чего ради надо давиться GTK и писать на C три кнопки, два окошка?

Ygor ★★★★★
()
Ответ на: комментарий от Ygor

Унификация.

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

У джавы под капотом не системный фреймворк, а набор для рисования, такой же как и в Паскале, Луа, Питоне и прочих.

Но вопрос не в рисовании кнопки. Вопрос в перерисовке кнопок в сотне приложений, когда одно из них применит другую системную тему, например. Вопрос в том, что приложение №1 может послать команду «свернуть окно» приложению №2, и то свернется. Вопрос в том, что десять приложений может вызвать меню открытия файла, которое будет одинаковым для всех. Вопрос в том, что в программе ты можешь вызвать иконку «folder» и плевать в каком файле темы будет физически находиться эта иконка.

В общем ГТК это не рисовалка, а целый набор взаимодействия как между собой, так и с системой.

windows10 ★★★★★
() автор топика
Ответ на: комментарий от einhander

Все тормозит кроме божественного Tk)))

Если снять с машины кузов, сидения, стекла и руль - она тоже будет ехать быстрее. Но есть один нюанс(с).

windows10 ★★★★★
() автор топика
Ответ на: комментарий от alysnix

система не может автоматом «удалить» этот ваш обработчик, поскольку он может быть статическим, а не на куче.

Упоротый механизм, я бы даже сказал имбецильный.

Было бы логично, если бы этот обработчик имел свой уникальный идентификатор. Но он имеет лишь int номер в контексте свойств объекта, т.е. есть ему нельзя сделать g_object_unref и\или g_free.

То есть если объект по какой-то причине потерялся, обработчик все равно висит и удалить его уже нельзя. Равно как и нельзя получить все существующие обработчики объекта.

но там какой-то механизм для решения этой проблемы быть обязан.

Через жопу. И все равно не работает, хоть и не возвращает ошибку. Сначала грешил на PHP, потом перенабрал на С - все то же самое.

Создал кнопку, навешал на нее событие которое вернуло мне int. Событие я могу прибить только пока жива кнопка, ну да бог с ним, прибил. Событие и вправду перестало отрабатываться, но память не высвободилась, такое впечатление что обработчик не удалился, а просто деактивировался.

Даже если такой механизм существует, то его скрытость и сложность мне не понятна. Я может и профан в программировании, но как мне кажется на каждый create должен быть свой destroy, на каждый open должен быть свой close.

windows10 ★★★★★
() автор топика
Ответ на: комментарий от token_polyak

ставящих пробелы перед знаками препинания … носителя каждого языка, в котором они (знаки) водятся.

В французском перед несколькими знаками препинания нужны пробелы.

gag ★★★★★
()
Ответ на: комментарий от Ygor

дали моно/джаву.

Если бы оно не выглядело и не вело себя как что-то инопланетное, то возможно ты был бы прав. Работа с hidpi на моно похоже на пляски с бубном, чтобы текст не уезжал с кнопок и так далее. Пару раз у меня сегфолтился именно моно, а не приложение. Запихнуть уже готовое моно приложение в аппимадж у меня ни разу не получилось.

При этом с gtk/qt таких проблем нету.

einhander ★★★★★
()
Последнее исправление: einhander (всего исправлений: 1)
Ответ на: комментарий от windows10

Единственная правда в том что swing не подхватит системную тему, придётся ручками до чего-то допиливать через конфиг.

А на фоне jconsole, которую всегда можно открыть и посмотреть, что происходит в приложении, твой gtk выглядит как неандерталец с топором.

В общем ГТК это не рисовалка, а целый набор взаимодействия как между собой, так и с системой.

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

А ещё помню, как во времена второго гнома надо было периодически перезахоронить в систему, чтобы оно освободило своп. И судя потому, что ты написал ровно ничего не изменилось. А уж писать ООП на языке без поддержки ООП - особое удовольствие.

Ygor ★★★★★
()
Ответ на: комментарий от einhander

Я моно упомянул просто для красного словца, на джаве таких проблем нет - текст не уезжает, падения происходят только по ошибкам в программе, а внешний вид можно настроить в конфиге. Правда не думаю, что оно будет в точности копировать системную тему.

Ygor ★★★★★
()
Ответ на: комментарий от Ygor

Запуск jvm все равно не быстрый даже на nvme. Проблем с уехавшим интерфейсом меньше, но не сказал бы что нет совсем. Системная тема это это не самое главное, диалог выбора файлов как правило не системный и зачастую всратый.

einhander ★★★★★
()