Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Automatically printing the structures and variables in C

I am working with 4-5 .c files (around 2000 to 5000 lines each) which include several headers.Currently I do not have any debug prints which would help me debug the program during its course of execution.

My question is :- Is there a way (or some existing tool) to parse the .c files and add new set of print statements for all the variables in the current scope in the .c file ? Just the same way as VC++ allows us to see Locals and globals etc. I need them printed at each step. Also, pointers should be dereferenced.

For ex. lets say at one point in the .c file, there are 10 global variables and 3 locals. I need to generate the smart printfs to print these 13 variables at that point. Later in the program if there are 20 variables, i should be able to print the 20 variables etc. The included header files contain all the relevant declarations for each of these
variables (which can be structures/pointers/arrays or some combinations etc etc.) I was trying to achieve this via perl script.

What I did is, I generated the preprocessed file (.i file) and i tried parsing it via perl and then generate individual print functions specific to each variable, but after half a days' effort i realized that its just too time consuming. Is there a tool that already does that ? If not this, anything close to it should be good enough (On which i can apply some perl processing etc) My goal is that after the program execution,at each step during the program execution, I should be able to see the variables(valid at that scope) without having to invoke the debugger.

I am allowed to process the .c files and re-write them again etc. etc. Hope my question is clear and thanks for your replies.

like image 544
Utkarsh Kumar Avatar asked Oct 21 '22 21:10

Utkarsh Kumar


1 Answers

Assuming that your C program can be interpreted by Frama-C's value analysis, which is far from a given, you could use that to obtain a log of the values of all living variables at each point of the program or at points of interest.

Consider the following program:

int x = 1;

main(){
  int l;

  x=2;
  Frama_C_dump_each();
  l=3;
  Frama_C_dump_each();
  {
    int blocklocal = l + 1;
    Frama_C_dump_each();
    x = blocklocal + 1;
    Frama_C_dump_each();
  }
  Frama_C_dump_each();
  return 0;
}

Running frama-c -val -slevel 1000000000 -no-results t.c on this program produces the log:

[value] Values of globals at initialization
        x ∈ {1}
[value] DUMPING STATE of file t.c line 7
        x ∈ {2}
        =END OF DUMP==
[value] DUMPING STATE of file t.c line 9
        x ∈ {2}
        l ∈ {3}
        =END OF DUMP==
[value] DUMPING STATE of file t.c line 12
        x ∈ {2}
        l ∈ {3}
        blocklocal ∈ {4}
        =END OF DUMP==
[value] DUMPING STATE of file t.c line 14
        x ∈ {5}
        l ∈ {3}
        blocklocal ∈ {4}
        =END OF DUMP==
[value] DUMPING STATE of file t.c line 16
        x ∈ {5}
        l ∈ {3}
        =END OF DUMP==

The Frama_C_dump_each() statements were inserted by me manually, but you could also nudge the interpreter so that it dumps a state automatically at each statement.

For this approach to work, you need the entire source code of your program, including standard library functions (strlen(), memcpy(), …) and you must hard-code the values of the input at the beginning of the main() function. Otherwise, it will behave as the static analyzer that it really is instead of behaving as a C interpreter.

You could also use the GUI to observe values of variables in your program, but if it is not linear, statements that are visited several times either because of function calls or because of loops will show all the values that can be taken during execution.

like image 82
Pascal Cuoq Avatar answered Nov 11 '22 15:11

Pascal Cuoq