valgrind says i have definitely lost block in very simple malloced code, and I can't figure why [duplicate] - memory-leaks

Consider this code:
#include <stdlib.h>
int* alloc()
{
return malloc(250 * sizeof(int));
}
int main()
{
int i;
int *vars[3];
for(i = 0; i < 3; ++i) {
vars[i] = alloc();
}
}
Valgrind output:
$ valgrind --leak-check=full ./lala
==16775== Memcheck, a memory error detector
==16775== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==16775== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==16775== Command: ./lala
==16775==
==16775==
==16775== HEAP SUMMARY:
==16775== in use at exit: 3,000 bytes in 3 blocks
==16775== total heap usage: 3 allocs, 0 frees, 3,000 bytes allocated
==16775==
==16775== 3,000 bytes in 3 blocks are definitely lost in loss record 1 of 1
==16775== at 0x4C2BBA0: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==16775== by 0x4005B3: alloc (lala.c:5)
==16775== by 0x4005DF: main (lala.c:13)
==16775==
==16775== LEAK SUMMARY:
==16775== definitely lost: 3,000 bytes in 3 blocks
==16775== indirectly lost: 0 bytes in 0 blocks
==16775== possibly lost: 0 bytes in 0 blocks
==16775== still reachable: 0 bytes in 0 blocks
==16775== suppressed: 0 bytes in 0 blocks
==16775==
==16775== For counts of detected and suppressed errors, rerun with: -v
==16775== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
According to Valgrind's manual:
If --leak-check is set appropriately, for each remaining block,
Memcheck determines if the block is reachable from pointers within the
root-set. The root-set consists of (a) general purpose registers of
all threads, and (b) initialized, aligned, pointer-sized data words in
accessible client memory, including stacks.
For what I understand, since the "definitely lost" memory are still pointed to from the main() function's stack, they should be categorized as "still reachable", right?
If not, how can I configure Valgrind to try to reach memory blocks from main's stack, to determine if they are "still reachable"?
EDIT:
Please don't tell me to free the pointers at the end of main, that is not what I am asking about. For the distinction between "still reachable" and "definitely lost" on Valgrind terms, see this answer: https://stackoverflow.com/a/3857638/578749

Your memory is definitely lost when the stack of main is destroyed, that is, when it returns. Thus, the solution is not to return.
#include <stdlib.h>
int main()
{
/* your code here */
exit(0);
}
The behavior or main returning 0 or exit(0) should be equivalent.
Now the output is:
==5035== Memcheck, a memory error detector
==5035== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==5035== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==5035== Command: ./a.out
==5035==
==5035==
==5035== HEAP SUMMARY:
==5035== in use at exit: 3,000 bytes in 3 blocks
==5035== total heap usage: 3 allocs, 0 frees, 3,000 bytes allocated
==5035==
==5035== LEAK SUMMARY:
==5035== definitely lost: 0 bytes in 0 blocks
==5035== indirectly lost: 0 bytes in 0 blocks
==5035== possibly lost: 0 bytes in 0 blocks
==5035== still reachable: 3,000 bytes in 3 blocks
==5035== suppressed: 0 bytes in 0 blocks
==5035== Reachable blocks (those to which a pointer was found) are not shown.
==5035== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==5035==
==5035== For counts of detected and suppressed errors, rerun with: -v
==5035== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

Related

Does mio::poll produce a true memory leak and can I ignore it?

