LINUX.ORG.RU

Как ограничить аппетит clangbackend

 , ,


5

3

Есть очень жирный проект на С++ который открыт в Qt Creator в котором включен «Clang Code Model». Проблема состоит в том, что временами процесс clangbackend уходит в себя и начинает неистово жрать время CPU. В результате чего вся система стает раком.

Понятно, что clangbackend так себя ведет не от хорошего кода (в проекте). Однако у меня вопрос: как (на уровне системы?) ограничить время CPU уделяемое процессу clangbackend (и, возможно, qtcreator)?

Багрепорт: https://bugreports.qt.io/browse/QTCREATORBUG-11640

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

Ну, когда он сьедает память — другая история. Я на него ulimit натравил. В таких случаях приходит oomkiller.

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

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

Я просто периодически его прибиваю когда он выше 3 гигов наглеет.


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

ymuv ★★★★ ()

Дело не в размере (c).

У меня на относительно мелком проекте ведёт себя так же. Лечиться смертоубийством жрущего процесса. Но вообще это явно бага, может в 4.5 поправят...

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

может в 4.5 поправят...

Я собрал себе 4.5 уже (из Git), не поправили... Вот что интересно QtCreator 4.4 работает только с llvm-3.9 при сборке (на 4.5 не проверял — не было времени)

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

Если заморочился уже со сборкой,

Да, я правда не для того собирал. Занимаюсь плагинописанием в свободное (от лени) время: https://github.com/elvenfighter/remotedev

Но посмотреть дебагером где оно висит может быть сложно: как я написал оно систему мне раком ставит. Но нутром чую — приключения на данном треде не закончатся

KennyMinigun ★★★★★ ()

Итак, вдоволь напердолившись с документацией cgroups (willkommen sie bitte: cgroups-v1, cgroups-v2) я решил, что оно таки не совсем мне похдходит и вообще (ой все!)...

С другой стороны я набрел на документацию по сборке Qt Creator c Git и (с удивлением для себя) обнаружил там требованиe "LLVM/Clang 5.0.0 or later". Однако последний QtCreator (4.5) отказывается собираться с libclang выше (и ниже) версии 3.9.

В то же время с багрепорта (QTCREATORBUG-11640) я вычитал комментарий разработчика (который собственно баг поправил). Nikolai Kosjar:

Regarding the memory consumption of the backend:

  • I've added a new API call to libclang that will suspend a translation unit, basically freeing all memory associated with it, except the preamble file on disk. This is part of upcoming clang 5.0 and I've also backported it to our shipped libclang 3.9. If you build Qt Creator yourself, you need to apply the llvm/clang patches from ${QT_CREATOR_SOURCE}/dist/clang/patches).
  • The backend will suspend the translation units of documents that are not in the top 7 most recently used list (tracked by visibility). If they become visible again later, the translation units are restored (a restore takes the time of a reparse). The number of «hot documents» to keep can be configured with the run time env variable QTC_CLANG_HOT_DOCUMENTS=N for now, 7 is the default. Not sure whether this should be configurable in the UI (for Qt Creator 4.4, this is too late).

I see how this helps with valgrind massif, but not directly when looking at the process monitor. I guess this is due memory fragmentation, so it probably pays off after longer use. New snapshots with this change are probably available from tomorrow on.

Ну и в результате я решил таки собрать qtcreator из мастера (скрестите пальцы за меня). И о чудо! На qmake оно уже не ругается на libclang 5.0. Потом отпишусь о результатах сборки.

KennyMinigun ★★★★★ ()

Однако у меня вопрос: как (на уровне системы?) ограничить время CPU уделяемое процессу clangbackend

systemd умеет. CPUQuota называется. только не знаю, можно ли clangbackend сделать сервисом.
или www.linux.org.ru/forum/talks/11899738#comment-11900409

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

systemd умеет. CPUQuota называется.

Насколько я понял (читая документацию) systemd делает это через cgroups. Т.е. можно и без systemd.

https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/6/html...

И еще вот про память: https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/6/html...

KennyMinigun ★★★★★ ()
Ответ на: комментарий от system-root

я не знаю как настроить cgroups чтобы для процесса, а не группы.

отпиши как решишь эту проблему пожалуйста.

Проблему я решил (надеюсь) немного другим способом. Но с того, что я прочитал — надо создать cgroup (v1) c контроллерами memory и cpu. Т.е. что-то такое в /etc/cgroup.conf:

group limit_usage {
    cpu {
# 50% CPU, или половина значения из /sys/fs/cgroup/cpu/cpu.shares
         shares = 512
# Или можно определить, что за одну секунду процессы в групе
# могут использовать процессор 0.5 секунды
#        cfs_period_us = 1000000
#        cfs_quota_us  =  500000
    }
    memory {
# Максимально 3 гигабайта
        limit_in_bytes = "3G"
    }
}
* Предполагается использование cgroups-v1 (ибо в Ubuntu они по умолчанию примонтированы)
** Предполагается, что контроллеры cpu,memory уже примонтированы, иначе надо еще дописать секцию mount в конфигурации

Далее можем запустить наш процесс:

cgexec -g cpu,memory:limit_usage qtcreator

Или пересунуть уже запущенный процесс:

cgclassify -g cpu,memory:limit_usage --cancel-sticky $(pgrep clangbackend)

Конечно подписаться за то, что оно работает не могу — ибо не пробовал. Но, очень вероятно, скоро попробую.

Пока что завтра посмотрю как qtcreator 4.6 (master) заработает с libclang 5.0

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

Немного конфигурация кривая, поправил. Вот так работает:

group limit_usage {
    perm {
        task {
            gid = cgtask;
            fperm = 777;
        } 
        admin {
            uid = root;
        }
    }
    cpu {
        cpu.shares = 512;
    }
    memory {
        memory.limit_in_bytes = "1G";
    }
}

Только я срздал групу cgtask специально:

sudo groupadd cgtask
sudo usermod -a -G cgtask $USER

Ну и потом запустил:

# загружаем нашу конфигурацию
sudo cgconfigparser -l /etc/cgconfig.conf

# запускаем процесс
cgexec -g mem,cpu:limit_usage stress --cpu 1 --vm 1 --vm-bytes 6G

Еще б расковырять cgred, чтоб вообще автоматически. https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/6/html...

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

Я просто периодически его прибиваю когда он выше 3 гигов наглеет.

Подсветка и прочие плюшки из-за это не начинают лагать? У меня та же проблема. На компе 8 Гб и эта сволочь всё сжирает.

ox55ff ()

Status Update

После нескольких дней использования QtCreator 4.6 beta (master) + libclang 5.0 зависаний не было, продолжаю наблюдения.

Единственное — местами показывает ошибки где их нет.

KennyMinigun ★★★★★ ()
Последнее исправление: KennyMinigun (всего исправлений: 1)
Ответ на: Re: Status Update от anonymous

На жирном проекте, ругается на недостачу параметра в, например, таком:

struct ValueView {
    template <typename T>
    T parse(int index, const T& defaultValue = T());
}

const auto value = view.parse<int>(10); // тут: expected 2 arguments

Дома на хеловорлде, естественно не удалось воспроизвести... Но на работе проект нормально собирается clang++ (3.9), g++ (6.2, 7)

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

Понятно, что clangbackend так себя ведет не от хорошего кода (в проекте)

Как бе от качества кода тут мало что зависит, на болшом объеме хорошего та же картина

annulen ★★★★★ ()
Ответ на: Re: Status Update от anonymous

Единственное — местами показывает ошибки где их нет.

Например?

Каєется я нашел проблему: /usr/include/c++/7/type_traits

#ifdef _GLIBCXX_HAVE_BUILTIN_HAS_UNIQ_OBJ_REP
# define __cpp_lib_has_unique_object_representations 201606
  /// has_unique_object_representations
  template<typename _Tp>
    struct has_unique_object_representations
    : bool_constant<__has_unique_object_representations(
      remove_cv_t<remove_all_extents_t<_Tp>>
      )>
    { };
#endif
#undef _GLIBCXX_HAVE_BUILTIN_HAS_UNIQ_OBJ_REP

Ругается на последние две строчки кода (не инструкции препроцессора):

3083:7: error: expected '(' for function-style cast or type construction
3084:5: error: expected class name

И потом идет вразнос...

KennyMinigun ★★★★★ ()