Uploaded image for project: 'MariaDB Server'
  1. MariaDB Server
  2. MDEV-26102

dgcov: add support for *.gcda.gcov.json.gz files of gcov 9.1+

Details

    Description

      1. dgcov should be supported with gcc version gcc 4.9.4+ since there is -i option introduced.
      2. json format found from here that is introduced with 9.1.0. Looking from all release changes for 9.1.0

      The following improvements to the gcov command-line utility have been made.
       
      The gcov tool received a new option --use-hotness-colors (-q) that can provide perf-like coloring of hot functions.
      The gcov tool has changed its intermediate format to a new JSON format.
      

      and seems that in that version intermediate format was deprecated.
      Additional links:
      [1] Zulip analysis
      [2] Support GCOV intermediate format

      Attachments

        Issue Links

          Activity

            perl bundles JSON::PP starting from the version v5.13.9. While not the fastest it can hopefully be enough for dgcov purposes and will work without additional dependencies.

            serg Sergei Golubchik added a comment - perl bundles JSON::PP starting from the version v5.13.9. While not the fastest it can hopefully be enough for dgcov purposes and will work without additional dependencies.
            anel Anel Husakovic added a comment - - edited

            serg can I try to implement this?
            JSON::PP is the only thing I should take care of ?

            anel Anel Husakovic added a comment - - edited serg can I try to implement this? JSON::PP is the only thing I should take care of ?

            of course, you're the assignee

            I don't understand the second question. What do you mean to "take care of JSON::PP" ?

            serg Sergei Golubchik added a comment - of course, you're the assignee I don't understand the second question. What do you mean to "take care of JSON::PP" ?

            Well I mean, do I need any preprocessing after it? I managed to create the script where locally everything works.
            However I have a problem with gcno files which should be generated when compiling - they are not created:

            $ gcc --version && gcov --version && g++ --version
            gcc (Ubuntu 9.4.0-1ubuntu1~18.04) 9.4.0
            Copyright (C) 2019 Free Software Foundation, Inc.
            This is free software; see the source for copying conditions.  There is NO
            warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
             
            gcov (Ubuntu 9.4.0-1ubuntu1~18.04) 9.4.0
            Copyright (C) 2019 Free Software Foundation, Inc.
            This is free software; see the source for copying conditions.
            There is NO warranty; not even for MERCHANTABILITY or 
            FITNESS FOR A PARTICULAR PURPOSE.
             
            g++ (Ubuntu 9.4.0-1ubuntu1~18.04) 9.4.0
            Copyright (C) 2019 Free Software Foundation, Inc.
            This is free software; see the source for copying conditions.  There is NO
            warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
             
            $ cmake . -DCMAKE_BUILD_TYPE=Debug -DCONC_WITH_{UNITTEST,SSL}=OFF -DWITH_EMBEDDED_SERVER=OFF -DWITH_UNIT_TESTS=OFF -DPLUGIN_{ARCHIVE,TOKUDB,MROONGA,OQGRAPH,ROCKSDB,CONNECT,PERFSCHEMA,SPIDER,SPHINX}=NO -DWITH_SAFEMALLOC=OFF -DWITH_SSL=bundled -DENABLE_GCOV=ON
             
            # Result with empty files
            

            Locally tests:

            $ ls
            main1.h  main.c  Makefile  test.pl
            $ gcc --coverage main.c 
            $ ls
            a.out  main1.h  main.c  main.gcno  Makefile  test.pl
             
            $ gcc --coverage -c main.c 
            $ ls
            main1.h  main.c  main.gcno  main.o  Makefile  test.pl
            

            Also I found some [regression](https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97193) in gcov and I'm not sure is it related.

            anel Anel Husakovic added a comment - Well I mean, do I need any preprocessing after it? I managed to create the script where locally everything works. However I have a problem with gcno files which should be generated when compiling - they are not created: $ gcc --version && gcov --version && g++ --version gcc (Ubuntu 9.4.0-1ubuntu1~18.04) 9.4.0 Copyright (C) 2019 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.   gcov (Ubuntu 9.4.0-1ubuntu1~18.04) 9.4.0 Copyright (C) 2019 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.   g++ (Ubuntu 9.4.0-1ubuntu1~18.04) 9.4.0 Copyright (C) 2019 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.   $ cmake . -DCMAKE_BUILD_TYPE=Debug -DCONC_WITH_{UNITTEST,SSL}=OFF -DWITH_EMBEDDED_SERVER=OFF -DWITH_UNIT_TESTS=OFF -DPLUGIN_{ARCHIVE,TOKUDB,MROONGA,OQGRAPH,ROCKSDB,CONNECT,PERFSCHEMA,SPIDER,SPHINX}=NO -DWITH_SAFEMALLOC=OFF -DWITH_SSL=bundled -DENABLE_GCOV=ON   # Result with empty files Locally tests: $ ls main1.h main.c Makefile test.pl $ gcc --coverage main.c $ ls a.out main1.h main.c main.gcno Makefile test.pl   $ gcc --coverage -c main.c $ ls main1.h main.c main.gcno main.o Makefile test.pl Also I found some [regression] ( https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97193 ) in gcov and I'm not sure is it related.

            Hi Serg,
            can you please review 6296c32b10ed2 have problem with write_coverage of created hash cov from function gcov_one_file?

            anel Anel Husakovic added a comment - Hi Serg, can you please review 6296c32b10ed2 have problem with write_coverage of created hash cov from function gcov_one_file ?
            serg Sergei Golubchik added a comment - - edited

            Haven't we agreed to use JSON::PP ?

            $ perldoc JSON::PP
            

            serg Sergei Golubchik added a comment - - edited Haven't we agreed to use JSON::PP ? $ perldoc JSON::PP

            Yes and I have used json_pp -f <from-type> -t <to-type> here to pretty (default option -t json -json_opt pretty) the json file.
            Other type -t dumper can be used, but not sure, how to use the output of Data::Dumper ($VAR1) on one or multiple files.
            Did you mean to use that conversion?

            json_pp dumper

            Show all

            $VAR1 = {
                      'files' => [
                                   {
                                     'lines' => [
                                                  {
                                                    'line_number' => 3,
                                                    'branches' => [],
                                                    'unexecuted_block' => bless( do{\(my $o = 0)}, 'JSON::PP::Boolean' ),
                                                    'function_name' => 'main',
                                                    'count' => 1
                                                  },
                                                  {
                                                    'count' => 1,
                                                    'line_number' => 5,
                                                    'unexecuted_block' => $VAR1->{'files'}[0]{'lines'}[0]{'unexecuted_block'},
                                                    'branches' => [],
                                                    'function_name' => 'main'
                                                  },
                                                  {
                                                    'count' => 1,
                                                    'unexecuted_block' => $VAR1->{'files'}[0]{'lines'}[0]{'unexecuted_block'},
                                                    'branches' => [],
                                                    'line_number' => 6,
                                                    'function_name' => 'main'
                                                  },
                                                  {
                                                    'branches' => [],
                                                    'unexecuted_block' => $VAR1->{'files'}[0]{'lines'}[0]{'unexecuted_block'},
                                                    'line_number' => 7,
                                                    'function_name' => 'main',
                                                    'count' => 1
                                                  }
                                                ],
                                     'functions' => [
                                                      {
                                                        'start_column' => 5,
                                                        'demangled_name' => 'main',
                                                        'end_column' => 1,
                                                        'blocks' => 5,
                                                        'start_line' => 3,
                                                        'end_line' => 8,
                                                        'blocks_executed' => 5,
                                                        'name' => 'main',
                                                        'execution_count' => 1
                                                      }
                                                    ],
                                     'file' => 'main.c'
                                   },
                                   {
                                     'functions' => [
                                                      {
                                                        'demangled_name' => 'sum',
                                                        'start_column' => 5,
                                                        'end_column' => 1,
                                                        'blocks' => 2,
                                                        'end_line' => 6,
                                                        'start_line' => 3,
                                                        'execution_count' => 1,
                                                        'name' => 'sum',
                                                        'blocks_executed' => 2
                                                      }
                                                    ],
                                     'file' => 'main1.h',
                                     'lines' => [
                                                  {
                                                    'function_name' => 'sum',
                                                    'line_number' => 3,
                                                    'unexecuted_block' => $VAR1->{'files'}[0]{'lines'}[0]{'unexecuted_block'},
                                                    'branches' => [],
                                                    'count' => 1
                                                  },
                                                  {
                                                    'count' => 1,
                                                    'line_number' => 5,
                                                    'unexecuted_block' => $VAR1->{'files'}[0]{'lines'}[0]{'unexecuted_block'},
                                                    'branches' => [],
                                                    'function_name' => 'sum'
                                                  }
                                                ]
                                   }
                                 ],
                      'data_file' => 'main.gcda',
                      'format_version' => '1',
                      'gcc_version' => '9.4.0',
                      'current_working_directory' => '/home/anel/mariadb/gcov-analysis/anel-gcc9'
                    };
            
            

            anel Anel Husakovic added a comment - Yes and I have used json_pp -f <from-type> -t <to-type> here to pretty (default option -t json -json_opt pretty ) the json file. Other type -t dumper can be used, but not sure, how to use the output of Data::Dumper ( $VAR1 ) on one or multiple files. Did you mean to use that conversion? json_pp dumper Show all $VAR1 = { 'files' => [ { 'lines' => [ { 'line_number' => 3, 'branches' => [], 'unexecuted_block' => bless ( do {\( my $o = 0)}, 'JSON::PP::Boolean' ), 'function_name' => 'main' , 'count' => 1 }, { 'count' => 1, 'line_number' => 5, 'unexecuted_block' => $VAR1 ->{ 'files' }[0]{ 'lines' }[0]{ 'unexecuted_block' }, 'branches' => [], 'function_name' => 'main' }, { 'count' => 1, 'unexecuted_block' => $VAR1 ->{ 'files' }[0]{ 'lines' }[0]{ 'unexecuted_block' }, 'branches' => [], 'line_number' => 6, 'function_name' => 'main' }, { 'branches' => [], 'unexecuted_block' => $VAR1 ->{ 'files' }[0]{ 'lines' }[0]{ 'unexecuted_block' }, 'line_number' => 7, 'function_name' => 'main' , 'count' => 1 } ], 'functions' => [ { 'start_column' => 5, 'demangled_name' => 'main' , 'end_column' => 1, 'blocks' => 5, 'start_line' => 3, 'end_line' => 8, 'blocks_executed' => 5, 'name' => 'main' , 'execution_count' => 1 } ], 'file' => 'main.c' }, { 'functions' => [ { 'demangled_name' => 'sum' , 'start_column' => 5, 'end_column' => 1, 'blocks' => 2, 'end_line' => 6, 'start_line' => 3, 'execution_count' => 1, 'name' => 'sum' , 'blocks_executed' => 2 } ], 'file' => 'main1.h' , 'lines' => [ { 'function_name' => 'sum' , 'line_number' => 3, 'unexecuted_block' => $VAR1 ->{ 'files' }[0]{ 'lines' }[0]{ 'unexecuted_block' }, 'branches' => [], 'count' => 1 }, { 'count' => 1, 'line_number' => 5, 'unexecuted_block' => $VAR1 ->{ 'files' }[0]{ 'lines' }[0]{ 'unexecuted_block' }, 'branches' => [], 'function_name' => 'sum' } ] } ], 'data_file' => 'main.gcda' , 'format_version' => '1' , 'gcc_version' => '9.4.0' , 'current_working_directory' => '/home/anel/mariadb/gcov-analysis/anel-gcc9' };

            Sorry, I haven't read perldoc. Reading/testing. Thanks.

            anel Anel Husakovic added a comment - Sorry, I haven't read perldoc . Reading/testing. Thanks.

            Why are you even looking at json_pp? Just use JSON::PP module. Like this:

            #!/usr/bin/perl -l
             
            use IO::Uncompress::Gunzip qw(gunzip $GunzipError);
            use JSON::PP;
             
            my $js;
            gunzip $ARGV[0] => \$js or die "gunzip($ARGV[0]): $GunzipError";
            my $obj=decode_json $js;
             
            for my $file (@{$obj->{files}}) {
              print "file: $file->{file}";
              for my $fn (@{$file->{functions}}) {
                print "..function: ", $fn->{demangled_name} || $fn-{name};
              }
            }
            

            This is a complete demo program, if you run it with a gcda.gcov.json.gz file as an argument, it'll print you all functions in all files in this json file. For example,

            $ ./a.pl gen_lex_token.cc.gcda.gcov.json.gz 
            file: sql/gen_lex_token.cc
            ..function: set_token(int, char const*)
            ..function: set_start_expr_token(int)
            ..function: compute_tokens()
            ..function: print_tokens()
            ..function: main
            

            serg Sergei Golubchik added a comment - Why are you even looking at json_pp ? Just use JSON::PP module. Like this: #!/usr/bin/perl -l   use IO::Uncompress::Gunzip qw(gunzip $GunzipError ); use JSON::PP;   my $js ; gunzip $ARGV [0] => \ $js or die "gunzip($ARGV[0]): $GunzipError" ; my $obj =decode_json $js ;   for my $file (@{ $obj ->{files}}) { print "file: $file->{file}" ; for my $fn (@{ $file ->{functions}}) { print "..function: " , $fn ->{demangled_name} || $fn -{name}; } } This is a complete demo program, if you run it with a gcda.gcov.json.gz file as an argument, it'll print you all functions in all files in this json file. For example, $ ./a.pl gen_lex_token.cc.gcda.gcov.json.gz file: sql/gen_lex_token.cc ..function: set_token(int, char const*) ..function: set_start_expr_token(int) ..function: compute_tokens() ..function: print_tokens() ..function: main

            Thanks for help serg it helped me a lot.
            New patch: 203aa38f9b6606d
            Example of the result:

            $./mtr --gcov is_check_constraints --record && cat var/last_changes.dgcov
             
            *********************
            dgcov sql/sql_show.cc
            *********************
            @@ +6601,7 @@ static int get_check_constraints_record(THD *thd, TABLE_LIST *tables,
                     : 6601:      }
                     : 6602:#endif
                     : 6603:      Virtual_column_info *check= tables->table->check_constraints[i];
                   44: 6605:      table->field[0]->store(STRING_WITH_LEN("definition"), system_charset_info);
                     : 6606:      table->field[3]->store(check->name.str, check->name.length,
                     : 6607:                             system_charset_info);
            

            anel Anel Husakovic added a comment - Thanks for help serg it helped me a lot. New patch: 203aa38f9b6606d Example of the result: $./mtr --gcov is_check_constraints --record && cat var/last_changes.dgcov   ********************* dgcov sql/sql_show.cc ********************* @@ +6601,7 @@ static int get_check_constraints_record(THD *thd, TABLE_LIST *tables, : 6601: } : 6602:#endif : 6603: Virtual_column_info *check= tables->table->check_constraints[i]; 44: 6605: table->field[0]->store(STRING_WITH_LEN("definition"), system_charset_info); : 6606: table->field[3]->store(check->name.str, check->name.length, : 6607: system_charset_info);

            Hi Serg,
            new patch 85aa3f8cf66per your review .

            anel Anel Husakovic added a comment - Hi Serg, new patch 85aa3f8cf66 per your review .
            anel Anel Husakovic added a comment - - edited

            Test of patch - with appended commit message (about usage of gcc version <9 and >=9 - noted error in regex - so new patch will be)

            • gcc version < 9 (gcov uses -i format as a file)

              # -DENABLE_GCOV=ON -DCMAKE_\{C_COMPILER=gcc,CXX_COMPILER=g++\}-7
              $ git cherry-pick 25d66172f4a2ba1c8fd25a68032e3d9b782e6adb  # note bb-10.2-anel-MDEV-18284-json_compact commit
              $ cmake --build . -- -j8
              $ ./mtr --gcov func_json
              $ cat var/last_changes.dgcov 
              ****************
              dgcov sql/item.h
              ****************
              @@ +4564,7 @@ class Item_ref :public Item_ident
                       : 4564:  {
                       : 4565:    return ref ? (*ref)->real_item() : this;
                       : 4566:  }
                      1: 4567:  bool is_json_type() { return (*ref)->is_json_type(); }
                       : 4568:  bool walk(Item_processor processor, bool walk_subquery, void *arg)
                       : 4569:  { 
                       : 4570:    if (ref && *ref)
              

            • gcov version 9 (gcc version 9 too)

               
              $ sudo update-alternatives --display gcc
              $ sudo update-alternatives --config gcc #(to 9)
              $ gcc --version
              gcc (Ubuntu 9.4.0-1ubuntu1~18.04) 9.4.0
              $ g++ --version
              g++ (Ubuntu 9.4.0-1ubuntu1~18.04) 9.4.0
              # Remove old gcov (symlink to gcov-7)
              $ sudo rm /usr/bin/gcov
              # Make it symlink to gcov-9
              $ sudo ln -s /usr/bin/gcov-9 /usr/bin/gcov
               
              # Remove old files
              $ git clean -dffx
              $ cmake . -DCMAKE_BUILD_TYPE=Debug -DPLUGIN_{ARCHIVE,TOKUDB,MROONGA,OQGRAPH,ROCKSDB,CONNECT,PERFSCHEMA,SPIDER,SPHINX}=NO -DENABLE_GCOV=ON -DCMAKE_\{C_COMPILER=gcc,CXX_COMPILER=g++\}-9
              $ cmake --build . -- -j8
               
              $ git cherry-pick 25d66172f4a2ba1c8fd25a68032e3d9b782e6adb  # note bb-10.2-anel-MDEV-18284-json_compact commit
              $ ./mtr --gcov func_json
              # Example of generated file: ./mysys/CMakeFiles/mysys.dir/list.c.gcda.gcov.json.gz
              $ cat var/last_changes.dgcov 
              ****************
              dgcov sql/item.h
              ****************
              @@ +4564,7 @@ class Item_ref :public Item_ident
                       : 4564:  {
                       : 4565:    return ref ? (*ref)->real_item() : this;
                       : 4566:  }
                      1: 4567:  bool is_json_type() { return (*ref)->is_json_type(); }
                       : 4568:  bool walk(Item_processor processor, bool walk_subquery, void *arg)
                       : 4569:  { 
                       : 4570:    if (ref && *ref)
              

            Same result as above.

            New patch (removed unused line) : 5599795abe1faee79 serg

            anel Anel Husakovic added a comment - - edited Test of patch - with appended commit message (about usage of gcc version <9 and >=9 - noted error in regex - so new patch will be) gcc version < 9 ( gcov uses -i format as a file) # -DENABLE_GCOV=ON -DCMAKE_\{C_COMPILER=gcc,CXX_COMPILER=g++\}-7 $ git cherry-pick 25d66172f4a2ba1c8fd25a68032e3d9b782e6adb # note bb-10.2-anel-MDEV-18284-json_compact commit $ cmake --build . -- -j8 $ . /mtr --gcov func_json $ cat var /last_changes .dgcov **************** dgcov sql /item .h **************** @@ +4564,7 @@ class Item_ref :public Item_ident : 4564: { : 4565: return ref ? (*ref)->real_item() : this; : 4566: } 1: 4567: bool is_json_type() { return (*ref)->is_json_type(); } : 4568: bool walk(Item_processor processor, bool walk_subquery, void *arg) : 4569: { : 4570: if (ref && *ref) gcov version 9 ( gcc version 9 too)   $ sudo update-alternatives --display gcc $ sudo update-alternatives --config gcc #(to 9) $ gcc --version gcc (Ubuntu 9.4.0-1ubuntu1~18.04) 9.4.0 $ g++ --version g++ (Ubuntu 9.4.0-1ubuntu1~18.04) 9.4.0 # Remove old gcov (symlink to gcov-7) $ sudo rm /usr/bin/gcov # Make it symlink to gcov-9 $ sudo ln -s /usr/bin/gcov-9 /usr/bin/gcov   # Remove old files $ git clean -dffx $ cmake . -DCMAKE_BUILD_TYPE=Debug -DPLUGIN_{ARCHIVE,TOKUDB,MROONGA,OQGRAPH,ROCKSDB,CONNECT,PERFSCHEMA,SPIDER,SPHINX}=NO -DENABLE_GCOV=ON -DCMAKE_\{C_COMPILER=gcc,CXX_COMPILER=g++\}-9 $ cmake --build . -- -j8   $ git cherry-pick 25d66172f4a2ba1c8fd25a68032e3d9b782e6adb # note bb-10.2-anel-MDEV-18284-json_compact commit $ . /mtr --gcov func_json # Example of generated file: ./mysys/CMakeFiles/mysys.dir/list.c.gcda.gcov.json.gz $ cat var /last_changes .dgcov **************** dgcov sql /item .h **************** @@ +4564,7 @@ class Item_ref :public Item_ident : 4564: { : 4565: return ref ? (*ref)->real_item() : this; : 4566: } 1: 4567: bool is_json_type() { return (*ref)->is_json_type(); } : 4568: bool walk(Item_processor processor, bool walk_subquery, void *arg) : 4569: { : 4570: if (ref && *ref) Same result as above. New patch (removed unused line) : 5599795abe1faee79 serg

            People

              anel Anel Husakovic
              anel Anel Husakovic
              Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved:

                Git Integration

                  Error rendering 'com.xiplink.jira.git.jira_git_plugin:git-issue-webpanel'. Please contact your Jira administrators.