I want to poll a character device to check for an interrupt. My code appears to work but I'm getting a memory leak when I run my code under Valgrind.
I have reduced the code to a minimum example which still produces the memory leak:
use mio::Poll;
fn main() {
// Construct a new `Poll` handle
let _poll = Poll::new().unwrap();
}
I expect _poll to be dropped cleanly when it goes out of scope. However, when run under Valgrind, the above code produces the following output:
==4771== Memcheck, a memory error detector
==4771== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==4771== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==4771== Command: ./target/debug/poll_test
==4771==
==4771== Syscall param epoll_ctl(event) points to uninitialised byte(s)
==4771== at 0x49B2BAC: epoll_ctl (syscall-template.S:78)
==4771== by 0x10DDC7: mio::sys::unix::epoll::Selector::register (epoll.rs:98)
==4771== by 0x10FA0B: <mio::sys::unix::eventedfd::EventedFd<'a> as mio::event_imp::Evented>::register (eventedfd.rs:97)
==4771== by 0x10FDFB: <mio::sys::unix::io::Io as mio::event_imp::Evented>::register (io.rs:65)
==4771== by 0x10E97F: <mio::sys::unix::awakener::pipe::Awakener as mio::event_imp::Evented>::register (awakener.rs:63)
==4771== by 0x10AB7F: mio::poll::Poll::new (poll.rs:665)
==4771== by 0x10A797: poll_test::main (main.rs:5)
==4771== by 0x10A62B: std::rt::lang_start::{{closure}} (rt.rs:64)
==4771== by 0x1190AF: {{closure}} (rt.rs:49)
==4771== by 0x1190AF: std::panicking::try::do_call (panicking.rs:297)
==4771== by 0x11B407: __rust_maybe_catch_panic (lib.rs:87)
==4771== by 0x119A8B: try<i32,closure> (panicking.rs:276)
==4771== by 0x119A8B: catch_unwind<closure,i32> (panic.rs:388)
==4771== by 0x119A8B: std::rt::lang_start_internal (rt.rs:48)
==4771== by 0x10A5FB: std::rt::lang_start (rt.rs:64)
==4771== Address 0xbde4b10c is on thread 1's stack
==4771== in frame #1, created by mio::sys::unix::epoll::Selector::register (epoll.rs:91)
==4771== Uninitialised value was created by a stack allocation
==4771== at 0x10DD40: mio::sys::unix::epoll::Selector::register (epoll.rs:91)
==4771==
==4771==
==4771== HEAP SUMMARY:
==4771== in use at exit: 20 bytes in 1 blocks
==4771== total heap usage: 18 allocs, 17 frees, 2,137 bytes allocated
==4771==
==4771== 20 bytes in 1 blocks are still reachable in loss record 1 of 1
==4771== at 0x484A004: calloc (in /usr/lib/valgrind/vgpreload_memcheck-arm-linux.so)
==4771==
==4771== LEAK SUMMARY:
==4771== definitely lost: 0 bytes in 0 blocks
==4771== indirectly lost: 0 bytes in 0 blocks
==4771== possibly lost: 0 bytes in 0 blocks
==4771== still reachable: 20 bytes in 1 blocks
==4771== suppressed: 0 bytes in 0 blocks
==4771==
==4771== For counts of detected and suppressed errors, rerun with: -v
==4771== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 6 from 3)
Why does this code produce a memory leak? Can I fix it? If not, can I safely ignore it?

How to extract a last block from a file

