11

I'm learning C language from Learn C The Hard Way. I'm on exercise 6 and while I can make it work, valgrind repots a lot of errors.

Here's the stripped down minimal program from a file ex6.c:

#include <stdio.h>

int main(int argc, char *argv[])
{
    char initial = 'A';
    float power = 2.345f;

    printf("Character is %c.\n", initial);
    printf("You have %f levels of power.\n", power);

    return 0;
}

Content of Makefile is just CFLAGS=-Wall -g.

I compile the program with $ make ex6 (there are no compiler warnings or errors). Executing with $ ./ex6 produces the expected output.

When I run the program with $ valgrind ./ex6 I get errors which I can't solve. Here's the full output:

==69691== Memcheck, a memory error detector
==69691== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==69691== Using Valgrind-3.11.0.SVN and LibVEX; rerun with -h for copyright info
==69691== Command: ./ex6
==69691==
--69691-- UNKNOWN mach_msg unhandled MACH_SEND_TRAILER option
--69691-- UNKNOWN mach_msg unhandled MACH_SEND_TRAILER option (repeated 2 times)
--69691-- UNKNOWN mach_msg unhandled MACH_SEND_TRAILER option (repeated 4 times)
==69691== Conditional jump or move depends on uninitialised value(s)
==69691==    at 0x1003FBC3F: _platform_memchr$VARIANT$Haswell (in /usr/lib/system/libsystem_platform.dylib)
==69691==    by 0x1001EFBB6: __sfvwrite (in /usr/lib/system/libsystem_c.dylib)
==69691==    by 0x1001FA005: __vfprintf (in /usr/lib/system/libsystem_c.dylib)
==69691==    by 0x10021F9CE: __v2printf (in /usr/lib/system/libsystem_c.dylib)
==69691==    by 0x10021FCA0: __xvprintf (in /usr/lib/system/libsystem_c.dylib)
==69691==    by 0x1001F5B91: vfprintf_l (in /usr/lib/system/libsystem_c.dylib)
==69691==    by 0x1001F39F7: printf (in /usr/lib/system/libsystem_c.dylib)
==69691==    by 0x100000F1B: main (ex6.c:8)
==69691==
Character is A.
==69691== Invalid read of size 32
==69691==    at 0x1003FBC1D: _platform_memchr$VARIANT$Haswell (in /usr/lib/system/libsystem_platform.dylib)
==69691==    by 0x1001EFBB6: __sfvwrite (in /usr/lib/system/libsystem_c.dylib)
==69691==    by 0x1001FA005: __vfprintf (in /usr/lib/system/libsystem_c.dylib)
==69691==    by 0x10021F9CE: __v2printf (in /usr/lib/system/libsystem_c.dylib)
==69691==    by 0x10021FCA0: __xvprintf (in /usr/lib/system/libsystem_c.dylib)
==69691==    by 0x1001F5B91: vfprintf_l (in /usr/lib/system/libsystem_c.dylib)
==69691==    by 0x1001F39F7: printf (in /usr/lib/system/libsystem_c.dylib)
==69691==    by 0x100000F31: main (ex6.c:9)
==69691==  Address 0x100809680 is 32 bytes before a block of size 32 in arena "client"
==69691==
You have 2.345000 levels of power.
==69691==
==69691== HEAP SUMMARY:
==69691==     in use at exit: 39,365 bytes in 429 blocks
==69691==   total heap usage: 510 allocs, 81 frees, 45,509 bytes allocated
==69691==
==69691== LEAK SUMMARY:
==69691==    definitely lost: 16 bytes in 1 blocks
==69691==    indirectly lost: 0 bytes in 0 blocks
==69691==      possibly lost: 13,090 bytes in 117 blocks
==69691==    still reachable: 26,259 bytes in 311 blocks
==69691==         suppressed: 0 bytes in 0 blocks
==69691== Rerun with --leak-check=full to see details of leaked memory
==69691==
==69691== For counts of detected and suppressed errors, rerun with: -v
==69691== Use --track-origins=yes to see where uninitialised values come from
==69691== ERROR SUMMARY: 5 errors from 2 contexts (suppressed: 0 from 0)

I'm on OS X yosemite. Valgrind is installed via brew with this command $ brew install valgrind --HEAD.

