3

I'm following along in Learn C The Hard Way and I'm on Exercise 4: Introducing Valgrind. I'm on Mac OS X Yosemite, and as of this writing, there's not a stable build of Valgrind for Yosemite. I found Yosemite and Valgrind and used the directions from the top-voted answer to brew install --HEAD valgrind. This installed Valgrind and I was able to follow along with Zed's exercise. However, when I "fixed" the app, I was still getting errors.

To double check, I went back to Exercise 3, which shouldn't have errors, but I still got errors in Valgrind. Here's the code and then the output:

ex3.c

#include <stdio.h>

int main()
{
    int age = 10;
    int height = 72;

    printf("I am %d years old.\n", age);
    printf("I am %d inches tall.\n", height);

    return 0;
}

In iTerm:

ransom:learn-c-the-hard-way ben$ rm -f ex3
ransom:learn-c-the-hard-way ben$ make ex3
cc -Wall -g    ex3.c   -o ex3
ransom:learn-c-the-hard-way ben$ valgrind ./ex3
==8795== Memcheck, a memory error detector
==8795== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==8795== Using Valgrind-3.11.0.SVN and LibVEX; rerun with -h for copyright info
==8795== Command: ./ex3
==8795==
==8795== Conditional jump or move depends on uninitialised value(s)
==8795==    at 0x1003FBC3F: _platform_memchr$VARIANT$Haswell (in /usr/lib/system/libsystem_platform.dylib)
==8795==    by 0x1001EFB96: __sfvwrite (in /usr/lib/system/libsystem_c.dylib)
==8795==    by 0x1001F9FE5: __vfprintf (in /usr/lib/system/libsystem_c.dylib)
==8795==    by 0x10021F9AE: __v2printf (in /usr/lib/system/libsystem_c.dylib)
==8795==    by 0x10021FC80: __xvprintf (in /usr/lib/system/libsystem_c.dylib)
==8795==    by 0x1001F5B71: vfprintf_l (in /usr/lib/system/libsystem_c.dylib)
==8795==    by 0x1001F39D7: printf (in /usr/lib/system/libsystem_c.dylib)
==8795==    by 0x100000F2D: main (ex3.c:8)
==8795==
==8795== Conditional jump or move depends on uninitialised value(s)
==8795==    at 0x1003FBC47: _platform_memchr$VARIANT$Haswell (in /usr/lib/system/libsystem_platform.dylib)
==8795==    by 0x1001EFB96: __sfvwrite (in /usr/lib/system/libsystem_c.dylib)
==8795==    by 0x1001F9FE5: __vfprintf (in /usr/lib/system/libsystem_c.dylib)
==8795==    by 0x10021F9AE: __v2printf (in /usr/lib/system/libsystem_c.dylib)
==8795==    by 0x10021FC80: __xvprintf (in /usr/lib/system/libsystem_c.dylib)
==8795==    by 0x1001F5B71: vfprintf_l (in /usr/lib/system/libsystem_c.dylib)
==8795==    by 0x1001F39D7: printf (in /usr/lib/system/libsystem_c.dylib)
==8795==    by 0x100000F2D: main (ex3.c:8)
==8795==
I am 10 years old.
I am 72 inches tall.
==8795==
==8795== HEAP SUMMARY:
==8795==     in use at exit: 38,888 bytes in 426 blocks
==8795==   total heap usage: 506 allocs, 80 frees, 45,016 bytes allocated
==8795==
==8795== LEAK SUMMARY:
==8795==    definitely lost: 0 bytes in 0 blocks
==8795==    indirectly lost: 0 bytes in 0 blocks
==8795==      possibly lost: 0 bytes in 0 blocks
==8795==    still reachable: 4,096 bytes in 1 blocks
==8795==         suppressed: 34,792 bytes in 425 blocks
==8795== Rerun with --leak-check=full to see details of leaked memory
==8795==
==8795== For counts of detected and suppressed errors, rerun with: -v
==8795== Use --track-origins=yes to see where uninitialised values come from
==8795== ERROR SUMMARY: 4 errors from 2 contexts (suppressed: 0 from 0)

It says I'm getting Conditional jump or move depends on uninitialized value(s) on ex3.c:8, but the height variable is initialized on line 6.