I have a file containing many blocks like this:
==9673==
==9673== HEAP SUMMARY:
==9673== in use at exit: 0 bytes in 0 blocks
==9673== total heap usage: 75,308 allocs, 75,308 frees, 7,099,382 bytes allocated
==9673==
==9673== All heap blocks were freed -- no leaks are possible
==9673==
==9673== For counts of detected and suppressed errors, rerun with: -v
==9673== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
....
....
....
....
==9655==
==9655== HEAP SUMMARY:
==9655== in use at exit: 0 bytes in 0 blocks
==9655== total heap usage: 75,308 allocs, 75,308 frees, 7,099,382 bytes allocated
==9655==
==9655== All heap blocks were freed -- no leaks are possible
==9655==
==9655== For counts of detected and suppressed errors, rerun with: -v
==9655== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
....
....
....
==9699==
==9699== HEAP SUMMARY:
==9699== in use at exit: 0 bytes in 0 blocks
==9699== total heap usage: 75,308 allocs, 75,308 frees, 7,099,382 bytes allocated
==9699==
==9699== All heap blocks were freed -- no leaks are possible
==9699==
==9699== For counts of detected and suppressed errors, rerun with: -v
==9699== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
I want to extract the last block starting with line:
==XXXX== HEAP SUMMARY:
So in my example I want to extract only the last bloc:
==9699== HEAP SUMMARY:
==9699== in use at exit: 0 bytes in 0 blocks
==9699== total heap usage: 75,308 allocs, 75,308 frees, 7,099,382 bytes allocated
==9699==
==9699== All heap blocks were freed -- no leaks are possible
==9699==
==9699== For counts of detected and suppressed errors, rerun with: -v
==9699== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
How I can do that with bash?
Using grep -zoP and a negative lookahead regex:
grep -zoP '==\w{4}== HEAP SUMMARY:(?![\s\S]*==\w{4}== HEAP SUMMARY:)[\s\S]*\z' file
==9699== HEAP SUMMARY:
==9699== in use at exit: 0 bytes in 0 blocks
==9699== total heap usage: 75,308 allocs, 75,308 frees, 7,099,382 bytes allocated
==9699==
==9699== All heap blocks were freed -- no leaks are possible
==9699==
==9699== For counts of detected and suppressed errors, rerun with: -v
==9699== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
-z treats file data as null terminated instead of new line terminated
(?![\s\S]*==\w{4}== HEAP SUMMARY:) is negative lookahead that asserts we don't have another instance of the same in the file below.
RegEx Demo
if you have tac, this might be the easiest
$ tac file | awk '1; /==....== HEAP SUMMARY/{exit}' | tac
If you know that the blocks are always 9 lines long, you can simply use tail:
tail -n9 file
With sed:
$ sed -n '/HEAP SUMMARY/{:a;/ERROR SUMMARY/bb;N;ba;:b;$p;d}' infile
==9699== HEAP SUMMARY:
==9699== in use at exit: 0 bytes in 0 blocks
==9699== total heap usage: 75,308 allocs, 75,308 frees, 7,099,382 bytes allocated
==9699==
==9699== All heap blocks were freed -- no leaks are possible
==9699==
==9699== For counts of detected and suppressed errors, rerun with: -v
==9699== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
Here is how this works:
sed -n ' # Do not print lines at end of each cycle
/HEAP SUMMARY/ { # If line matches "HEAP SUMMARY"
:a # Label to jump back to
/ERROR SUMMARY/bb # If line matches "ERROR SUMMARY", jump to :b
N # Append next line to pattern space
ba # Jump to :a
:b # Label to jump forward to
$p # If we are on the last line, print pattern space
d # Delete pattern space
}
' infile
Each time this encounters HEAP SUMMARY, it reads all the lines up to the next ERROR SUMMARY into the pattern space. Then, it checks if the last line has been reached; if yes, the pattern space gets printed, if not, it gets deleted.
If the last line of the file also has the block number, this will get the block number fast (no reading of the whole file to find which number that is):
n="$(tail -n1 infile | awk '{print $1}')"
Then we can select all lines that have such block number from the end up:
tac infile | awk -vn="$n" '!($1~n){exit};1'| tac
This might work for you (GNU sed):
sed '/HEAP SUMMARY:/h;//!H;$!d;x' file
When encountering HEAP SUMMARY: replace whatever is in the hold space (HS) by the current line. For any other pattern append tha line to the HS. Delete all lines excepting the last, when the pattern space (PS) is swapped with the HS and the PS is printed out.
Using number in front of data as an id /group number:
id=$(tail -n1 file | grep -Po '(?<=\=\=)[0-9]*') && grep "$id" file |tail -n+2

What is a minimal example of an Rc dependency cycle?

