Search code examples
cprofilingvalgrindmemory-profilingmemcheck

Access User variables from Valgrind source code


I am trying to do some experiment with valgrind source code. I am using the below code as my test code:

#include <stdio.h>
int g_int = 12;
int main()
{
  int y = 10;
  int x;
  printf("%d\n",x);
  return x;
}

I build a executable named "test.out". Then I executed below command:

$./valgrind --tool=memcheck ./test.out

In my test code I have a uninitialized bugs and valgrind reports that bug from "mc_errors.c" by giving me some message like:

../build/bin$ ./valgrind --tool=memcheck --track-origins=yes --read-var-info=yes ./test >> outpur.txt
==24255== Memcheck, a memory error detector
==24255== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==24255== Using Valgrind-3.14.0.GIT and LibVEX; rerun with -h for copyright info
==24255== Command: ./test
==24255== 
==24255== Conditional jump or move depends on uninitialised value(s)
==24255== I want to print my local variable here!
==24255==    at 0x4E87B83: vfprintf (vfprintf.c:1631)
==24255==    by 0x4E8F898: printf (printf.c:33)
==24255==    by 0x400548: main (test.c:10)
==24255==  Uninitialised value was created by a stack allocation
==24255==    at 0x400526: main (test.c:6)
==24255== 
==24255== Use of uninitialised value of size 8
==24255== I want to print my local variable here!
==24255==    at 0x4E8476B: _itoa_word (_itoa.c:179)
==24255==    by 0x4E8812C: vfprintf (vfprintf.c:1631)
==24255==    by 0x4E8F898: printf (printf.c:33)
==24255==    by 0x400548: main (test.c:10)
==24255==  Uninitialised value was created by a stack allocation
==24255==    at 0x400526: main (test.c:6)
==24255== 
==24255== Conditional jump or move depends on uninitialised value(s)
==24255== I want to print my local variable here!
==24255==    at 0x4E84775: _itoa_word (_itoa.c:179)
==24255==    by 0x4E8812C: vfprintf (vfprintf.c:1631)
==24255==    by 0x4E8F898: printf (printf.c:33)
==24255==    by 0x400548: main (test.c:10)
==24255==  Uninitialised value was created by a stack allocation
==24255==    at 0x400526: main (test.c:6)
==24255== 
==24255== Conditional jump or move depends on uninitialised value(s)
==24255== I want to print my local variable here!
==24255==    at 0x4E881AF: vfprintf (vfprintf.c:1631)
==24255==    by 0x4E8F898: printf (printf.c:33)
==24255==    by 0x400548: main (test.c:10)
==24255==  Uninitialised value was created by a stack allocation
==24255==    at 0x400526: main (test.c:6)
==24255== 
==24255== Conditional jump or move depends on uninitialised value(s)
==24255== I want to print my local variable here!
==24255==    at 0x4E87C59: vfprintf (vfprintf.c:1631)
==24255==    by 0x4E8F898: printf (printf.c:33)
==24255==    by 0x400548: main (test.c:10)
==24255==  Uninitialised value was created by a stack allocation
==24255==    at 0x400526: main (test.c:6)
==24255== 
==24255== Conditional jump or move depends on uninitialised value(s)
==24255== I want to print my local variable here!
==24255==    at 0x4E8841A: vfprintf (vfprintf.c:1631)
==24255==    by 0x4E8F898: printf (printf.c:33)
==24255==    by 0x400548: main (test.c:10)
==24255==  Uninitialised value was created by a stack allocation
==24255==    at 0x400526: main (test.c:6)
==24255== 
==24255== Conditional jump or move depends on uninitialised value(s)
==24255== I want to print my local variable here!
==24255==    at 0x4E87CAB: vfprintf (vfprintf.c:1631)
==24255==    by 0x4E8F898: printf (printf.c:33)
==24255==    by 0x400548: main (test.c:10)
==24255==  Uninitialised value was created by a stack allocation
==24255==    at 0x400526: main (test.c:6)
==24255== 
==24255== Conditional jump or move depends on uninitialised value(s)
==24255== I want to print my local variable here!
==24255==    at 0x4E87CE2: vfprintf (vfprintf.c:1631)
==24255==    by 0x4E8F898: printf (printf.c:33)
==24255==    by 0x400548: main (test.c:10)
==24255==  Uninitialised value was created by a stack allocation
==24255==    at 0x400526: main (test.c:6)
==24255== 
==24255== 
==24255== HEAP SUMMARY:
==24255==     in use at exit: 0 bytes in 0 blocks
==24255==   total heap usage: 1 allocs, 1 frees, 4,096 bytes allocated
==24255== 
==24255== All heap blocks were freed -- no leaks are possible
==24255== 
==24255== For counts of detected and suppressed errors, rerun with: -v
==24255== ERROR SUMMARY: 8 errors from 8 contexts (suppressed: 0 from 0)

