Search code examples
c++valgrindsfml

Valgrind error when loading font in SFML project


This code:

// g++ sfml.cpp -o sfml_test -lsfml-graphics -lsfml-window -lsfml-system
#include <SFML/Graphics.hpp>
#include <iostream>

int main()
{
    sf::Font font;
    if (!font.loadFromFile("font.ttf"))
    {
        std::cout << "ruh oh" << std::endl;
    }

    sf::RenderWindow window(sf::VideoMode(200, 200), "SFML works!");

    return 0;
}

...causes valgrind to report two identical errors from two contexts:

valgrind ./sfml_test
==7557==  Invalid read of size 8
==7557==    at 0x401D734: strncmp (strcmp.S:175)
==7557==    by 0x400604D: is_dst (dl-load.c:209)
==7557==    by 0x4008566: _dl_dst_count (dl-load.c:246)
==7557==    by 0x4008757: expand_dynamic_string_token (dl-load.c:388)
==7557==    by 0x40088D1: fillin_rpath.isra.0 (dl-load.c:460)
==7557==    by 0x4008BE1: decompose_rpath (dl-load.c:631)
==7557==    by 0x4009745: cache_rpath (dl-load.c:673)
==7557==    by 0x4009745: cache_rpath (dl-load.c:654)
==7557==    by 0x4009745: _dl_map_object (dl-load.c:2074)
==7557==    by 0x400DDC0: openaux (dl-deps.c:64)
==7557==    by 0x4C0CACF: _dl_catch_exception (dl-error-skeleton.c:208)
==7557==    by 0x400E138: _dl_map_object_deps (dl-deps.c:248)
==7557==    by 0x4013DAA: dl_open_worker (dl-open.c:571)
==7557==    by 0x4C0CACF: _dl_catch_exception (dl-error-skeleton.c:208)
==7557==  Address 0x5a25719 is 9 bytes inside a block of size 15 alloc'd
==7557==    at 0x483877F: malloc (vg_replace_malloc.c:307)
==7557==    by 0x401C29A: strdup (strdup.c:42)
==7557==    by 0x4008B74: decompose_rpath (dl-load.c:606)
==7557==    by 0x4009745: cache_rpath (dl-load.c:673)
==7557==    by 0x4009745: cache_rpath (dl-load.c:654)
==7557==    by 0x4009745: _dl_map_object (dl-load.c:2074)
==7557==    by 0x400DDC0: openaux (dl-deps.c:64)
==7557==    by 0x4C0CACF: _dl_catch_exception (dl-error-skeleton.c:208)
==7557==    by 0x400E138: _dl_map_object_deps (dl-deps.c:248)
==7557==    by 0x4013DAA: dl_open_worker (dl-open.c:571)
==7557==    by 0x4C0CACF: _dl_catch_exception (dl-error-skeleton.c:208)
==7557==    by 0x40138F9: _dl_open (dl-open.c:837)
==7557==    by 0x545C257: dlopen_doit (dlopen.c:66)
==7557==    by 0x4C0CACF: _dl_catch_exception (dl-error-skeleton.c:208)

When the five font loading lines are removed, valgrind reports no errors. The font file sits alongside the executable sfml_test.

The program executes correctly regardless of the errors and the fonts are loaded and usable. Any ideas on how to remove the valgrind errors?

I am on linux and cannot remember how I installed SFML. I may have just run:

sudo apt-get install libsfml-dev

I can't figure out a way to check my SFML version but it will be either 2.5/2.6.

My OS is PureOS version 10 (debian fork), my g++ version is (Debian 10.2.1-6) 10.2.1 20210110 (if that makes sense), my glibc version is 2.31.

The full valgrind output is:

