Activity log for bug #1694644

Date Who What changed Old value New value Message
2017-05-31 09:05:23 Reetesh Ranjan bug added bug
2017-05-31 09:05:23 Reetesh Ranjan attachment added The for loop changes as described in the summary https://bugs.launchpad.net/bugs/1694644/+attachment/4886663/+files/gcc.patch
2017-05-31 09:11:41 Reetesh Ranjan description Release version: 5-2016-q3-update Using binary package Host: Mac OSX, Windows All other mandatory details are available in the description below: I was trying to do code coverage for my embedded project using 5-2016-q3-update and GNU ARM Eclipse (http://gnuarmeclipse.github.io/). I broadly followed the concept of manually breaking into 'gcov_exit' and using 'gdb dump binary' to create the gcda files, as described in https://mcuoneclipse.com/2014/12/26/code-coverage-for-embedded-target-with-eclipse-gcc-and-gcov/. However; gcov_exit hanged infinitely. For a simple project of not more than 25 source files, it would take minutes and won't return. To debug this, I made a copy of respective gcc and libgcc code and tailored it as needed and plugged it into my project so that I could see what the hang is about. It turned out that the 1st instance of these loops "for (gi_ptr = list; gi_ptr; gi_ptr = gi_ptr->next)" just won't finish. On debugging it appeared that the list was circular and not a null-terminated one. I cannot figure it out why that is as I studied gcc code, as __gcov_root.list construction through __gcov_init does not seem to create any circular lists. But it appeared to be so, because when I changed the loops to expect a circular list rather than a null-terminated singly linked list, things worked. Also, I manually debugged the functions called by gcov_exit to see that there are exactly as many gcov_info nodes in the __gcov_root.list as the number of source files covered, and the change to expect a circular list made sense. I had to end up changing 3 instances of such loops and then I was able to generated the gcda files. The ported/tailored version of the minimum gcc/libgcc code has been made available at: https://github.com/reeteshranjan/libgcov-embedded I saw that the toolchain is based on svn://gcc.gnu.org/svn/gcc/branches/ARM/; and I picked the code from gcc trunk. However; it seems at least from embedded-6-branch onwards that the gcov source is the same as I could see in gcc trunk that time. I have also attached a patch I made using the embedded-6-branch which clearly shows the for loop changes made. I also did a sample GNU ARM Eclipse project to use the above, which is available at: https://github.com/reeteshranjan/libgcov-embedded-example Steps to reproduce and analyze: - Setup any embedded project using GNU ARM Eclipse. Follow the steps in https://mcuoneclipse.com/2014/12/26/code-coverage-for-embedded-target-with-eclipse-gcc-and-gcov/ to generate coverage data by breaking into gcov_exit or __gcov_flush (whichever is available). The hang in gcov_exit should be reproducible. - Now create another project from scratch without using the stub code as described in https://mcuoneclipse.com/2014/12/26/code-coverage-for-embedded-target-with-eclipse-gcc-and-gcov/ - Plugin https://github.com/reeteshranjan/libgcov-embedded using the instructions in README.md provided in this repository into the new project. - In the port/libgcc/libgcov-driver.c file in the above, search for the loops "for (gi_ptr = list; gi_ptr && !(gi_ptr == list && break_loop_counter); gi_ptr = gi_ptr->next, break_loop_counter++)". These are the changes to expect a circular list and not a null-terminated singly linked list. Change these lines to how they are in original gcc code which is "for (gi_ptr = list; gi_ptr; gi_ptr = gi_ptr->next)" - Follow the README instructions on how to break in gcov-io.c to use gdb instructions to manually create gcda files. You won't hit this breakpoint because of the hang in first of these for loops in 'compute_summary' function (now reproducible as we changed the code to use the original libgcc version) - Now revert the for loop changes back - Now the breakpoints should hit once for each source file Release version: 5-2016-q3-update Using binary package Host: Mac OSX, Windows All other mandatory details are available in the description below: I was trying to do code coverage for my embedded project using 5-2016-q3-update and GNU ARM Eclipse (http://gnuarmeclipse.github.io/). I broadly followed the concept of manually breaking into 'gcov_exit' and using 'gdb dump binary' to create the gcda files, as described in https://mcuoneclipse.com/2014/12/26/code-coverage-for-embedded-target-with-eclipse-gcc-and-gcov/. However; gcov_exit hanged infinitely. For a simple project of not more than 25 source files, it would take minutes and won't return. To debug this, I made a copy of respective gcc and libgcc code and tailored it as needed and plugged it into my project so that I could see what the hang is about. It turned out that the 1st instance of these loops "for (gi_ptr = list; gi_ptr; gi_ptr = gi_ptr->next)" just won't finish. On debugging it appeared that the list was circular and not a null-terminated one. I cannot figure it out why that is as I studied gcc code, and __gcov_root.list construction through __gcov_init does not seem to create any circular lists. But it appeared to be so, because when I changed the loops to expect a circular list rather than a null-terminated singly linked list, things worked. Also, I manually debugged the functions called by gcov_exit to see that there are exactly as many gcov_info nodes in the __gcov_root.list as the number of source files covered, and the change to expect a circular list made sense. I had to end up changing 3 instances of such loops and then I was able to generated the gcda files. The ported/tailored version of the minimum gcc/libgcc code has been made available at: https://github.com/reeteshranjan/libgcov-embedded I saw that the toolchain is based on svn://gcc.gnu.org/svn/gcc/branches/ARM/; and I picked the code from gcc trunk. However; it seems at least from embedded-6-branch onwards that the gcov source is the same as I could see in gcc trunk that time. I have also attached a patch I made using the embedded-6-branch which clearly shows the for loop changes made. I also did a sample GNU ARM Eclipse project to use the above, which is available at: https://github.com/reeteshranjan/libgcov-embedded-example Steps to reproduce and analyze: - Setup any embedded project using GNU ARM Eclipse. Follow the steps in https://mcuoneclipse.com/2014/12/26/code-coverage-for-embedded-target-with-eclipse-gcc-and-gcov/ to generate coverage data by breaking into gcov_exit or __gcov_flush (whichever is available). The hang in gcov_exit should be reproducible. - Now create another project from scratch without using the stub code as described in https://mcuoneclipse.com/2014/12/26/code-coverage-for-embedded-target-with-eclipse-gcc-and-gcov/ - Plugin https://github.com/reeteshranjan/libgcov-embedded using the instructions in README.md provided in this repository into the new project. - In the port/libgcc/libgcov-driver.c file in the above, search for the loops "for (gi_ptr = list; gi_ptr && !(gi_ptr == list && break_loop_counter); gi_ptr = gi_ptr->next, break_loop_counter++)". These are the changes to expect a circular list and not a null-terminated singly linked list. Change these lines to how they are in original gcc code which is "for (gi_ptr = list; gi_ptr; gi_ptr = gi_ptr->next)" - Follow the README instructions on how to break in gcov-io.c to use gdb instructions to manually create gcda files. You won't hit this breakpoint because of the hang in first of these for loops in 'compute_summary' function (now reproducible as we changed the code to use the original libgcc version) - Now revert the for loop changes back - Now the breakpoints should hit once for each source file
2017-05-31 16:35:38 Eldar Khayrullin bug added subscriber Eldar Khayrullin