【Valgrind】How to check if we reading uninitialized memory in 10 min

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3
 4 int main(int argc, char** argv)
 5 {
 6   int i;
 7   int a[10];
 8   for (i = 0; i < 9; i++)
 9     a[i] = i;
10
11   for (i = 0; i < 10; i++){
12     printf("%d ", a[i]);
13   }
14   printf("\n");
15   return 0;
16 }

Let‘s build and run:

$ gcc -O0 -g un_uninit.c -o un_uninit
$ ./un_uninit
0 1 2 3 4 5 6 7 8 32767

It seems not as expect, and reading some memory that is randomized. Let‘s use Valgrind to test:

 1 $ valgrind ./un_uninit
 2 ==3863== Memcheck, a memory error detector
 3 ==3863== Copyright (C) 2002-2013, and GNU GPL‘d, by Julian Seward et al.
 4 ==3863== Using Valgrind-3.10.0.SVN and LibVEX; rerun with -h for copyright info
 5 ==3863== Command: ./un_uninit
 6 ==3863==
 7 ==3863== Conditional jump or move depends on uninitialised value(s)
 8 ==3863==    at 0x4E8183E: vfprintf (vfprintf.c:1660)
 9 ==3863==    by 0x4E8B748: printf (printf.c:33)
10 ==3863==    by 0x4005CD: main (un_uninit.c:12)
11 ==3863==
12 ==3863== Use of uninitialised value of size 8
13 ==3863==    at 0x4E80CFB: _itoa_word (_itoa.c:179)
14 ==3863==    by 0x4E849A6: vfprintf (vfprintf.c:1660)
15 ==3863==    by 0x4E8B748: printf (printf.c:33)
16 ==3863==    by 0x4005CD: main (un_uninit.c:12)
17 ==3863==
18 ==3863== Conditional jump or move depends on uninitialised value(s)
19 ==3863==    at 0x4E80D05: _itoa_word (_itoa.c:179)
20 ==3863==    by 0x4E849A6: vfprintf (vfprintf.c:1660)
21 ==3863==    by 0x4E8B748: printf (printf.c:33)
22 ==3863==    by 0x4005CD: main (un_uninit.c:12)
23 ==3863==
24 ==3863== Conditional jump or move depends on uninitialised value(s)
25 ==3863==    at 0x4E849F2: vfprintf (vfprintf.c:1660)
26 ==3863==    by 0x4E8B748: printf (printf.c:33)
27 ==3863==    by 0x4005CD: main (un_uninit.c:12)
28 ==3863==
29 ==3863== Conditional jump or move depends on uninitialised value(s)
30 ==3863==    at 0x4E81909: vfprintf (vfprintf.c:1660)
31 ==3863==    by 0x4E8B748: printf (printf.c:33)
32 ==3863==    by 0x4005CD: main (un_uninit.c:12)
33 ==3863==
34 ==3863== Conditional jump or move depends on uninitialised value(s)
35 ==3863==    at 0x4E8198C: vfprintf (vfprintf.c:1660)
36 ==3863==    by 0x4E8B748: printf (printf.c:33)
37 ==3863==    by 0x4005CD: main (un_uninit.c:12)
38 ==3863==
39 0 1 2 3 4 5 6 7 8 15
40 ==3863==
41 ==3863== HEAP SUMMARY:
42 ==3863==     in use at exit: 0 bytes in 0 blocks
43 ==3863==   total heap usage: 0 allocs, 0 frees, 0 bytes allocated
44 ==3863==
45 ==3863== All heap blocks were freed -- no leaks are possible
46 ==3863==
47 ==3863== For counts of detected and suppressed errors, rerun with: -v
48 ==3863== Use --track-origins=yes to see where uninitialised values come from
49 ==3863== ERROR SUMMARY: 8 errors from 6 contexts (suppressed: 0 from 0)

From the error msg, we find there is "Use of uninitialised value of size 8" in line 12.

Let‘s assume we still cannot be sure if i or a[i] is the root cause, and use ‘--track-origins=yes‘ valgrind command line:

 1 $ valgrind --track-origins=yes ./un_uninit
 2 ==3917== Memcheck, a memory error detector
 3 ==3917== Copyright (C) 2002-2013, and GNU GPL‘d, by Julian Seward et al.
 4 ==3917== Using Valgrind-3.10.0.SVN and LibVEX; rerun with -h for copyright info
 5 ==3917== Command: ./un_uninit
 6 ==3917==
 7 ==3917== Conditional jump or move depends on uninitialised value(s)
 8 ==3917==    at 0x4E8183E: vfprintf (vfprintf.c:1660)
 9 ==3917==    by 0x4E8B748: printf (printf.c:33)
10 ==3917==    by 0x4005CD: main (un_uninit.c:12)
11 ==3917==  Uninitialised value was created by a stack allocation
12 ==3917==    at 0x40057D: main (un_uninit.c:5)
13 ==3917==
14 ==3917== Use of uninitialised value of size 8
15 ==3917==    at 0x4E80CFB: _itoa_word (_itoa.c:179)
16 ==3917==    by 0x4E849A6: vfprintf (vfprintf.c:1660)
17 ==3917==    by 0x4E8B748: printf (printf.c:33)
18 ==3917==    by 0x4005CD: main (un_uninit.c:12)
19 ==3917==  Uninitialised value was created by a stack allocation
20 ==3917==    at 0x40057D: main (un_uninit.c:5)
21 ==3917==
22 ==3917== Conditional jump or move depends on uninitialised value(s)
23 ==3917==    at 0x4E80D05: _itoa_word (_itoa.c:179)
24 ==3917==    by 0x4E849A6: vfprintf (vfprintf.c:1660)
25 ==3917==    by 0x4E8B748: printf (printf.c:33)
26 ==3917==    by 0x4005CD: main (un_uninit.c:12)
27 ==3917==  Uninitialised value was created by a stack allocation
28 ==3917==    at 0x40057D: main (un_uninit.c:5)
29 ==3917==
30 ==3917== Conditional jump or move depends on uninitialised value(s)
31 ==3917==    at 0x4E849F2: vfprintf (vfprintf.c:1660)
32 ==3917==    by 0x4E8B748: printf (printf.c:33)
33 ==3917==    by 0x4005CD: main (un_uninit.c:12)
34 ==3917==  Uninitialised value was created by a stack allocation
35 ==3917==    at 0x40057D: main (un_uninit.c:5)
36 ==3917==
37 ==3917== Conditional jump or move depends on uninitialised value(s)
38 ==3917==    at 0x4E81909: vfprintf (vfprintf.c:1660)
39 ==3917==    by 0x4E8B748: printf (printf.c:33)
40 ==3917==    by 0x4005CD: main (un_uninit.c:12)
41 ==3917==  Uninitialised value was created by a stack allocation
42 ==3917==    at 0x40057D: main (un_uninit.c:5)
43 ==3917==
44 ==3917== Conditional jump or move depends on uninitialised value(s)
45 ==3917==    at 0x4E8198C: vfprintf (vfprintf.c:1660)
46 ==3917==    by 0x4E8B748: printf (printf.c:33)
47 ==3917==    by 0x4005CD: main (un_uninit.c:12)
48 ==3917==  Uninitialised value was created by a stack allocation
49 ==3917==    at 0x40057D: main (un_uninit.c:5)
50 ==3917==
51 0 1 2 3 4 5 6 7 8 15
52 ==3917==
53 ==3917== HEAP SUMMARY:
54 ==3917==     in use at exit: 0 bytes in 0 blocks
55 ==3917==   total heap usage: 0 allocs, 0 frees, 0 bytes allocated
56 ==3917==
57 ==3917== All heap blocks were freed -- no leaks are possible
58 ==3917==
59 ==3917== For counts of detected and suppressed errors, rerun with: -v
60 ==3917== ERROR SUMMARY: 8 errors from 6 contexts (suppressed: 0 from 0)

Now, everything is clear by "Uninitialised value was created by a stack allocation" in line 5(this line number should cover all the varable in stack).

reference:

http://pages.cs.wisc.edu/~bart/537/valgrind.html

时间: 2024-11-06 09:06:28

