Средства диагностики Плагин для Qt Creator

Доброго времени суток. Недавно загорелся идеей написать простой, но функциональный плагин для среды разработки Qt Creator, предназначенный для визуализации данных об использовании оперативной памяти и загрузки ЦП текущим запущенным процессом. В качестве вдохновения для меня послужил инструментарий «Средства диагностики», присутствующий в Visual Studio. Ниже я расскажу об основных деталях разработки.


Так как тема создания плагинов для Qt Creator уже подробно описана на хабре, например, в статье Система расширений Qt Creator, то поэтому не буду останавливаться на общей информации и перейду сразу к описанию плагина.

Собственно, для того, чтобы получить информацию о любом запущенном в операционной системе процессе для начала необходимо узнать его идентификатор (PID). Вопросом получения PID запущенного через Qt Creator процесса я и занялся в первую очередь. После безрезультатного гугления на эту тему я перешел к изучению исходников Qt Creator, в ходе чего обнаружил, что узнать искомые данные несложно. Для этого нужны поймать следующие сигналы, испускаемые статическим экземпляром ProjectExplorer::ProjectExplorerPlugin::instance():
void runControlStarted(ProjectExplorer::RunControl *rc);
void runControlFinished(ProjectExplorer::RunControl *rc);

// connects
    connect(ProjectExplorer::ProjectExplorerPlugin::instance(),
      &ProjectExplorer::ProjectExplorerPlugin::runControlStarted,
            this, &DiagnosticToolsPlugin::onRunControlStarted);

    connect(ProjectExplorer::ProjectExplorerPlugin::instance(),
      &ProjectExplorer::ProjectExplorerPlugin::runControlFinished,
            this, &DiagnosticToolsPlugin::onRunControlFinished);

// slots
void DiagnosticToolsPlugin::onRunControlStarted(ProjectExplorer::RunControl *rc){
    m_runControlPtr = rc;
    connect(m_runControlPtr,
            &ProjectExplorer::RunControl::applicationProcessHandleChanged,
            this, &DiagnosticToolsPlugin::onApplicationHandleChanged);
}
void DiagnosticToolsPlugin::onRunControlFinished(ProjectExplorer::RunControl *rc){
    Q_UNUSED(rc)
    m_runControlPtr = NULL;
    m_dataQueryEngine->stopDataQuery();
}
void DiagnosticToolsPlugin::onApplicationHandleChanged(){
    if (m_runControlPtr->applicationProcessHandle().isValid()){
        m_dataQueryEngine->setPid(m_runControlPtr->applicationProcessHandle().pid());
        m_dataQueryEngine->startDataQuery();
    } else {
        qDebug() << "Process handle is invalid";
    }
}

Получив сигнал runControlStarted(ProjectExplorer::RunControl *rc), запоминаем указать m_runControlPtr на объект ProjectExplorer::RunControl *rc и далее по сигналу applicationProcessHandleChanged запускаем запрос данных.

Следующие задачи были тривиальными. В операционной системе Windows информация об используемой процессом памяти и загрузке ЦП была получена через WinApi, в Linux — посредством анализа содержимого файлов /proc/pid/stat и /proc/stat.

Финальный штрих — визуализация собранной информации. Первой мыслью было использовать модуль Qt для построения графиков Qt Charts, но в виду того, что данный компонент не является частью Qt Creator из коробки и по причине простоты решаемой мною задачи, в итоге было решено реализовать свой класс для рисования графиков. Закончив работу с GUI, я стал думать, где разместить созданную графическую форму. С одной стороны, было бы логично поместить ее снизу вместе с остальными панелями вывода, с другой — хотелось бы видеть одновременно и вывод приложения и информацию об используемых им ресурсах компьютера. Поэтому было принято волевое (возможно, неудачное) решение поместить графическую форму на левую боковую панель. И вот, что получилось в итоге:


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

Всем спасибо за внимание.

UPD
Статья была отредактирована с учетом замечания хабропользователя Krepver
Поделиться публикацией
AdBlock похитил этот баннер, но баннеры не зубы — отрастут

Подробнее
Реклама

Комментарии 18

    0
    Windows only?
      +2
      в Linux — посредством анализа содержимого файлов /proc/pid/stat и /proc/stat.
        0
        Точно. Я этот момент проморгал. Спасибо.
        0
        В операционной системе Windows информация об используемой процессом памяти и загрузке ЦП была получена через WinApi, в Linux — посредством анализа содержимого файлов /proc/pid/stat и /proc/stat.


        Думаю Windows и Linux

        Не прогрузился ответ выше)
        0
        Может быть, кто-нибудь подкинет другие идеи по улучшению.

        Как на счет подсчета утечек памяти?
          0
          Valgrind?
            0
            Valgrind хорош, но у него часто бывают ложные срабатывания при анализе Qtшного приложения. Шикарно было бы, если б динамический анализатор понимал Qtшный менеджер памяти.
          0
          Круть, полезная вещь! Завтра, на свежую голову, попытаюсь вкрутить в свой Creator :)
          Спасибо автору за разработку.
            0
            1. Предлагаю не очищать график после закрытия приложения. (Ну или все очищать, не только график но и числа)
            2. Сделать чтобы число объема памяти вмещалось вне зависимости от ширины. (Сейчас под поле отводится фиксированный % ширины, чуточку «умнее» бы)
            screenshot Спасибо, плагин понравился. Kubuntu 16.04 x64.
            0
            Имеет смысл релиз сделать обычным способом. ИМХО.
            То есть бинари запаковать и выложить на гитхабе на вкладке releases, а из исходников убрать.
              0
              Плагин супер. Фичи, которые хотелось бы видеть:

              1) Отображение графиков после выключения приложения
              2) Скроллинг по графикам
              3) Совсем было бы чудесно видеть используюемую память при отладке на Remote Device. Хотя бы в случае, когда Remote Device — это localhost.

              Если будет время сегодня, может быть сам попробую запилить эти фичи, хотя бы первые две.
                +1
                Отличный плагин, спасибо за труды!

                Помимо вышесказанного хотелось бы иметь:

                1) Английский язык в интерфейсе
                2) Возможность выгрузить логи сессии диагностики во внешний файл (csv, например) для того, чтобы можно было запустить тестирование и потом проанализировать нагрузку от приложения на больших отрезках времени (час, сутки...)
                  0

                  Собрал для версии 4.1.0, но у плагина не получается получить pid, в qDebug пишет


                  ProjectExplorer::ProjectExplorerPlugin::updateRunActions signal
                  PID: 0
                    0
                    Хм, с ходу не могу ответить. Возможно, как-то повлияла разница в минорных версиях. Разработка велась для Qt Creator 4.2.1.
                    А на какой ОС и с каким компилятором собираете?
                      0

                      Ubuntu 17.04, gcc 6.3


                      Решил проблему так:
                      Завел слот onApplicationHandleChanged и в onRunControlStarted сделал


                      connect(m_runControlPtr,
                              &ProjectExplorer::RunControl::applicationProcessHandleChanged,
                              this, &DiagnosticToolsPlugin::onApplicationHandleChanged);

                      setPid и startDataQuery вызываю уже там (при условии, что m_runControlPtr->applicationProcessHandle().isValid()


                      Pull request сделать?

                • НЛО прилетело и опубликовало эту надпись здесь

                  Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                  Самое читаемое