==11908== Memcheck, a memory error detector
==11908== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==11908== Using Valgrind-3.16.1 and LibVEX; rerun with -h for copyright info
==11908== Command: ./sfml_test
==11908== 
==11908== Invalid read of size 8
==11908==    at 0x401D734: strncmp (strcmp.S:175)
==11908==    by 0x400604D: is_dst (dl-load.c:209)
==11908==    by 0x4008566: _dl_dst_count (dl-load.c:246)
==11908==    by 0x4008757: expand_dynamic_string_token (dl-load.c:388)
==11908==    by 0x40088D1: fillin_rpath.isra.0 (dl-load.c:460)
==11908==    by 0x4008BE1: decompose_rpath (dl-load.c:631)
==11908==    by 0x4009745: cache_rpath (dl-load.c:673)
==11908==    by 0x4009745: cache_rpath (dl-load.c:654)
==11908==    by 0x4009745: _dl_map_object (dl-load.c:2074)
==11908==    by 0x400DDC0: openaux (dl-deps.c:64)
==11908==    by 0x4C0CACF: _dl_catch_exception (dl-error-skeleton.c:208)
==11908==    by 0x400E138: _dl_map_object_deps (dl-deps.c:248)
==11908==    by 0x4013DAA: dl_open_worker (dl-open.c:571)
==11908==    by 0x4C0CACF: _dl_catch_exception (dl-error-skeleton.c:208)
==11908==  Address 0x5a25719 is 9 bytes inside a block of size 15 alloc'd
==11908==    at 0x483877F: malloc (vg_replace_malloc.c:307)
==11908==    by 0x401C29A: strdup (strdup.c:42)
==11908==    by 0x4008B74: decompose_rpath (dl-load.c:606)
==11908==    by 0x4009745: cache_rpath (dl-load.c:673)
==11908==    by 0x4009745: cache_rpath (dl-load.c:654)
==11908==    by 0x4009745: _dl_map_object (dl-load.c:2074)
==11908==    by 0x400DDC0: openaux (dl-deps.c:64)
==11908==    by 0x4C0CACF: _dl_catch_exception (dl-error-skeleton.c:208)
==11908==    by 0x400E138: _dl_map_object_deps (dl-deps.c:248)
==11908==    by 0x4013DAA: dl_open_worker (dl-open.c:571)
==11908==    by 0x4C0CACF: _dl_catch_exception (dl-error-skeleton.c:208)
==11908==    by 0x40138F9: _dl_open (dl-open.c:837)
==11908==    by 0x545C257: dlopen_doit (dlopen.c:66)
==11908==    by 0x4C0CACF: _dl_catch_exception (dl-error-skeleton.c:208)
==11908== 
==11908== Invalid read of size 8
==11908==    at 0x401D734: strncmp (strcmp.S:175)
==11908==    by 0x400604D: is_dst (dl-load.c:209)
==11908==    by 0x400861E: _dl_dst_substitute (dl-load.c:288)
==11908==    by 0x40088D1: fillin_rpath.isra.0 (dl-load.c:460)
==11908==    by 0x4008BE1: decompose_rpath (dl-load.c:631)
==11908==    by 0x4009745: cache_rpath (dl-load.c:673)
==11908==    by 0x4009745: cache_rpath (dl-load.c:654)
==11908==    by 0x4009745: _dl_map_object (dl-load.c:2074)
==11908==    by 0x400DDC0: openaux (dl-deps.c:64)
==11908==    by 0x4C0CACF: _dl_catch_exception (dl-error-skeleton.c:208)
==11908==    by 0x400E138: _dl_map_object_deps (dl-deps.c:248)
==11908==    by 0x4013DAA: dl_open_worker (dl-open.c:571)
==11908==    by 0x4C0CACF: _dl_catch_exception (dl-error-skeleton.c:208)
==11908==    by 0x40138F9: _dl_open (dl-open.c:837)
==11908==  Address 0x5a25719 is 9 bytes inside a block of size 15 alloc'd
==11908==    at 0x483877F: malloc (vg_replace_malloc.c:307)
==11908==    by 0x401C29A: strdup (strdup.c:42)
==11908==    by 0x4008B74: decompose_rpath (dl-load.c:606)
==11908==    by 0x4009745: cache_rpath (dl-load.c:673)
==11908==    by 0x4009745: cache_rpath (dl-load.c:654)
==11908==    by 0x4009745: _dl_map_object (dl-load.c:2074)
==11908==    by 0x400DDC0: openaux (dl-deps.c:64)
==11908==    by 0x4C0CACF: _dl_catch_exception (dl-error-skeleton.c:208)
==11908==    by 0x400E138: _dl_map_object_deps (dl-deps.c:248)
==11908==    by 0x4013DAA: dl_open_worker (dl-open.c:571)
==11908==    by 0x4C0CACF: _dl_catch_exception (dl-error-skeleton.c:208)
==11908==    by 0x40138F9: _dl_open (dl-open.c:837)
==11908==    by 0x545C257: dlopen_doit (dlopen.c:66)
==11908==    by 0x4C0CACF: _dl_catch_exception (dl-error-skeleton.c:208)
==11908== 
==11908== 
==11908== HEAP SUMMARY:
==11908==     in use at exit: 199,041 bytes in 2,589 blocks
==11908==   total heap usage: 28,778 allocs, 26,189 frees, 8,662,565 bytes allocated
==11908== 
==11908== LEAK SUMMARY:
==11908==    definitely lost: 0 bytes in 0 blocks
==11908==    indirectly lost: 0 bytes in 0 blocks
==11908==      possibly lost: 0 bytes in 0 blocks
==11908==    still reachable: 199,041 bytes in 2,589 blocks
==11908==         suppressed: 0 bytes in 0 blocks
==11908== Rerun with --leak-check=full to see details of leaked memory
==11908== 
==11908== For lists of detected and suppressed errors, rerun with: -s
==11908== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)

Solution

  • ==7557==    at 0x401D734: strncmp (strcmp.S:175)
    

    Memcheck should be redirecting strncmp. If it isn't then either you are using an old version of Valgrind (most likely) or you are using a libc that has a strncmp that Valgrind does not detect (less likely).

    Edit: OP added more details, using Valgrind 3.16.1 from about 7 years ago.

    Looks like this was fixed in 2019:

    Author: Mike Crowe <[email protected]>  2019-09-09 15:16:16
    Committer: Mark Wielaard <[email protected]>  2022-05-14 00:41:18
    Parent: 53dd9bd255d7add6f5a502ec9cd4895d3ed21452 (FreeBSD support, patch 9)
    Child:  4fb52a67b5650ecc3c7d90d39ab2dc67b4476505 (Cleanup of str* and mem* functions)
    Branches: master, remotes/origin/master and many more (23)
    Follows: VALGRIND_3_19_0
    Precedes: VALGRIND_3_20_0
    
        Intercept strncmp for glibc ld.so v2.28+
        
        In glibc 5aad5f617892e75d91d4c8fb7594ff35b610c042 (first released in
        v2.28) a call to strncmp was added to dl-load.c:is_dst. This causes
        valgrind to complain about glibc's highly-optimised strncmp performing
        sixteen-byte reads on short strings in ld.so. Let's intercept strncmp in
        ld.so too so we use valgrind's simple version to avoid this problem.