0
votes

I am using boost::asio::io_service to call the std::thread as shown below.. function:

      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();

When I compile I could see .gcno files are generated. It means, I properly set -g -O0 --coverage compiler flag and then -lgcov linker flag. Also, after the test has run, the .gcda files are generated. But there's no coverage shown for the function start_tcp even though it is executed. I could see the following been printed to the console when the test has executed; which means this function is executed. But the coverage hasn't shown anything. spdlog::info( "start_tcp debug:{} host:{} port:{} max_connections:{}", debug,

excerpt from test output: [2020-03-21 10:41:48.268] [info] start_tcp debug:false host:127.0.0.1 port:1502 max_connections:50\n'

The test is not a unit test, rather it's a functional test written in python (using python subprocess) which validates the commandline options of an executable built from the source.

Can someone help me with this problem. Am I doing anything wrong or for boost threads do we need some other special flags if any to get the right coverage report??

1

1 Answers

1
votes

I resolved this problem. It is nothing to do with threads. The test is using the executable built from source. Test has spawn the process from executable using pythons subprocess and at the end of the test, this process is terminating using sigterm. But the executable is not handling the sigterm. So no .gcda files been created as explained here...

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

By default systemd terminates a service by sending SIGTERM. (See systemd.kill(5).) If your service doesn't handle it and will just be killed, it won't produce .gcda file.

Your service should handle SIGTERM and terminate cleanly, like:

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

By using exit(), the functions registered by atexit() and on_exit() would be called. GCC registers one atexit function to produce .gcda file.

Even if without gcov, it's recommended to catch SIGTERM and terminate your service cleanly.

After adding code to my main.cpp to handle the sigterm as suggested above. Everything works fine. And I got the proper coverage report.

Thanks.