So, does anyone know what's the issue here? How do I fix the valgrind errors?

  • Are you linking to some external library? – Iharob Al Asimi Jan 08 '15 at 14:59
  • 2
    On my Linux, your example doesn't report any errors. In the Related Links sidebar, there's [one that suggests using suppression files](http://stackoverflow.com/questions/5226691/valgrind-mac-os-mem-leak?rq=1). – M Oehm Jan 08 '15 at 15:00
  • @IngoLeonhardt: Variadic arguments of type `float` are promoted to `double`, so that shouldn't be a problem. (And the correct prototype is in ``, which was included.) – M Oehm Jan 08 '15 at 19:50
  • 1
    This is characteristic of the false positives that `--partial-loads-ok=yes` is supposed to fix. – Nemo Jan 09 '15 at 02:12
  • Similar thread with same question and a slightly different array of answers: [Valgrind on OS X Yosemite, giving bogus errors?](http://stackoverflow.com/questions/29312335/valgrind-on-os-x-yosemite-giving-bogus-errors?noredirect=1) – M.M Jun 07 '15 at 11:20
  • There seem to be a similar incompatibility now with Valgrind and MacOS 10.14. I can report that disabling output buffering via `setbuf(stdout, NULL);` is a workaround. – real-or-random Sep 11 '20 at 11:47

3 Answers3

11

If the programme you are running through Valgrind is exactly the one you posted in your question, it clearly doesn't have any memory leaks. In fact, you don't even use malloc/free yourself!

It looks to me like these are spurious errors / false positives that Valgrind detects on OS X (only!), similar to what happened to myself some time ago.

If you have access to a different operating system, e.g. a Linux machine, try to analyze the programme using Valgrind on that system.

EDIT: I haven't tried this myself, since I don't have access to a Mac right now, but you should try what M Oehm suggested: try to use a supressions file as mentioned in this other SO question.

Community
  • 1
  • 1
Genba
  • 854
  • 2
  • 10
  • 19
  • I couldn't find a suppression file for OS X Yosemite. The one from that SA answer didn't have any effect on Valgrind output. On the other hand, doing the same steps in vagrant with linux produced a clean Valgrind output. –  Jan 10 '15 at 20:44
  • I confirmed this on my own machine. I duplicated this simple program on Mac OS X, ran with Valgrind, and got a conditional jump. – intcreator Jul 28 '15 at 18:38
10

This issue is fixed for Darwin 14.3.0 (Mac OS X 10.10.2) using Valgrind r14960 with VEX r3124 for Xcode6.2 and Valgrind r15088 for Xcode 6.3.

If you are using Macports (at this time of writing), sudo port install valgrind-devel will give you Valgrind r14960 with VEX r3093.

Here's my build script to install Valgrind r14960 with VEX r3124:

#! /usr/bin/env bash

mkdir -p buildvalgrind
cd buildvalgrind
svn co svn://svn.valgrind.org/valgrind/trunk/@14960 valgrind
cd valgrind
./autogen.sh
./configure --prefix=/usr/local
make && sudo make install

# check that we have our valgrind installed
/usr/local/bin/valgrind --version 

(reference: http://calvinx.com/2015/04/10/valgrind-on-mac-os-x-10-10-yosemite/)

My macports-installed valgrind is located at /opt/local/bin/valgrind.

If I now run

/opt/local/bin/valgrind --leak-check=yes --suppressions=`pwd`/objc.supp ./ex6

I will get exactly the same errors you described above. (Using my objc.supp file here https://gist.github.com/calvinchengx/0b1d45f67be9fdca205b)

But if I run

/usr/local/bin/valgrind --leak-check=yes --suppressions=`pwd`/objc.supp ./ex6

Everything works as expected and I do not get the system level memory leak errors showing up.

Calvin Cheng
  • 35,640
  • 39
  • 116
  • 167
1

Judging from this topic, I assume that valgrind is not guaranteed to give correct results on your platform. If you can, try this code on another platform.

The culprit is either in valgrid itself or in your system's implementation of printf, both of which would be impractical for you to fix.

Rerun with --leak-check=full to see details of leaked memory. This should give you some more information about the leak you are experiencing. If nothing helps, you can create a suppression file to stop the errors from being displayed.

Community
  • 1
  • 1
Daerst
  • 954
  • 7
  • 24
  • Unfortunately you can't create a suppression file for "Invalid read of size 32" currently. There is this new error in the Darwin port, but yet not support for suppressing errors with a size greater than 16. Should be a matter of time to get this implemented (sounds like a trivial fix). – antirez Jan 24 '15 at 08:37