【Valgrind】How to check if we reading uninitialized memory in 10 min的相关文章

【Valgrind】How to check memory leak and where it&#39;s in 10 mins

1. Install sudo apt-get install valgrind 2. If memory leak example code: /* memleak.c */ #include <stdlib.h> void* memleak(int n) { void *p = malloc(n); return p; } memleak.c /* main.c */ #include <stdio.h> #include <stdlib.h> void* meml

【Valgrind】How to check buffer overflow/underflow in 10 mins

Introduction Buffer overflow/underflow frequently happens when we did something wrong with the array index, no matter the array is heap or stack, no matter you are reading the memory or writing the memory. Example 1: heap overflow // head_overflow.c

【转】Git如何Check Out出指定文件或者文件夹

[转]Git如何Check Out出指定文件或者文件夹http://www.handaoliang.com/a/20140506/195406.html 在进行项目开发的时候,有时候会有这样的需求那就是:我们只希望从Git仓库里取指定的文件或者文件夹出来.在SVN里面,这非常容易实现,因为SVN基于文件方式存储,而Git却是基于元数据方式分布式存储文件信息的,它会在每一次Clone的时候将所有信息都取回到本地,即相当于在你的机器上生成一个克隆版的版本库.因此在Git1.7.0以前,这无法实现,但

【DataStructure】A useful util class for reading and writing files

Faced with the upcoming exam, Some useful methods referred to file operation drew tremenous attention. Now I make a summary to reading file. [java] view plaincopy import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; impo

【Oracle】Exadata Heathy Check工具Exachk的使用

在Exadata中,出现任何与数据库无关的问题的时候最好都运行exachk进行健康检查.exachk收集的信息很全,省去大量人工收集的繁琐步骤.并且收集完成以后,可以在整体上对系统的健康状况做一个评估,该报告包含软件.硬件.固件版本.配置等方面信息,从中发现一些可疑点,进而缩小范围进行下一步的诊断. 这篇文章主要记录了exachk的基本使用方法,exachk可以从MOS文档:1070954.1中下载得到. 首先要声明两个环境变量RAT_ORACLE_HOME和RAT_EXADATA_VERSIO

【SQLSERVER】How to check current pool size

SELECT des.program_name , des.login_name , des.host_name , COUNT(des.session_id) [Connections] FROM sys.dm_exec_sessions des INNER JOIN sys.dm_exec_connections DEC ON des.session_id = DEC.session_id WHERE des.is_user_process = 1 AND des.status != 'ru

【转】UltraISO制作U盘启动盘安装Win7/9/10系统攻略

U盘安装好处就是不用使用笨拙的光盘,光盘还容易出现问题,无法读取的问题.U盘体积小,携带方便,随时都可以制作系统启动盘. U盘建议选择8G及以上大小的. 下面一步一步讲解如果制作U盘安装盘: 1.首先是要先下载操作系统,推荐大家去下面这个网站下载,都是MSDN微软原版,非常棒. http://msdn.itellyou.cn/ 这里我们以下载到的最新64位Win10为例介绍,我们下载的Win10版本如下图所示,下载好的文件为:cn_windows_10_multiple_editions_x64

【转】Linux 下取进程占用 cpu/内存 最高的前10个进程

# Linux 下 取进程占用 cpu 最高的前10个进程ps aux|head -1;ps aux|grep -v PID|sort -rn -k +3|head # linux 下 取进程占用内存(MEM)最高的前10个进程ps aux|head -1;ps aux|grep -v PID|sort -rn -k +4|head 转自:http://blog.csdn.net/namesliu/article/details/6037972

【转】Oracle中如何用一条SQL快速生成10万条测试数据

转自http://blog.csdn.net/welken/article/details/4971887 做数据库开发或管理的人经常要创建大量的测试数据,动不动就需要上万条,如果一条一条的录入,那会浪费大量的时间,本文介绍了Oracle中如何通过一条SQL快速生成大量的测试数据的方法. 产生测试数据的SQL如下: SQL> select rownum as id,  2                 to_char(sysdate + rownum / 24 / 3600, 'yyyy-mm