2

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.

kayas
  • 703
  • 1
  • 5
  • 14

3 Answers3

3

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
ks1322
  • 33,961
  • 14
  • 109
  • 164
  • Thanks a lot for your answer. Actually I want to use the values the local variables(a thread local variable in particular) inside Valgrind source code. Only printing the values will will not work for me, I need to get value of a thread local variable inside Valgrind source code. Can you give me some suggestion on that? – kayas Dec 01 '17 at 00:19
0

Try using the option

--track-origins=yes

This will give further information on dynamic memory.

Additionally, try

--read-var-info=yes

This should be used with a debug build (see the comment about compiling with -g). This will give further information on automatic variables.

Paul Floyd
  • 5,530
  • 5
  • 29
  • 43
  • I used your suggested options and attached the valgrind output in my edited question. But still can not find any way to access the local variables from valgrind source code. Even, can not see any useful information about the variable names, values in the valgrind output. – kayas Nov 22 '17 at 18:25
  • It doesn't give you the name of the variable, but it does tell you which line the error happens and it gives you the scope of the variable. I was expecting it to give the variable name (which is what the doc says). Could be an issue with Valgrind and it's ability to read debug dwarf-3 information. – Paul Floyd Nov 24 '17 at 16:27
0

Use the valgrind option --vgdb-error=1

With this, when valgrind reports an error, it will wait for a gdb to attach. With gdb, you can then look at all local or global variables.

See http://www.valgrind.org/docs/manual/manual-core-adv.html#manual-core-adv.gdbserver for more info.

phd
  • 3,669
  • 1
  • 11
  • 12
  • I want to access the variables from valgrind source, not in the command line. gdb gives me variable information in the command line. In my question, I already attachment the custom message "I want to print my local variable here!". In place of that message I want to print my local variable. – kayas Nov 25 '17 at 22:17
  • You mean: what you would like is that the errors reported by valgrind automatically show the local variables ? I guess you might do that by scripting gdb, based on the about vgdb connection. You might e.g. use hook-stop in gdb to run bactrace full : this will show all local variables – phd Nov 26 '17 at 16:45