10

Requirement:

Given a C program I have to identify whether the functions accessing global variables are reading them or writing them.

Example code:

#include <stdio.h>

/* global variable declaration */
int g = 20;

int main()
{

    /* writing the global variable */
    g = 10;

    /* reading the global variable */
    printf ("value of g = %d\n",  g);

    return 0;
}

Executing the above code I want to generate a log file in the below format:

1- Global variable a written in function main() "TIME_STAMP"
2- Global variable a read in function main() "TIME_STAMP"

Research:

I am cetainly able to acheive this by doing a static analysis of source code as per below logic:

  • Go through the c code and identify the statements where the global variable is read.
  • Then analysis the c code statement to identify if it is a read or write statement.(Checking if ++ or -- operator is used with global variable or any assignemnt has been made to the global variable)
  • Add a log statement above the identified statement which will execute along with this statement execution.

This is not a proper implementation.

Some studies:

I have gone through how debuggers are able to capture information.

Some links in the internet: How to catch a memory write and call function with address of write

Community
  • 1
  • 1
Sanjit Kumar Mishra
  • 1,153
  • 13
  • 32
  • 2
    The *normal* C way would be to use getters and setters and instrument them. C is still rather low level, and it does not even support references, so even through macros I cannot imagine how you could simply instrument assignations... – Serge Ballesta Dec 15 '16 at 08:34
  • If dynamic analysis/instrumentation is an option, tools like [Pin](https://software.intel.com/sites/landingpage/pintool/docs/58423/Pin/html/) can do exactly what you want. See "Memory Reference Trace". – Michael Foukarakis Dec 15 '16 at 08:48
  • @SergeBallesta: Yes you are right this feature is there in Object Oriented or high level language, it helps a lot in profiling performance enhancement etc... so looking for a implementation in c – Sanjit Kumar Mishra Dec 15 '16 at 08:51
  • 1
    If you need That, C is not the appropriate language... – Serge Ballesta Dec 15 '16 at 09:04
  • Alternatively, but it will no longer be portable, use the low level system calls used by debuggers to step at run time through instructions or even better use a true debugger... – Serge Ballesta Dec 15 '16 at 09:07
  • Yes it looks difficult to implement in C, but lets see if anyone have implemented – Sanjit Kumar Mishra Dec 15 '16 at 09:12

2 Answers2

7

Not completely answering your question, but to just log access you could do:

#include <stdio.h>

int g = 0;

#define g (*(fprintf(stderr, "accessing g from %s. g = %d\n", __FUNCTION__, g), &g))

void foo(void)
{
  g = 2;
  printf("g=%d\n", g);
}

void bar(void)
{
  g = 3;
  printf("g=%d\n", g);
}

int main(void)
{
  printf("g=%d\n", g);
  g = 1;
  foo();
  bar();
  printf("g=%d\n", g);
}

Which would print:

accessing g from main. g = 0
g=0
accessing g from main. g = 0
accessing g from foo. g = 1
accessing g from foo. g = 2
g=2
accessing g from bar. g = 2
accessing g from bar. g = 3
g=3
accessing g from main. g = 3
g=3
alk
  • 69,737
  • 10
  • 105
  • 255
  • Thanks for your answer @alk, but how can i identify if it is a read or write call. – Sanjit Kumar Mishra Dec 15 '16 at 08:53
  • 1
    @SanjitKumarMishra: I see no (standard?) way to do this. You could detect changes by saving the current value to a temporary variable each time the macro gets "called" and compare to it the next time. – alk Dec 15 '16 at 09:01
  • Yes that is an option i am checking but the problem is, there can be occurrence in which memory will be written but the value will remain the same(Ex: Multiplying with 1(This one can be result of some expression)). – Sanjit Kumar Mishra Dec 15 '16 at 09:09
-1

Below is the way i solved this problem:

  • I created a utility(In java) which works as below(C program source file is the input to my utility):
    • Parse the file line by line identifying the variables and functions.
    • It stores global variables in a separate container and look for lines using them.
    • For every line which access the global variable i am analyzing them identifying whether it is a read operation or write operation(ex: ==, +=, -+ etc are write operation).
    • For every such operation i am instrumenting the code as suggested by @alk(https://stackoverflow.com/a/41158928/6160431) and that in turn will generate the log file when i execute the modified source file.

I am certainly able to achieve what i want but still looking for better implementation if anyone have.

For further discussion if anybody want we can have have a chat.

I refer the source code and algos from the below tools:

http://www.dyninst.org/

https://software.intel.com/en-us/articles/pin-a-dynamic-binary-instrumentation-tool

Community
  • 1
  • 1
Sanjit Kumar Mishra
  • 1,153
  • 13
  • 32
  • _"I am cetainly able to acheive this by doing a static analysis of so [...] This is not a proper implementation."_ Plain ol' `grep` would work as well. – edmz Dec 16 '16 at 12:48
  • @black: Yes this is not a proper way, but it solves what i want i would love if you can direct me to a proper implementation. How static analysis can give me a run time result? – Sanjit Kumar Mishra Dec 17 '16 at 05:53