Now I want to print the value of "g_int" and "y" with the message(bug report) from valgrind. I already add a print out in the valgrind source printing: "I want to print my local variable here!" Is there any possible way to read the values of the variable from the user source code from valgrind source using any internal api? If I can get get all the variable names from the user code it will be a plus.


Solution

  • You can use VALGRIND_COUNT_ERRORS, VALGRIND_PRINTF Valgrind Client Requests for this.

    Here how you can use them in your example code:

    #include <stdio.h>
    #include <valgrind/valgrind.h>
    
    int g_int = 12;
    int main()
    {
      int y = 10;
      int x;
      printf("%d\n",x);
      if (VALGRIND_COUNT_ERRORS > 0)
      {
        VALGRIND_PRINTF("y=%d, g_int=%d\n", y, g_int);
      }
      return x;
    }
    

    Valgrind output:

    ==4030== Memcheck, a memory error detector
    ==4030== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
    ==4030== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
    ==4030== Command: ./a.out
    ==4030== 
    ==4030== Conditional jump or move depends on uninitialised value(s)
    ==4030==    at 0x4E90DDA: vfprintf (in /usr/lib64/libc-2.26.so)
    ==4030==    by 0x4E99285: printf (in /usr/lib64/libc-2.26.so)
    ==4030==    by 0x400719: main (in /home/ks/a.out)
    ==4030== 
    ==4030== Use of uninitialised value of size 8
    ==4030==    at 0x4E8CDAB: _itoa_word (in /usr/lib64/libc-2.26.so)
    ==4030==    by 0x4E9046D: vfprintf (in /usr/lib64/libc-2.26.so)
    ==4030==    by 0x4E99285: printf (in /usr/lib64/libc-2.26.so)
    ==4030==    by 0x400719: main (in /home/ks/a.out)
    ==4030== 
    ==4030== Conditional jump or move depends on uninitialised value(s)
    ==4030==    at 0x4E8CDB5: _itoa_word (in /usr/lib64/libc-2.26.so)
    ==4030==    by 0x4E9046D: vfprintf (in /usr/lib64/libc-2.26.so)
    ==4030==    by 0x4E99285: printf (in /usr/lib64/libc-2.26.so)
    ==4030==    by 0x400719: main (in /home/ks/a.out)
    ==4030== 
    ==4030== Conditional jump or move depends on uninitialised value(s)
    ==4030==    at 0x4E90572: vfprintf (in /usr/lib64/libc-2.26.so)
    ==4030==    by 0x4E99285: printf (in /usr/lib64/libc-2.26.so)
    ==4030==    by 0x400719: main (in /home/ks/a.out)
    ==4030== 
    ==4030== Conditional jump or move depends on uninitialised value(s)
    ==4030==    at 0x4E9104C: vfprintf (in /usr/lib64/libc-2.26.so)
    ==4030==    by 0x4E99285: printf (in /usr/lib64/libc-2.26.so)
    ==4030==    by 0x400719: main (in /home/ks/a.out)
    ==4030== 
    0
    **4030** y=10, g_int=12
    ==4030== Syscall param exit_group(status) contains uninitialised byte(s)
    ==4030==    at 0x4F1A478: _Exit (in /usr/lib64/libc-2.26.so)
    ==4030==    by 0x4E77B3A: __run_exit_handlers (in /usr/lib64/libc-2.26.so)
    ==4030==    by 0x4E77BD9: exit (in /usr/lib64/libc-2.26.so)
    ==4030==    by 0x4E5D040: (below main) (in /usr/lib64/libc-2.26.so)
    ==4030== 
    ==4030== 
    ==4030== HEAP SUMMARY:
    ==4030==     in use at exit: 0 bytes in 0 blocks
    ==4030==   total heap usage: 1 allocs, 1 frees, 1,024 bytes allocated
    ==4030== 
    ==4030== All heap blocks were freed -- no leaks are possible
    ==4030== 
    ==4030== For counts of detected and suppressed errors, rerun with: -v
    ==4030== Use --track-origins=yes to see where uninitialised values come from
    ==4030== ERROR SUMMARY: 6 errors from 6 contexts (suppressed: 0 from 0)
    

    Variables g_int and y are printed in this line:

    **4030** y=10, g_int=12