Is there a way to compare two different runs of a C / C ++ program?

So, I'm working on debugging this program, which I inherited from this graduate student who is about to graduate from school, or whatever happens after the student completes his dissertation. Anyway, now I am responsible for debugging it. The program basically takes a couple of text files and processes them. The problem I encountered (segfault) occurs because the program is trying to access an array that has not yet been initialized. I was wondering if there is any debugging tool that allows you to run the program and compare two different paths along which the program goes down. I believe that I could execute the program manually, but I would prefer not to do this, since it is quite large, and I still have not mastered it. I use GDB and Valgrind (and also use g ++ -wall to display warnings) since I got this far. But is there any software that will allow you to do what I described above, or even just walk you through your program.

+6
source share
3 answers

I think you are looking in the right direction with your tools like GDB and valgrind.

With GDB, you can script to execute a program in both conditions and look at the call stack when segfault occurs. You can then set a breakpoint at this location and run again with options that do not cause the program to crash, and examine the difference in both.

Using valgrind, which is actually a toolbox ( http://valgrind.org/info/tools.html ), you can succeed with callgrind and kcachegrind. Callgrind gives you call diagrams and kcachegrind ( http://kcachegrind.sourceforge.net/cgi-bin/show.cgi/KcacheGrindIndex ) allows you to visualize them. I used them both to profile profiles of large C code databases.

Another tool that can help you is Fenris ( http://lcamtuf.coredump.cx/fenris/whatis.shtml ), which can also print a graph of your code calls. Reading your requirements, I think Fenris is approaching, as it also allows you to β€œvisualize” the code path.

+4
source

These suggestions apply to the GCC. You can use the gcov tool to get a detailed report on which parts of the program were executed and how often. You must pass some special options to GCC to create the correct hardware and output for gcov to handle.

--coverage This option is used to compile and link code intended for coverage analysis. This parameter is synonymous with -fprofile-arcs -ftest-coverage (at compilation) and -lgcov (at linking). See the documentation for these parameters for details.

Then, when you run your program, some profiling and coverage data is generated. Then you can call gcov to analyze this output. The following is an example of the output taken from the link above:

  -: 0:Source:tmp.c -: 0:Graph:tmp.gcno -: 0:Data:tmp.gcda -: 0:Runs:1 -: 0:Programs:1 -: 1:#include <stdio.h> -: 2: -: 3:int main (void) 1: 4:{ 1: 5: int i, total; -: 6: 1: 7: total = 0; -: 8: 11: 9: for (i = 0; i < 10; i++) 10: 10: total += i; -: 11: 1: 12: if (total != 45) #####: 13: printf ("Failure\n"); -: 14: else 1: 15: printf ("Success\n"); 1: 16: return 0; -: 17:} 

If you want to implement your own tool for recording call history of a program, you can use -finstrument-functions and its associated parameters on GCC.

-finstrument-functions
Generate instrumental calls to enter and exit functions. Immediately after entering the function and immediately before the exit of the function, the following profiling functions are called with the address of the current function and its call site. (On some platforms, __builtin_return_address does not work outside the current function, so call site information may not be available for profiling functions otherwise.)

  void __cyg_profile_func_enter (void *this_fn, void *call_site); void __cyg_profile_func_exit (void *this_fn, void *call_site); 

The first argument is the address of the beginning of the current function, which can be searched for exactly in the symbol table.

In C ++, your implementation of these hooks must be declared extern "C" . You can implement hooks to register every time a function is called. You do not get function names, but after that you can then process pointers with objdump or addr2line .

+4
source

GDB may allow you to step through your program line by line. Some tips:

  • Just go to the main one (type b main ) and press n + Enter to execute the current line and go to the next.
  • Press s + Enter if you want to enter the function (i.e. go to the function that is called and continue from there).
  • Enter p + the name of the variable to print the value (it is really useful to determine if this variable is initialized or not, hint hint ...)
  • If you run GDB from the command line and want to use the GUI shell for it, use Emacs. Just type emacs program.c and type Alt + x , then type gdb . Type the name of the executable file and press Enter. Now you can see more of your code and still use gdb commands for debugging.
+3
source

Source: https://habr.com/ru/post/947848/


All Articles