My guess is that this is a problem with Valgrind on Yosemite and the error is bogus, but I'm very new to C and while I'm fairly certain the code is correct, I also don't know if there might be something I'm missing.

Is it a problem with Valgrind or my code?

Community
  • 1
  • 1
Ben McCormack
  • 32,086
  • 48
  • 148
  • 223
  • The code looks fine, for what it's worth; the warnings are spurious. I have a wild hunch what's happening; if you add another character to the first format string (doesn't matter which, it's just to make the format string a multiple of 4 bytes long) and run the code again, does the first warning disappear? – Wintermute Mar 28 '15 at 01:40
  • Adding another character to the first format string didn't seem to do anything different. – Ben McCormack Mar 29 '15 at 14:51
  • Hmm...something I hadn't noticed before: Both errors come from the same line in `ex3.c`, i.e. the same `printf` call (the first). That the innermost stackframe is a `memchr` leads me to believe that it is a vectorized search for the string terminator, which reads uninitialized memory if the string is not a multiple of 4 (or possibly 8) bytes long. Including the terminator, your format strings are 19 and 21 bytes long, respectively, and the substitution of `%d` with a two-digit number doesn't change it. It makes little sense to me that one should cause valgrind to complain but not the other. – Wintermute Mar 29 '15 at 15:03
  • I'm sorry. I know this doesn't solve your problem, but it is interesting on a technical level. From a practical point of view, what it boils down to is probably that valgrind on MacOS X is still experimental, and that you're not going to get rid of those warnings easily. If I were you, I'd post this to the valgrind bug tracker, and in the meantime I'd set up a Linux VM in which to do my valgrind testing. Valgrind on Linux is reliable. – Wintermute Mar 29 '15 at 15:05

4 Answers4

9

This specific report is a false positive on Valgrind's behalf. Valgrind on Yosemite does not yet fully cover the system libraries for all corner cases and optimisations those libraries use.

The hint here is the function name _platform_memchr$VARIANT$Haswell i.e. the presence of this bug will depend on your system hardware, in this case whether you have an Intel Haswell-based CPU.

It would be great if you can report this bug per Valgrind's http://valgrind.org/support/bug_reports.html so that it can be fixed prior to the next stable Valgrind release.

Full disclosure: I'm one of the Valgrind developers who contributed patches to support OS X 10.10

e76d587d9
  • 994
  • 5
  • 14
1

you can run valgrind with the parameter to ignore library code.

Then all those (you should ignore) library error messages will go away.

from valgrind.org page: http://valgrind.org/docs/manual/manual-core.html#manual-core.suppress

The error-checking tools detect numerous problems in the system libraries, such as the C library, which come pre-installed with your OS. You can't easily fix these, but you don't want to see these errors (and yes, there are many!) So Valgrind reads a list of errors to suppress at startup. A default suppression file is created by the ./configure script when the system is built.

You can modify and add to the suppressions file at your leisure, or, better, write your own. Multiple suppression files are allowed. This is useful if part of your project contains errors you can't or don't want to fix, yet you don't want to continuously be reminded of them.

Note: By far the easiest way to add suppressions is to use the --gen-suppressions=yes option described in Core Command-line Options. This generates suppressions automatically. For best results, though, you may want to edit the output of --gen-suppressions=yes by hand, in which case it would be advisable to read through this section.

Each error to be suppressed is described very specifically, to minimise the possibility that a suppression-directive inadvertently suppresses a bunch of similar errors which you did want to see. The suppression mechanism is designed to allow precise yet flexible specification of errors to suppress.

Ben McCormack
  • 32,086
  • 48
  • 148
  • 223
user3629249
  • 16,402
  • 1
  • 16
  • 17
  • At first I thought this was working because when I ran `--gen-supression=yes`, I got 0 errors on the correct code. But then I ran it again on the _incorrect_ code and still got 0 errors. This of course isn't what I want. – Ben McCormack Mar 29 '15 at 14:51
1

Valgrind is definitely experimental on Yosemite. However I am getting different (more correct?) results running your example. I also use svn version, probably newer than you, as I updated it just before the test. The other difference is that I built it myself, didn't use brew.

