Valgrind сообщает об ошибках для очень простой программы на C

Я изучаю C-язык из Learn C The Hard Way. Я нахожусь в упражнении 6, и пока я могу заставить его работать, valgrind много раз перегружает.

Здесь вырезанная минимальная программа из файла 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;
}

Содержимое Makefile - это просто CFLAGS=-Wall -g.

Я скомпилирую программу с помощью $ make ex6 (нет предупреждений или ошибок компилятора). Выполнение с помощью $ ./ex6 приводит к ожидаемому результату.

Когда я запускаю программу с помощью $ valgrind ./ex6, я получаю ошибки, которые я не могу решить. Здесь полный вывод:

==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)

Я нахожусь в OS X yosemite. Valgrind устанавливается через brew с помощью этой команды $ brew install valgrind --HEAD.

Итак, кто-нибудь знает, в чем проблема? Как исправить ошибки valgrind?

Ответ 1

Если программа, которую вы запускаете через Valgrind, является именно той, которую вы опубликовали в своем вопросе, она явно не имеет утечек памяти. Фактически, вы даже не используете malloc/free!

Мне кажется, что это ложные ошибки/ложные срабатывания, которые Valgrind обнаруживает на OS X (только!), аналогично что случилось с самим собой некоторое время назад.

Если у вас есть доступ к другой операционной системе, например. машина Linux, попробуйте проанализировать программу, используя Valgrind в этой системе.

EDIT: Я не пробовал это сам, так как у меня нет доступа к Mac прямо сейчас, но вы должны попробовать, что M Oehm предложил: попытаться использовать файл supressions, упомянутый в этом другом вопросе SO.

Ответ 2

Эта проблема исправлена ​​для Darwin 14.3.0 (Mac OS X 10.10.2), используя Valgrind r14960 with VEX r3124 для Xcode6.2 и Valgrind r15088 для Xcode 6.3.

Если вы используете Macports (в это время написания), sudo port install valgrind-devel предоставит вам Valgrind r14960 with VEX r3093.

Здесь моя сборка script для установки 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 

(ссылка: http://calvinx.com/2015/04/10/valgrind-on-mac-os-x-10-10-yosemite/)

Мой установленный macports valgrind находится в /opt/local/bin/valgrind.

Если я сейчас запустил

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

Я получу точно такие же ошибки, которые вы описали выше. (Используя мой objc.supp файл здесь https://gist.github.com/calvinchengx/0b1d45f67be9fdca205b)

Но если я запустил

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

Все работает так, как ожидалось, и я не получаю ошибки утечки памяти уровня системы, которые появляются.

Ответ 3

Судя по этой теме, я полагаю, что valgrind не гарантирует правильные результаты на вашей платформе. Если вы можете, попробуйте этот код на другой платформе.

Претендент либо находится в valgrid, либо в вашей реализации системы printf, обе из которых нецелесообразно исправить.

Rerun with --leak-check=full to see details of leaked memory. Это должно дать вам дополнительную информацию об утечке, которую вы испытываете. Если ничего не помогает, вы можете создать файл файл подавления, чтобы остановить отображение ошибок.