I'm trying to write a Rust program that leaks memory due to cycles with reference counts. The following example, which seems like it should cause a memory leak, does not leak memory according to Valgrind. What gives?
test.rs:
use std::cell::RefCell;
use std::rc::Rc;
struct Foo {
f: Rc<Bar>,
}
struct Bar {
b: RefCell<Option<Rc<Foo>>>,
}
fn main() {
let bar = Rc::new(Bar {
b: RefCell::new(None),
});
let foo = Rc::new(Foo { f: bar.clone() });
*bar.b.borrow_mut() = Some(foo.clone());
}
Valgrind output:
$ rustc --version
rustc 1.4.0 (8ab8581f6 2015-10-27)
$ rustc -o test test.rs
$ valgrind test
==23331== Memcheck, a memory error detector
==23331== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==23331== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==23331== Command: test
==23331==
==23331==
==23331== HEAP SUMMARY:
==23331== in use at exit: 0 bytes in 0 blocks
==23331== total heap usage: 37 allocs, 37 frees, 9,078 bytes allocated
==23331==
==23331== All heap blocks were freed -- no leaks are possible
==23331==
==23331== For counts of detected and suppressed errors, rerun with: -v
==23331== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
With the version of Rust you were using, it's most likely that you were using jemalloc, which doesn't always play well with Valgrind (see the linked questions for more information). With modern versions of Rust, the system allocator is used by default and the code you have posted does report memory leaks:
$ valgrind --leak-check=full ./test
==761== Memcheck, a memory error detector
==761== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==761== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==761== Command: ./test
==761==
==761==
==761== HEAP SUMMARY:
==761== in use at exit: 56 bytes in 2 blocks
==761== total heap usage: 13 allocs, 11 frees, 2,233 bytes allocated
==761==
==761== 56 (32 direct, 24 indirect) bytes in 1 blocks are definitely lost in loss record 2 of 2
==761== at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==761== by 0x10BDAB: alloc::alloc::alloc (in /tmp/test)
==761== by 0x10BD17: alloc::alloc::exchange_malloc (in /tmp/test)
==761== by 0x10C3F6: <alloc::rc::Rc<T>>::new (in /tmp/test)
==761== by 0x10BF6F: test::main (in /tmp/test)
==761== by 0x10DAF2: std::rt::lang_start::{{closure}} (in /tmp/test)
==761== by 0x115CC2: {{closure}} (rt.rs:49)
==761== by 0x115CC2: std::panicking::try::do_call (panicking.rs:297)
==761== by 0x117BA9: __rust_maybe_catch_panic (lib.rs:87)
==761== by 0x11677C: try<i32,closure> (panicking.rs:276)
==761== by 0x11677C: catch_unwind<closure,i32> (panic.rs:388)
==761== by 0x11677C: std::rt::lang_start_internal (rt.rs:48)
==761== by 0x10DAD4: std::rt::lang_start (in /tmp/test)
==761== by 0x10C19A: main (in /tmp/test)
==761==
==761== LEAK SUMMARY:
==761== definitely lost: 32 bytes in 1 blocks
==761== indirectly lost: 24 bytes in 1 blocks
==761== possibly lost: 0 bytes in 0 blocks
==761== still reachable: 0 bytes in 0 blocks
==761== suppressed: 0 bytes in 0 blocks
==761==
==761== For counts of detected and suppressed errors, rerun with: -v
==761== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
I am using Valgrind 3.13.0 with Rust 1.34.1 on Ubuntu, but I do not believe that would change the results.
You can also add dummy values to your structs to more easily find them in the output. I used a Box<[u8; 10240]> which stands out pretty well.
As for minimal, I'd model a linked list:
use std::cell::RefCell;
use std::rc::Rc;
struct Node {
next: RefCell<Option<Rc<Node>>>,
}
fn main() {
let foo1 = Rc::new(Node {
next: RefCell::new(None),
});
let foo2 = Rc::new(Node {
next: RefCell::new(Some(foo1.clone())),
});
*foo1.next.borrow_mut() = Some(foo2.clone());
}
This program also reports leaks.
See also:
Why does Valgrind not detect a memory leak in a Rust program using nightly 1.29.0?
Valgrind shows no allocations

is there any static code analyzer which can catch this memory leak?

Such leaks seem too trivial to naked eye and I think static code analysis tools should be able to find them out.
Ex1:
void foo(void) {
u32 *ptr = kmalloc(512, GFP_KERNEL);
ptr = (u32 *)0xffffffff;
kfree(ptr);
}
I know Coverity can find leaks as below but not sure about the above one: Can anyone please let me know if this will get detected in either Coverity or tools like Sparse?
Ex2:
void foo(void) {
kmalloc(512, GFP_KERNEL);
}
Ex3:
void foo(void) {
void * ptr = kmalloc(512, GFP_KERNEL);
if (true)
return;
kfree(ptr)
}
I don't know about kmalloc (and I don't have a Linux system with a Coverity license to test that on), but Coverity detects leaks of this form with malloc easily. So I doubt kmalloc would give it trouble.
If it does give trouble, you can always provide a user model of the kmalloc function that just wraps around the malloc function so Coverity knows how to treat the function.
Valgrind can be used to detect memory leaks mentioned in Ex1.
e.g.
#include<stdio.h>
void foo(void) {
int *ptr = (int *)malloc(512);
ptr = (int *)0xffffffff;
free(ptr);
}
int main(){
foo();
return 1;
}
Valigrind Output:
[test#myhost /tmp]# valgrind --tool=memcheck --leak-check=full ./Ex1
==23780== Memcheck, a memory error detector
==23780== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al.
==23780== Using Valgrind-3.5.0 and LibVEX; rerun with -h for copyright info
==23780== Command: ./Ex1
==23780==
==23780== Invalid free() / delete / delete[]
==23780== at 0x4A05A31: free (vg_replace_malloc.c:325)
==23780== by 0x400509: foo (in /tmp/Ex1)
==23780== by 0x400514: main (in /tmp/Ex1)
==23780== Address 0xffffffff is not stack'd, malloc'd or (recently) free'd
==23780==
==23780==
==23780== HEAP SUMMARY:
==23780== in use at exit: 512 bytes in 1 blocks
==23780== total heap usage: 1 allocs, 1 frees, 512 bytes allocated
==23780==
==23780== 512 bytes in 1 blocks are definitely lost in loss record 1 of 1
==23780== at 0x4A05E1C: malloc (vg_replace_malloc.c:195)
==23780== by 0x4004E9: foo (in /tmp/Ex1)
==23780== by 0x400514: main (in /tmp/Ex1)
==23780==
==23780== LEAK SUMMARY:
==23780== definitely lost: 512 bytes in 1 blocks
==23780== indirectly lost: 0 bytes in 0 blocks
==23780== possibly lost: 0 bytes in 0 blocks
==23780== still reachable: 0 bytes in 0 blocks
==23780== suppressed: 0 bytes in 0 blocks
==23780==
==23780== For counts of detected and suppressed errors, rerun with: -v
==23780== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 4 from 4)

