Skip to content

Instantly share code, notes, and snippets.

@hypothermic
Created March 1, 2022 10:38
Show Gist options
  • Save hypothermic/0ec5a4be67ce0e7ebddd4d6e4446ddf8 to your computer and use it in GitHub Desktop.
Save hypothermic/0ec5a4be67ce0e7ebddd4d6e4446ddf8 to your computer and use it in GitHub Desktop.
Example of valgrind + vgdb + gdb debugging to find uninitialized memory segments

Introduction

It took me two hours to find out that I hadn't properly initialized a dynamic array that was allocated on the stack. Valgrind is truly an awesome tool, and in conjuction with GDB it is really powerful. I will have probably forgotten how to use Valgrind in a week from now, so that's why I'm writing this quick summary on how I managed to debug the issue. I hope it's useful for future reference.

1. Running the program

In a shell, start the program in the Valgrind VM:

valgrind --vgdb=yes --vgdb-error=0 ./my_program

in another shell, start gdb and attach it to vgdb:

gdb ./my_program

(gdb) target remote | vgdb
(gdb) c

2. Hitting an error

Then, the program runs and eventually hits an error:

==231851== Conditional jump or move depends on uninitialised value(s)
==231851==    at 0x10B6C8: lane_kmeans_segment (lane_kmeans.c:42)
==231851==    by 0x1093D7: main (lane_kmseg_test.c:32)
==231851== 
==231851== (action on error) vgdb me ... 

in GDB terminal this shows:

Program received signal SIGTRAP, Trace/breakpoint trap.
0x000000000010b6c8 in lane_kmeans_segment (image=0x4b816e0, iterations=10 '\n', clusters=2 '\002') at ./src/lane_kmeans.c:42
42					if (diff < pixels[k].nearest) {

3. Investigating the error seen in 2.

First, get a pointer to the element that may be uninitialized. And also get the size of the element (in bytes).

(gdb) p &diff
$46 = (int *) 0x1ffefff9cc
(gdb) p sizeof(diff)
$47 = 4

Then, investigate whether it is allocated or not (ff means a byte is NOT allocated, 0 means a byte IS allocated):

(gdb) monitor xb 0x1ffefff9cc 4
		  ff	  ff	  ff	  ff
0x1FFEFFF9CC:	0x10	0x00	0x00	0x00

So, we found our uninitialized memory. To fix it, just assign = 0 to variables and = {0} to arrays when initializing them. Or use memset.

4. Exiting valgrind/vgdb

Use the following GDB commands to exit:

(gdb) monitor v.kill
(gdb) q

5. Proper Initialization

Either static initializers or memset is OK.

int diff = 0, avg[k] = {0}, total[k];

memset(total, 0, sizeof(total));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment