Отчет gcov не показывает покрытие для функций, вызываемых в потоке boost :: asio :: io_service - PullRequest
0 голосов
/ 21 марта 2020

Я использую boost :: asio :: io_service для вызова std :: thread, как показано ниже .. функция:

      91           0 : void start_tcp( std::shared_ptr<mapping_t> m_mapping, l_publisher& ll_publisher,
      92             :                 reg_publisher& reg_publisher, std::mutex& mtx, bool debug, const string& host,
      93             :                 uint16_t port, uint16_t maximum_number_of_connections ) {
      94             :     spdlog::info( "start_tcp debug:{} host:{} port:{} max_connections:{}", debug, host, port,
      95           0 :                   maximum_number_of_connections );
      96           0 :     modbus_t* ctx = nullptr;
      97           0 :     if( host == "0.0.0.0" ) {
      98           0 :         ctx = new_tcp( NULL, port ); 
      99             :     } else {
     100           0 :         ctx = new_tcp( host.c_str(), port );
     101             :     }

**Above function calling from thread insdie main.cpp:**
           :             std::thread tcp_thread{start_tcp,
     424             :                                    m_mapping,
     425           0 :                                    std::ref( l_publisher ),
     426           0 :                                    std::ref( reg_publisher ),
     427           0 :                                    std::ref( mtx ),
     428             :                                    debug_mode,
     429           0 :                                    input_file["bindAddress"].as<string>(),
     430           0 :                                    input_file["port"].as<unsigned>(),
     431           0 :                                    config["maximum-connections"].as<unsigned>()};
     432           0 :             io_service->run();

При компиляции я вижу .gcno файлы генерируются. Это означает, что я правильно установил -g -O0 --coverage флаг компилятора и затем -lgcov флаг компоновщика. Кроме того, после выполнения теста создаются файлы .gcda . Но для функции start_tcp покрытие не показано, даже если она выполнена. Я мог видеть следующее было напечатано на консоли, когда тест был выполнен; что означает, что эта функция выполняется. Но освещение ничего не показало. spdlog::info( "start_tcp debug:{} host:{} port:{} max_connections:{}", debug,

выдержка из тестового вывода: [2020-03-21 10: 41: 48.268] [info] start_tcp отладка: ложный хост: 127.0.0.1 порт: 1502 max_connections: 50 \ n '

Тест не является модульным тестом, скорее это функциональный тест, написанный на python (с использованием подпроцесса python), который проверяет параметры командной строки исполняемого файла, созданного из исходного кода.

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

1 Ответ

0 голосов
/ 22 марта 2020

Я решил эту проблему. Это не имеет ничего общего с потоками. В тесте используется исполняемый файл, созданный из исходного кода. Тест породил процесс из исполняемого файла, используя подпроцесс pythons, и в конце теста этот процесс завершается с использованием sigterm. Но исполняемый файл не обрабатывает сигтерму. Таким образом, файлы .gcda не были созданы, как описано здесь ...

http://gcc.1065356.n8.nabble.com/gcov-can-t-collect-data-when-process-is-executed-by-systemctl-start-but-it-can-when-executed-by-procs-td1396806.html

По умолчанию systemd прекращает обслуживание, отправляя SIGTERM. (См. Systemd.kill (5).) Если ваш сервис не обрабатывает его и будет просто убит, он не будет создавать файл .gcda.

Ваш сервис должен обрабатывать SIGTERM и завершать работу чисто, например:

void handler(int signum)
  {
    /* notify the operator that the service has receive SIGTERM
       and clean up (close file descriptors, etc).  */

    exit(0);
  }

  int main(int argc, char **argv)
  {
    signal(handler, SIGTERM);

    /* do service */
  }

enter code here

При использовании exit () будут вызваны функции, зарегистрированные atexit () и on_exit (). G CC регистрирует одну функцию atexit для создания файла .gcda.

Даже если без gcov рекомендуется перехватить SIGTERM и завершить работу вашего сервиса.

После добавления кода в мой main.cpp обрабатывать сигтерму, как предложено выше. Все отлично работает И я получил соответствующий отчет о покрытии.

Спасибо.

...