Valgrind memory leak detection

I am new to Valgrind, and I wanted to see how valgrind works. I wrote a sample program for memory leak. However Valgrind does not seem to detect a memory leak. Can you please tell me why? Or does the below code leak memory?
#include <iostream>
using namespace std;
class test {
private:
int a;
public:
test(int c) {
a = c;
}
};
int main() {
test* t = new test(7);
}
this is the valgrind output
HEAP SUMMARY:
==5449== in use at exit: 0 bytes in 0 blocks
==5449== total heap usage: 29 allocs, 29 frees, 3,592 bytes allocated
==5449==
==5449== All heap blocks were freed -- no leaks are possible
I don't think that constitutes a memory leak; the memory at pointer t is not 'lost' until t goes out of scope, and that's at the end of main() so there's no memory loss.
dan#rachel ~ $ g++ -o t t.cpp
dan#rachel ~ $ valgrind ./t
==11945== Memcheck, a memory error detector
==11945== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==11945== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==11945== Command: ./t
==11945==
==11945==
==11945== HEAP SUMMARY:
==11945== in use at exit: 36 bytes in 9 blocks
==11945== total heap usage: 9 allocs, 0 frees, 36 bytes allocated
==11945==
==11945== LEAK SUMMARY:
==11945== definitely lost: 36 bytes in 9 blocks
==11945== indirectly lost: 0 bytes in 0 blocks
==11945== possibly lost: 0 bytes in 0 blocks
==11945== still reachable: 0 bytes in 0 blocks
==11945== suppressed: 0 bytes in 0 blocks
==11945== Rerun with --leak-check=full to see details of leaked memory
==11945==
==11945== For counts of detected and suppressed errors, rerun with: -v
==11945== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2)
The code was modified slightly to use test* t multiple times in a for loop, effectively "forgetting" all but the last test object.
#include <iostream>
using namespace std;
class test {
private:
int a;
public:
test(int c){
a = c;
}
};
int main(){
test* t;
for(int i=1; i<10;i++)
t=new test(i);
}
For even better memory leak patching, try compiling with debugging information and using the valgrind option recommended in the output:
dan#rachel ~ $ g++ -g -o t t.cpp
dan#rachel ~ $ valgvalgrind --leak-check=full ./t
==11981== Memcheck, a memory error detector
==11981== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==11981== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==11981== Command: ./t
==11981==
==11981==
==11981== HEAP SUMMARY:
==11981== in use at exit: 36 bytes in 9 blocks
==11981== total heap usage: 9 allocs, 0 frees, 36 bytes allocated
==11981==
==11981== 36 bytes in 9 blocks are definitely lost in loss record 1 of 1
==11981== at 0x4C2C099: operator new(unsigned long) (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==11981== by 0x4006EF: main (t.cpp:15)
==11981==
==11981== LEAK SUMMARY:
==11981== definitely lost: 36 bytes in 9 blocks
==11981== indirectly lost: 0 bytes in 0 blocks
==11981== possibly lost: 0 bytes in 0 blocks
==11981== still reachable: 0 bytes in 0 blocks
==11981== suppressed: 0 bytes in 0 blocks
==11981==
==11981== For counts of detected and suppressed errors, rerun with: -v
==11981== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 2 from 2)
Try allocating t to another test object - i.e.
int main() {
test* t = new test(7);
t = new test(7);
t = new test(8); // and so on...
}
I believe each time t is assigned to another memory location, without freeing the previously allocated memory will constitute a leak (unless your compiler is smart enough to see that the allocated memory is never used and does something clever -- in which case, be doubly certain by creating some sample variables that use t , before reassigning t and maybe even return one of those variables...)

Resources