{"id":5434,"date":"2019-12-09T08:54:04","date_gmt":"2019-12-09T16:54:04","guid":{"rendered":"https:\/\/visualgdb.com\/w\/?p=5434"},"modified":"2023-09-28T19:10:59","modified_gmt":"2023-09-29T02:10:59","slug":"analyzing-code-coverage-for-embedded-projects","status":"publish","type":"post","link":"https:\/\/visualgdb.com\/tutorials\/profiler\/embedded\/coverage\/","title":{"rendered":"Analyzing Code Coverage for Embedded Projects"},"content":{"rendered":"<p>This tutorial shows how to use VisualGDB to analyze the code coverage of embedded projects. We will create a basic test project based on the TinyEmbeddedTest framework, will instrument it to produce code coverage reports at the end of the debug sessions and will show how to view the reports and reduce the memory overhead by controlling which files get instrumented.<\/p>\n<p>Before you begin, install VisualGDB 5.5 or later.<\/p>\n<ol>\n<li>Start Visual Studio and open the VisualGDB Embedded Project Wizard:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/11\/01-embwiz.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5435\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/11\/01-embwiz.png\" alt=\"\" width=\"1024\" height=\"710\" \/><\/a><\/li>\n<li>Specify the name and location for the project you are creating:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/11\/02-name-1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5436\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/11\/02-name-1.png\" alt=\"\" width=\"1024\" height=\"710\" \/><\/a><\/li>\n<li>On the first page of the VisualGDB&#8217;s part of the wizard, select &#8220;Create a new project -&gt; Unit test -&gt; MSBuild -&gt; TinyEmbeddedTest&#8221;:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/11\/03-test.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5437\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/11\/03-test.png\" alt=\"\" width=\"886\" height=\"693\" \/><\/a><\/li>\n<li>On the next page select the toolchain and your device. For most accurate code coverage results we advise using GCC 9.x or later:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/11\/04-device.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5438\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/11\/04-device.png\" alt=\"\" width=\"886\" height=\"693\" \/><\/a><\/li>\n<li>Proceed with the default test project sample and click &#8220;Next&#8221; to continue to the next page:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/11\/05-project.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5439\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/11\/05-project.png\" alt=\"\" width=\"886\" height=\"693\" \/><\/a><\/li>\n<li>Connect your JTAG debugger to the USB and make sure VisualGDB detects it. If not, you can pick a debug method manually on the <strong>Debug Method<\/strong> page of the wizard:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/11\/06-stlink.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5440\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/11\/06-stlink.png\" alt=\"\" width=\"886\" height=\"693\" \/><\/a><\/li>\n<li>Press &#8220;OK&#8221; to generate a basic project. Build it by pressing Ctrl-Shift-B and take a note of the FLASH\/RAM use via the Embedded Memory Explorer window:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/11\/07-memory.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5441\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/11\/07-memory.png\" alt=\"\" width=\"1227\" height=\"801\" \/><\/a><\/li>\n<li>Open VisualGDB Project Properties and go to the Code Coverage page. Enable the &#8220;build code coverage reports&#8221; checkbox and click &#8220;OK&#8221;. Click &#8220;Yes&#8221; when VisualGDB asks whether you want to enable code instrumentation in the build settings:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/11\/08-coverage.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5442\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/11\/08-coverage.png\" alt=\"\" width=\"953\" height=\"632\" \/><\/a><\/li>\n<li>Build the project again. Note that the instrumented code will use more FLASH (due to extra instructions needed to track the executed functions and branches) and more RAM (due to the variables storing the function\/branch counts):<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/11\/09-instrumented.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5443\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/11\/09-instrumented.png\" alt=\"\" width=\"1227\" height=\"801\" \/><\/a>We will show how to reduce the overhead caused by the code coverage instrumentation later in this tutorial. Note that if instrumenting all code results in more than 100% overhead, the VisualGDB&#8217;s logic for trimming unnecessary coverage-related structures from the object files is likely not running. Double-check that the build output contains the following line:\n<pre class=\"\">Detached X coverage information blocks from Y object files<\/pre>\n<p>If not. make sure you have enabled code coverage on the project level, not just in the C\/C++-&gt;Instrumentation. We will show the exact setting responsible for this later in the tutorial.<\/li>\n<li>Open the Test Explorer window, right-click on the test project and select &#8220;Run Selected Tests&#8221;:<br \/>\n<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/11\/10-runtests.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5444\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/11\/10-runtests.png\" alt=\"\" width=\"1227\" height=\"801\" \/><\/a><\/li>\n<li>When the tests finish running, open the <strong>Test-&gt;VisualGDB Code Coverage Reports window<\/strong> to display the code coverage from the latest run:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/11\/11-result.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5445\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/11\/11-result.png\" alt=\"\" width=\"1227\" height=\"801\" \/><\/a>The <strong>Code Coverage<\/strong> window will show statistics on the coverage of various functions in the project. As long as the coverage highlighting is enabled and you are using the Clang IntelliSense engine, the lines that were executed will be highlighted green and the lines that were never executed will be highlighted red. Note that the lines that could be resolved during compile time (e.g. CHECK_EQUAL(1,1)) will be excluded from the coverage report by gcc in order to reduce the memory overhead.<\/li>\n<li>Now try running only a single test:\u00a0 <a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/11\/12-test2.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5446\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/11\/12-test2.png\" alt=\"\" width=\"1227\" height=\"801\" \/><\/a><\/li>\n<li>Note how the body of the other tests is now highlighted in red (the test declaration will be highlighted in green because it contains a static constructor):<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/11\/13-onetest.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5447\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/11\/13-onetest.png\" alt=\"\" width=\"1227\" height=\"801\" \/><\/a><\/li>\n<li>Now we will show how to reduce the memory overhead caused by the code coverage. Open Visual Studio Project Properties for the project itself and go to the Embedded Project page. Make sure that the <strong>Instrument Code for Code Coverage setting<\/strong> is turned on: \u00a0 <a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/11\/14-instr1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5448\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/11\/14-instr1.png\" alt=\"\" width=\"1227\" height=\"801\" \/><\/a>Enabling this setting turns on coverage information optimization by VisualGDB. Unless it is enabled, GCC will try to insert the function layout information for every <strong>function<\/strong> defined in the project (even the unused ones) into the final binary, quickly consuming most of the available RAM.<\/li>\n<li>Go to the C\/C++-&gt;Instrumentation page of Visual Studio Project Properties and turn off the <strong>Generate Code Coverage Reports<\/strong> setting there. This will disable the instrumentation of all source files unless we override it for specific files:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/11\/14-noinstr.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5449\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/11\/14-noinstr.png\" alt=\"\" width=\"1227\" height=\"801\" \/><\/a>Note that the project-level setting configured in the previous step needs to be turned on.<\/li>\n<li>Now select specific file(s) you want to instrument and enable the &#8220;Generate Code Coverage Reports&#8221; option for them:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/11\/15-reinstr.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5450\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/11\/15-reinstr.png\" alt=\"\" width=\"1227\" height=\"801\" \/><\/a><\/li>\n<li>Build the project and run the tests. Note that the coverage report will only include the functions in the instrumented files and the overall memory overhead will be much lower: <a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/11\/16-report.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5451\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/11\/16-report.png\" alt=\"\" width=\"1227\" height=\"801\" \/><\/a><\/li>\n<li>Another way of limiting the files that get instrumented is using the &#8220;<strong>Only instrument Functions in Files<\/strong>&#8221; and &#8220;<strong>Skip Instrumenting Functions in Files<\/strong>&#8221; settings on the &#8220;<strong>C\/C++-&gt;Instrumentation<\/strong>&#8221; page of VS Project Properties. E.g. you can re-enable the instrumentation for all source files and then limit it to files ending with &#8220;<strong>Tests.cpp<\/strong>&#8221; as shown below:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/11\/17-regex.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5452\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/11\/17-regex.png\" alt=\"\" width=\"1227\" height=\"801\" \/><\/a>Note that setting the &#8220;<strong>Generate Code Coverage Reports<\/strong>&#8221; setting for individual files affects the entire translation unit (i.e. it will instrument the selected <strong>.cpp<\/strong> file and any inline functions in any header file that were called from that <strong>.cpp<\/strong> file). The &#8220;<strong>Only Instrument Functions in Files<\/strong>&#8221; setting filters the functions based on the exact file where they were defined. E.g. setting it to <strong>.*Tests\\.cpp <\/strong>(note the regex syntax) will instrument all functions defined in <strong>EmbeddedCoverageDemoTests.cpp<\/strong>, but not the inline functions in headers that were called from that <strong>.cpp<\/strong> file. Similarly, you can use the &#8220;Skip Instrumenting Functions in Files&#8221; option to exclude specific headers (e.g. defining syscalls) from instrumentation.<\/li>\n<li>VisualGDB builds its coverage reports from the raw reports generated by <strong>gcov<\/strong>. If you would like to feed the gcov files into another tool, enable <strong>Tools-&gt;Options-&gt;VisualGDB-&gt;General-&gt;Keep Raw Coverage Reports<\/strong>:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/12\/raw.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-8448\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/12\/raw.png\" alt=\"\" width=\"744\" height=\"489\" \/><\/a><\/li>\n<li>You will find the raw report files next to the <strong>.o<\/strong> files inside the build directory:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/12\/reports.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-8449\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/12\/reports.png\" alt=\"\" width=\"966\" height=\"495\" \/><\/a><\/li>\n<li>You can also run the tests and generate reports from command line by locating the test container file (<strong>.vgdbtestcontainer<\/strong>) and running <strong>VisualGDB.exe \/runtests &lt;container file&gt;<\/strong>. As long as the project is configured to produce coverage reports, running it via command line will produce them as well (including the raw files): <a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/12\/runtests.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-8450\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/12\/runtests.png\" alt=\"\" width=\"979\" height=\"512\" \/><\/a><\/li>\n<\/ol>\n<p>You can read more about VisualGDB coverage reports, and programmatic ways of reading them on <a href=\"https:\/\/visualgdb.com\/documentation\/embedded\/coverage\/#reports\">this page<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This tutorial shows how to use VisualGDB to analyze the code coverage of embedded projects. We will create a basic<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[108],"tags":[156,133,109,61],"_links":{"self":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/5434"}],"collection":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/comments?post=5434"}],"version-history":[{"count":3,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/5434\/revisions"}],"predecessor-version":[{"id":8451,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/5434\/revisions\/8451"}],"wp:attachment":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/media?parent=5434"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/categories?post=5434"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/tags?post=5434"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}