gcov: print selected annotated source files only

Fixes #3070
This commit is contained in:
Christian Prochaska 2018-12-03 18:18:53 +01:00 committed by Norman Feske
parent abe80a4bfe
commit 97d8bea5ec
4 changed files with 148 additions and 21 deletions

View File

@ -80,6 +80,11 @@
<default caps="100"/>
<start name="test-xml_generator">
<resource name="RAM" quantum="2M"/>
<config>
<libgcov>
<annotate source="include/util/xml_generator.h"/>
</libgcov>
</config>
</start>
</config>
</runtime>

View File

@ -1 +1 @@
f0518e32e26d8286b84789e661c4999e01d8b569
f08ebbb6104c2ac722fc5222939bfd9bcdef3d1f

View File

@ -4,11 +4,11 @@ From: Christian Prochaska <christian.prochaska@genode-labs.com>
---
gcc/gcov.c | 89 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 84 insertions(+), 5 deletions(-)
gcc/gcov.c | 134 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 128 insertions(+), 6 deletions(-)
diff --git a/gcc/gcov.c b/gcc/gcov.c
index 50061c7..eead285 100644
index 50061c7..b9ddccb 100644
--- a/gcc/gcov.c
+++ b/gcc/gcov.c
@@ -41,10 +41,13 @@ along with Gcov; see the file COPYING3. If not see
@ -25,7 +25,19 @@ index 50061c7..eead285 100644
/* The gcno file is generated by -ftest-coverage option. The gcda file is
generated by a program compiled with -fprofile-arcs. Their formats
are documented in gcov-io.h. */
@@ -350,6 +353,16 @@ static int flag_all_blocks = 0;
@@ -299,6 +302,11 @@ static unsigned bbg_stamp;
static char *da_file_name;
+/* Name and file pointer of the input file for the annotation source list (gcan). */
+
+#define GCOV_ANNOTATE_SUFFIX ".gcan"
+static char *an_file_name;
+
/* Data file is missing. */
static int no_data_file;
@@ -350,6 +358,16 @@ static int flag_all_blocks = 0;
static int flag_function_summary = 0;
@ -42,7 +54,7 @@ index 50061c7..eead285 100644
/* Object directory file prefix. This is the directory/file where the
graph and data files are looked for, if nonzero. */
@@ -407,6 +420,43 @@ static void release_structures (void);
@@ -407,6 +425,43 @@ static void release_structures (void);
static void release_function (function_t *);
extern int main (int, char **);
@ -86,7 +98,7 @@ index 50061c7..eead285 100644
int
main (int argc, char **argv)
{
@@ -437,7 +487,7 @@ main (int argc, char **argv)
@@ -437,7 +492,7 @@ main (int argc, char **argv)
sources = XNEWVEC (source_t, a_sources);
argno = process_args (argc, argv);
@ -95,7 +107,7 @@ index 50061c7..eead285 100644
print_usage (true);
if (argc - argno > 1)
@@ -445,6 +495,15 @@ main (int argc, char **argv)
@@ -445,6 +500,18 @@ main (int argc, char **argv)
first_arg = argno;
@ -104,14 +116,17 @@ index 50061c7..eead285 100644
+ /* search .gcda files and process each one */
+ process_files("/");
+
+ /* finish processing arguments */
+ argno = argc;
+ generate_results(NULL);
+
+ release_structures();
+
+ return 0;
+ }
+
for (; argno != argc; argno++)
{
if (flag_display_progress)
@@ -488,7 +547,8 @@ print_usage (int error_p)
@@ -488,7 +555,8 @@ print_usage (int error_p)
fnotice (file, " -r, --relative-only Only show data for relative sources\n");
fnotice (file, " -s, --source-prefix DIR Source prefix to elide\n");
fnotice (file, " -u, --unconditional-branches Show unconditional branch counts too\n");
@ -121,7 +136,7 @@ index 50061c7..eead285 100644
fnotice (file, "\nFor bug reporting instructions, please see:\n%s.\n",
bug_report_url);
exit (status);
@@ -528,6 +588,7 @@ static const struct option options[] =
@@ -528,6 +596,7 @@ static const struct option options[] =
{ "source-prefix", required_argument, NULL, 's' },
{ "unconditional-branches", no_argument, NULL, 'u' },
{ "display-progress", no_argument, NULL, 'd' },
@ -129,7 +144,7 @@ index 50061c7..eead285 100644
{ 0, 0, 0, 0 }
};
@@ -538,7 +599,7 @@ process_args (int argc, char **argv)
@@ -538,7 +607,7 @@ process_args (int argc, char **argv)
{
int opt;
@ -138,7 +153,7 @@ index 50061c7..eead285 100644
-1)
{
switch (opt)
@@ -555,6 +616,9 @@ process_args (int argc, char **argv)
@@ -555,6 +624,9 @@ process_args (int argc, char **argv)
case 'f':
flag_function_summary = 1;
break;
@ -148,7 +163,41 @@ index 50061c7..eead285 100644
case 'h':
print_usage (false);
/* print_usage will exit. */
@@ -788,14 +852,17 @@ output_gcov_file (const char *file_name, source_t *src)
@@ -784,18 +856,51 @@ process_file (const char *file_name)
static void
output_gcov_file (const char *file_name, source_t *src)
{
+ if (flag_genode_autopilot) {
+
+ /* output only if the file name appears in the .gcan file */
+
+ FILE *annotate_file = fopen(an_file_name, "r");
+
+ if (!annotate_file)
+ return;
+
+ char *source_file = NULL;
+ size_t len = 0;
+ bool annotate = false;
+
+ while (getline(&source_file, &len, annotate_file) != -1) {
+
+ /* remove '\n' */
+ source_file[strlen(source_file) - 1] = 0;
+
+ if (strstr(src->coverage.name, source_file) != NULL) {
+ annotate = true;
+ break;
+ }
+ }
+
+ fclose(annotate_file);
+
+ if (!annotate)
+ return;
+ }
+
char *gcov_file_name = make_gcov_file_name (file_name, src->coverage.name);
if (src->coverage.lines)
{
@ -168,7 +217,28 @@ index 50061c7..eead285 100644
}
else
fnotice (stderr, "Could not open output file '%s'\n", gcov_file_name);
@@ -1114,6 +1181,18 @@ find_source (const char *file_name)
@@ -968,7 +1073,8 @@ create_file_names (const char *file_name)
/* Free previous file names. */
free (bbg_file_name);
free (da_file_name);
- da_file_name = bbg_file_name = NULL;
+ free (an_file_name);
+ da_file_name = bbg_file_name = an_file_name = NULL;
bbg_file_time = 0;
bbg_stamp = 0;
@@ -1014,6 +1120,10 @@ create_file_names (const char *file_name)
strcpy (da_file_name, name);
strcpy (da_file_name + length, GCOV_DATA_SUFFIX);
+ an_file_name = XNEWVEC (char, length + strlen (GCOV_ANNOTATE_SUFFIX) + 1);
+ strcpy (an_file_name, name);
+ strcpy (an_file_name + length, GCOV_ANNOTATE_SUFFIX);
+
free (name);
return;
}
@@ -1114,6 +1224,18 @@ find_source (const char *file_name)
#endif
&& IS_DIR_SEPARATOR (src->coverage.name[source_length]))
src->coverage.name += source_length + 1;

View File

@ -12,6 +12,7 @@
* under the terms of the GNU Affero General Public License version 3.
*/
#include <base/attached_rom_dataspace.h>
#include <base/env.h>
#include <base/heap.h>
#include <base/log.h>
@ -20,6 +21,7 @@
#include <file_system_session/connection.h>
#include <file_system/util.h>
#include <util/string.h>
#include <util/xml_node.h>
extern "C" {
#include "stdio.h"
@ -35,11 +37,12 @@ FILE *stderr = &stderr_file;
struct Gcov_env
{
Genode::Env &env;
Genode::Heap heap { env.ram(), env.rm() };
Genode::Allocator_avl fs_alloc { &heap };
File_system::Connection fs { env, fs_alloc, "gcov_data" };
unsigned long seek_offset { 0 };
Genode::Env &env;
Genode::Attached_rom_dataspace config { env, "config" };
Genode::Heap heap { env.ram(), env.rm() };
Genode::Allocator_avl fs_alloc { &heap };
File_system::Connection fs { env, fs_alloc, "gcov_data" };
unsigned long seek_offset { 0 };
/* only one file is open at a time */
Genode::Constructible<File_system::File_handle> file_handle;
@ -118,6 +121,55 @@ extern "C" FILE *fopen(const char *path, const char *mode)
gcov_env->seek_offset = 0;
/*
* Write the list of source files to be annotated by gcov into a '.gcan'
* file in the same directory as the '.gcda' file.
*/
try {
Genode::Xml_node config(gcov_env->config.local_addr<char>(),
gcov_env->config.size());
Genode::Xml_node libgcov_node = config.sub_node("libgcov");
Absolute_path annotate_file_name { file_name };
annotate_file_name.remove_trailing('a');
annotate_file_name.remove_trailing('d');
annotate_file_name.append("an");
File_system::File_handle annotate_file_handle {
gcov_env->fs.file(dir, annotate_file_name.base() + 1,
File_system::WRITE_ONLY, true) };
File_system::seek_off_t seek_offset = 0;
libgcov_node.for_each_sub_node("annotate",
[&] (Genode::Xml_node annotate_node) {
Absolute_path source_path;
annotate_node.attribute("source").value(source_path.base(),
source_path.capacity());
seek_offset += File_system::write(gcov_env->fs,
annotate_file_handle,
source_path.base(),
Genode::strlen(source_path.base()),
seek_offset);
seek_offset += File_system::write(gcov_env->fs,
annotate_file_handle,
"\n",
1,
seek_offset);
});
gcov_env->fs.close(annotate_file_handle);
}
catch (Genode::Xml_node::Nonexistent_sub_node) { }
catch (Genode::Xml_attribute::Nonexistent_attribute) { }
return &gcov_env->file;
}