==14456== Memcheck, a memory error detector
==14456== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==14456== Using Valgrind-3.11.0.SVN and LibVEX; rerun with -h for copyright info
==14456== Command: ./t1
==14456==
I am 10 years old.
I am 72 inches tall.
==14456==
==14456== HEAP SUMMARY:
==14456==     in use at exit: 38,396 bytes in 418 blocks
==14456==   total heap usage: 503 allocs, 85 frees, 44,692 bytes allocated
==14456==
==14456== LEAK SUMMARY:
==14456==    definitely lost: 0 bytes in 0 blocks
==14456==    indirectly lost: 0 bytes in 0 blocks
==14456==      possibly lost: 0 bytes in 0 blocks
==14456==    still reachable: 4,096 bytes in 1 blocks
==14456==         suppressed: 34,300 bytes in 417 blocks
==14456== Rerun with --leak-check=full to see details of leaked memory
==14456==
==14456== For counts of detected and suppressed errors, rerun with: -v
==14456== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

Update:

This is how I built valgrind (default options):

./autogen.sh
./configure
make
sudo make install

This is libc (libSystem metalibrary) version my example binary is linked against:

$ otool -L t1
t1:
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1213.0.0)

This is my clang version:

$ clang -v
Apple LLVM version 6.0 (clang-600.0.57) (based on LLVM 3.5svn)
Target: x86_64-apple-darwin14.1.0
Thread model: posix
baf
  • 4,531
  • 1
  • 21
  • 24
  • I ended up cloning from SVN and running make again and got similar results as I had gotten before. Perhaps differences in hardware is what makes a difference here? – Ben McCormack Mar 29 '15 at 14:48
  • Strange. It is rather software that matters here, not hardware. I updated my answer with some more info on my software. – baf Mar 29 '15 at 16:03
  • Though `Haswell` keyword in your error message may suggest that the `memchr` variant, that causes false positive, is hardware dependent and may be present only on your platform. – baf Mar 29 '15 at 16:27
1

Well, I can add another "it doesn't happen for me with my home-built valgrind running on Yosemite". The binary is dated 2014-11-25 and has a version "Valgrind-3.11.0.SVN". Running on the test code, I get the output:

$ valgrind --suppressions=suppressions ./ex3
==40416== Memcheck, a memory error detector
==40416== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==40416== Using Valgrind-3.11.0.SVN and LibVEX; rerun with -h for copyright info
==40416== Command: ./ex3
==40416== 
--40416-- UNKNOWN mach_msg unhandled MACH_SEND_TRAILER option
--40416-- UNKNOWN mach_msg unhandled MACH_SEND_TRAILER option (repeated 2 times)
--40416-- UNKNOWN mach_msg unhandled MACH_SEND_TRAILER option (repeated 4 times)
I am 10 years old.
I am 72 inches tall.
==40416== 
==40416== HEAP SUMMARY:
==40416==     in use at exit: 39,086 bytes in 428 blocks
==40416==   total heap usage: 511 allocs, 83 frees, 45,358 bytes allocated
==40416== 
==40416== LEAK SUMMARY:
==40416==    definitely lost: 0 bytes in 0 blocks
==40416==    indirectly lost: 0 bytes in 0 blocks
==40416==      possibly lost: 0 bytes in 0 blocks
==40416==    still reachable: 25,940 bytes in 308 blocks
==40416==         suppressed: 13,146 bytes in 120 blocks
==40416== Rerun with --leak-check=full to see details of leaked memory
==40416== 
==40416== For counts of detected and suppressed errors, rerun with: -v
==40416== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
$

My suppressions file lists 18 leaks (and no access errors) from Yosemite runtime (I'm happy to share if that'll help; it's been created over time with the --gen-suppressions=yes option). I'm running on an oldish (early-2011, 17 inch) MacBook Pro with an Intel Core i7.

I don't like the 'Unknown mach_msg' messages, but they always appear for me and they don't self-evidently stop valgrind working (it's spotted genuine problems for me, as well as not reporting errors on this code that should be working).

I think the problem you are seeing is in the system library and it is reasonable to suppress those two messages, but it is undesirable to have to do so (much like it is undesirable to have to suppress so many o/s leaks).

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278