Search code examples
c++valgrindalpine-linux

valgrind won't show stack trace


EDIT:

It seems that there is a something unsupported by valgrind with alpine ditrib. With a simple main like this :

#include <iostream>
int main() {return 0;}

valgrind return a leak :

==8== Memcheck, a memory error detector
==8== Copyright (C) 2002-2022, and GNU GPL'd, by Julian Seward et al.
==8== Using Valgrind-3.19.0-8d3c8034b8-20220411 and LibVEX; rerun with -h for copyright info
==8== Command: ./toto
==8== Parent PID: 1
==8== 
--8-- 
--8-- Valgrind options:
--8--    --track-origins=yes
--8--    --keep-debuginfo=yes
--8--    --read-inline-info=yes
--8--    --error-exitcode=1
--8--    --leak-check=full
--8--    --errors-for-leak-kinds=all
--8--    --show-leak-kinds=all
--8--    --verbose
--8--    --sigill-diagnostics=no
--8--    --log-file=valgrind-out.txt
--8-- Contents of /proc/version:
--8--   Linux version 5.10.16.3-microsoft-standard-WSL2 (oe-user@oe-host) (x86_64-msft-linux-gcc (GCC) 9.3.0, GNU ld (GNU Binutils) 2.34.0.20200220) #1 SMP Fri Apr 2 22:23:49 UTC 2021
--8-- 
--8-- Arch and hwcaps: AMD64, LittleEndian, amd64-cx16-lzcnt-rdtscp-sse3-ssse3-avx-avx2-bmi-f16c-rdrand-rdseed
--8-- Page sizes: currently 4096, max supported 4096
--8-- Valgrind library directory: /usr/libexec/valgrind
--8-- Reading syms from /src/toto
--8-- Reading syms from /lib/ld-musl-x86_64.so.1
--8--    object doesn't have a symbol table
--8-- Reading syms from /usr/libexec/valgrind/memcheck-amd64-linux
--8--    object doesn't have a dynamic symbol table
--8-- Scheduler: using generic scheduler lock implementation.
--8-- Reading suppressions file: /usr/libexec/valgrind/default.supp
==8== embedded gdbserver: reading from /tmp/vgdb-pipe-from-vgdb-to-8-by-???-on-0d65120c6746
==8== embedded gdbserver: writing to   /tmp/vgdb-pipe-to-vgdb-from-8-by-???-on-0d65120c6746
==8== embedded gdbserver: shared mem   /tmp/vgdb-pipe-shared-mem-vgdb-8-by-???-on-0d65120c6746
==8== 
==8== TO CONTROL THIS PROCESS USING vgdb (which you probably
==8== don't want to do, unless you know exactly what you're doing,
==8== or are doing some strange experiment):
==8==   /usr/libexec/valgrind/../../bin/vgdb --pid=8 ...command...
==8== 
==8== TO DEBUG THIS PROCESS USING GDB: start GDB like this
==8==   /path/to/gdb ./toto
==8== and then give GDB the following command
==8==   target remote | /usr/libexec/valgrind/../../bin/vgdb --pid=8
==8== --pid is optional if only one valgrind process is running
==8== 
--8-- Reading syms from /usr/libexec/valgrind/vgpreload_core-amd64-linux.so
--8--    object doesn't have a symbol table
--8-- Reading syms from /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so
--8--    object doesn't have a symbol table
--8-- REDIR: 0x405082f (libc.musl-x86_64.so.1:strlen) redirected to 0x48a7b10 (strlen)
--8-- REDIR: 0x40505f1 (libc.musl-x86_64.so.1:strcpy) redirected to 0x48a7b72 (strcpy)
--8-- REDIR: 0x4050534 (libc.musl-x86_64.so.1:strchr) redirected to 0x48a787c (strchr)
--8-- REDIR: 0x4050935 (libc.musl-x86_64.so.1:strncmp) redirected to 0x48a7f6a (strncmp)
--8-- REDIR: 0x40509bd (libc.musl-x86_64.so.1:strnlen) redirected to 0x48a7aea (strnlen)
--8-- REDIR: 0x4050a80 (libc.musl-x86_64.so.1:strspn) redirected to 0x48ab61a (strspn)
--8-- REDIR: 0x4050601 (libc.musl-x86_64.so.1:strcspn) redirected to 0x48ab5ba (strcspn)
--8-- Reading syms from /usr/lib/libstdc++.so.6.0.29
--8--    object doesn't have a symbol table
--8-- REDIR: 0x40509f9 (libc.musl-x86_64.so.1:strrchr) redirected to 0x48a77e9 (strrchr)
--8-- Reading syms from /usr/lib/libgcc_s.so.1
--8--    object doesn't have a symbol table
--8-- REDIR: 0x4023529 (libc.musl-x86_64.so.1:malloc) redirected to 0x48a2650 (malloc)
--8-- REDIR: 0x40505d9 (libc.musl-x86_64.so.1:strcmp) redirected to 0x48a847c (strcmp)
==8== 
==8== HEAP SUMMARY:
==8==     in use at exit: 72,704 bytes in 1 blocks
==8==   total heap usage: 1 allocs, 0 frees, 72,704 bytes allocated
==8== 
==8== Searching for pointers to 1 not-freed blocks
==8== Checked 51,200 bytes
==8== 
==8== 72,704 bytes in 1 blocks are still reachable in loss record 1 of 1
==8==    at 0x48A26D5: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==8==    by 0x4974557: ??? (in /usr/lib/libstdc++.so.6.0.29)
==8==    by 0x4059482: ??? (in /lib/ld-musl-x86_64.so.1)
==8==    by 0x409693F: ???
==8==    by 0x4A7651F: ??? (in /usr/lib/libstdc++.so.6.0.29)
==8==    by 0x1FFF000CFF: ???
==8==    by 0xB907FED: ???
==8==    by 0x5C1A2: ???
==8==    by 0xCE9F: ???
==8==    by 0x1CEAEF: ???
==8== 
==8== LEAK SUMMARY:
==8==    definitely lost: 0 bytes in 0 blocks
==8==    indirectly lost: 0 bytes in 0 blocks
==8==      possibly lost: 0 bytes in 0 blocks
==8==    still reachable: 72,704 bytes in 1 blocks
==8==         suppressed: 0 bytes in 0 blocks
==8== 
==8== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

for easy reproduction, you could use a docker file like this :

FROM alpine 
RUN apk update && apk add libstdc++ g++ make linux-headers valgrind
WORKDIR /src
CMD ["make"]

with this makefile

MAKEFLAGS += --no-print-directory
CC=g++
CFLAGS=-W -Wall -Wunused -Wshadow -Wpointer-arith -Wcast-qual -Wno-missing-braces -ansi -pedantic -std=c++20 -I/usr/local/include
LDFLAGS=-L /usr/lib/openssl/lib -L /usr/lib
EXEC_DEBUG=toto
DEBOBJDIR=./obj/debug
SRCDIR=.
SRC_FILES=$(wildcard $(SRCDIR)/*/*/*.cpp $(SRCDIR)/*/*.cpp $(SRCDIR)/*.cpp)
DEBOBJ= $(SRC_FILES:%.cpp=$(DEBOBJDIR)/%.o)
DEPS= $(DEBOBJ:.o=.d)
MEMORYCHECKER=valgrind
MEMORY_RESULT_FILE=valgrind-out.txt
VALGRIND_FLAGS=--error-exitcode=1 --leak-check=full --errors-for-leak-kinds=all --show-leak-kinds=all --verbose --sigill-diagnostics=no --log-file=$(MEMORY_RESULT_FILE)
VALGRIND_FULL_FLAGS=--track-origins=yes --keep-debuginfo=yes --read-inline-info=yes
.PHONY: all clear 

all: $(EXEC_DEBUG) fullMemoryCheck
-include $(DEPS)
$(EXEC_DEBUG): $(DEBOBJ)
    $(CC) -o $@ $^ $(LDFLAGS)
$(DEBOBJDIR)/%.o : %.cpp makefile
    @mkdir -p $(dir $@)
    $(CC) -o $@ -MP -MMD -c $< $(CFLAGS) -g
clean: 
    find $(DEBOBJDIR) -name "*.o" -type f -delete
    find $(DEBOBJDIR) -name "*.d" -type f -delete
clear: clean
    rm -rf $(EXEC) $(EXEC_DEBUG)
fullMemoryCheck: $(EXEC_DEBUG)
    @export GLIBCXX_FORCE_NEW
    $(MEMORYCHECKER) $(VALGRIND_FULL_FLAGS) $(VALGRIND_FLAGS) ./$(EXEC_DEBUG)

As @Paul Floyd mention it, there is an existing bug declare here : https://bugs.kde.org/show_bug.cgi?id=426751 but without known issue. So I had my exemple to help finding what is unsupported in alpine (lib musl libc).

PS : the problem come from iostream, because it disapear if I comment the include.

OLD VERSION:

after lot of searches I can't find a way to see the stack strace for a "leak" (still reachable) in my code. As I can read in the documentation I add some option to valgrind "--track-origins=yes --keep-debuginfo=yes --read-inline-info=yes" but it doesn't help me.

My compilation lines looks like this (with -g3) :

g++ -o obj/debug/./src/file1.o -MP -MMD -c src/file1.cpp -W -Wall -Wunused -Wshadow -Wpointer-arith -Wcast-qual -Wno-missing-braces -ansi -pedantic -std=c++20 -I/usr/local/include -DRAPIDJSON_HAS_STDSTRING -g3
g++ -o obj/debug/./src/file2.o -MP -MMD -c src/file2.cpp -W -Wall -Wunused -Wshadow -Wpointer-arith -Wcast-qual -Wno-missing-braces -ansi -pedantic -std=c++20 -I/usr/local/include -DRAPIDJSON_HAS_STDSTRING -g3
g++ -o obj/debug/./src/file3.o -MP -MMD -c src/file3.cpp -W -Wall -Wunused -Wshadow -Wpointer-arith -Wcast-qual -Wno-missing-braces -ansi -pedantic -std=c++20 -I/usr/local/include -DRAPIDJSON_HAS_STDSTRING -g3
...
g++ -o obj/debug/./src/fileX.o -MP -MMD -c src/fileX.cpp -W -Wall -Wunused -Wshadow -Wpointer-arith -Wcast-qual -Wno-missing-braces -ansi -pedantic -std=c++20 -I/usr/local/include -DRAPIDJSON_HAS_STDSTRING -g3
g++ -o obj/debug/./src/main.o -MP -MMD -c src/main.cpp -W -Wall -Wunused -Wshadow -Wpointer-arith -Wcast-qual -Wno-missing-braces -ansi -pedantic -std=c++20 -I/usr/local/include -DRAPIDJSON_HAS_STDSTRING -g3
g++ -o botsd obj/debug/./src/file1.o obj/debug/./src/file2.o obj/debug/./src/file3.o obj/debug/./src/fileX.o obj/debug/./src/main.o -L /usr/lib/openssl/lib -L /usr/lib -llog4cplus -lpthread -lssl -lcrypto -lcurl
g++ -c -g3 -I. -I.. -std=c++20  -I/usr/include -I./cxxtest-4.4/ -DCXXTEST_RUNNING -DRAPIDJSON_HAS_STDSTRING -o output/OutputTrace.o ../src/cmdLine/OutputTrace.cpp
python3 cxxtest-4.4/bin/cxxtestgen -o output/testMemory.cpp --error-printer testFile1.h testFile2.h testFile3.h ... testFileX.h
g++ -c -g3 -I. -I.. -std=c++20  -I/usr/include -I./cxxtest-4.4/ -DCXXTEST_RUNNING -DRAPIDJSON_HAS_STDSTRING output/testMemory.cpp -o output/testMemory.o
g++ -Wall -g3 -I. -I.. output/testMemory.o ../obj/debug/src/file1.o ../obj/debug/src/file2.o ../obj/debug/src/file3.o ... ../obj/debug/src/fileX.o -L /usr/lib/openssl/lib -L /usr/lib -llog4cplus -lpthread -lssl -lcrypto -lcurl -o output/testMemory

Extract from my primary makefile :

MAKEFLAGS += --no-print-directory
CC=g++
CPPCHECK=cppcheck
CFLAGS=-W -Wall -Wunused -Wshadow -Wpointer-arith -Wcast-qual -Wno-missing-braces -ansi -pedantic -std=c++20 -I/usr/local/include -DRAPIDJSON_HAS_STDSTRING
LDFLAGS=-L /usr/lib/openssl/lib -L /usr/lib -llog4cplus -lpthread -lssl -lcrypto -lcurl 
EXEC_DEBUG=test
DEBOBJDIR=./obj/debug
SRCDIR=./src
TESTDIR=./tests
SRC=$(wildcard $(SRCDIR)/*/*/*.cpp $(SRCDIR)/*/*.cpp $(SRCDIR)/*.cpp)
DEBOBJ= $(SRC:%.cpp=$(DEBOBJDIR)/%.o)
DEPS= $(DEBOBJ:.o=.d)

.PHONY: all clean clear 

all: $(EXEC_DEBUG) run-tests

-include $(DEPS)

$(EXEC_DEBUG): $(DEBOBJ)
    $(CC) -o $@ $^ $(LDFLAGS)

$(DEBOBJDIR)/%.o : %.cpp makefile
    @mkdir -p $(dir $@)
    $(CC) -o $@ -MP -MMD -c $< $(CFLAGS) -g3
    
test-clean:
    +@cd $(TESTDIR) && make clean

clean: test-clean
    find $(DEBOBJDIR) -name "*.o" -type f -delete
    find $(DEBOBJDIR) -name "*.d" -type f -delete

clear: clean
    rm -rf $(EXEC_DEBUG)
    
run-tests: $(EXEC_DEBUG)
    +@cd $(TESTDIR) && make

fullMemoryCheck: $(EXEC_DEBUG)
    +@cd $(TESTDIR) && make fullMemoryCheck

And then I launch Valgrind like this (I think GLIBCXX_FORCE_NEW is useless but I try a lot of things :) )

export GLIBCXX_FORCE_NEW
valgrind --track-origins=yes --keep-debuginfo=yes --read-inline-info=yes --error-exitcode=1 --leak-check=full --errors-for-leak-kinds=all --show-leak-kinds=all --verbose --sigill-diagnostics=no --log-file=valgrind-out.txt ./output/testMemory

see from my secondary (test) makefile :

CXXC = g++ -Wall -g3 -I. -I..
CC = g++ -c -g3 -I. -I.. -std=c++20  -I/usr/include -I./cxxtest-4.4/ -DCXXTEST_RUNNING -DRAPIDJSON_HAS_STDSTRING
LDFLAGS=-L /usr/lib/openssl/lib -L /usr/lib -llog4cplus -lpthread -lssl -lcrypto -lcurl 
TESTGEN=cxxtest-4.4/bin/cxxtestgen
MEMORYCHECKER=valgrind
MEMORY_RESULT_FILE=valgrind-out.txt
VALGRIND_FLAGS=--error-exitcode=1 --leak-check=full --errors-for-leak-kinds=all --show-leak-kinds=all --verbose --sigill-diagnostics=no --log-file=$(MEMORY_RESULT_FILE)
VALGRIND_FULL_FLAGS=--track-origins=yes --keep-debuginfo=yes --read-inline-info=yes
TARGETS=error_printer
VALGRIND_TARGET=testMemory
OUTDIR=output
OBJDIR=../obj/debug/src
TST_FILES=$(wildcard */*/*.h */*.h)
TSTFILES= $(filter-out $(wildcard cxxtest*/*/*), $(TST_FILES))
NOPERFFILES= $(filter-out $(wildcard */Perf*.h), $(TSTFILES))
NO_PERF_FILES= $(filter-out $(wildcard */*/Perf*.h), $(NOPERFFILES))
OBJ_FILES=$(wildcard $(OBJDIR)/*/*/*.o $(OBJDIR)/*/*.o)
ADDITIONNAL_SRC=../src/cmdLine/OutputTrace.cpp
EXCLUDE_OBJ=$(subst ../,../obj/debug/,$(ADDITIONNAL_SRC:%.cpp=%.o))
ADDITIONNAL_OBJ=$(OUTDIR)/$(addsuffix .o,$(basename $(notdir $(ADDITIONNAL_SRC))))
FINAL_OBJ=$(filter-out $(EXCLUDE_OBJ), $(OBJ_FILES))

.PHONY: all clean distclean fullMemoryCheck

all: run memoryCheck

clean:
    rm -f $(OUTDIR)/*
 
distclean: clean
    rm -f Makefile
 
memoryCheck: $(VALGRIND_TARGET)
    @export GLIBCXX_FORCE_NEW
    @if $(MEMORYCHECKER) $(VALGRIND_FLAGS) ./$(OUTDIR)/$(VALGRIND_TARGET); then \
        echo " Memory is clear!"; \
    else \
        cat $(MEMORY_RESULT_FILE); \
        exit "Memory problems found"; \
    fi

fullMemoryCheck: $(VALGRIND_TARGET)
    @export GLIBCXX_FORCE_NEW
    $(MEMORYCHECKER) $(VALGRIND_FULL_FLAGS) $(VALGRIND_FLAGS) ./$(OUTDIR)/$(VALGRIND_TARGET)

run: $(TARGETS)
    @./$(OUTDIR)/$(TARGETS)

$(ADDITIONNAL_OBJ): $(ADDITIONNAL_SRC)
    @mkdir -p $(dir $@)
    $(CC) -o $@ $<
 
$(TARGETS).cpp: $(TSTFILES)
    python3 $(TESTGEN) -o $(OUTDIR)/$@ --error-printer $(TSTFILES)
 
$(TARGETS).o: $(TARGETS).cpp
    $(CC) $(OUTDIR)/$(TARGETS).cpp -o $(OUTDIR)/$(TARGETS).o
 
$(TARGETS): $(ADDITIONNAL_OBJ) $(TARGETS).o
    $(CXXC) $(OUTDIR)/$(TARGETS).o $(ADDITIONNAL_OBJ) $(FINAL_OBJ) $(LDFLAGS) -o $(OUTDIR)/$(TARGETS)
    
$(VALGRIND_TARGET).cpp: $(NO_PERF_FILES)
    python3 $(TESTGEN) -o $(OUTDIR)/$@ --error-printer $(NO_PERF_FILES)
 
$(VALGRIND_TARGET).o: $(VALGRIND_TARGET).cpp
    $(CC) $(OUTDIR)/$(VALGRIND_TARGET).cpp -o $(OUTDIR)/$(VALGRIND_TARGET).o
 
$(VALGRIND_TARGET): $(ADDITIONNAL_OBJ) $(VALGRIND_TARGET).o
    $(CXXC) $(OUTDIR)/$(VALGRIND_TARGET).o $(ADDITIONNAL_OBJ) $(FINAL_OBJ) $(LDFLAGS) -o $(OUTDIR)/$(VALGRIND_TARGET)

I had to add --sigill-diagnostics=no to avoid an error with openSSL which use SIGKILL (cf https://bugzilla.redhat.com/show_bug.cgi?id=1495320)

and the output is now just one "leak" :

==255== Memcheck, a memory error detector
==255== Copyright (C) 2002-2022, and GNU GPL'd, by Julian Seward et al.
==255== Using Valgrind-3.19.0-8d3c8034b8-20220411 and LibVEX; rerun with -h for copyright info
==255== Command: ./output/testMemory
==255== Parent PID: 246
==255== 
--255-- 
--255-- Valgrind options:
--255--    --track-origins=yes
--255--    --keep-debuginfo=yes
--255--    --read-inline-info=yes
--255--    --error-exitcode=1
--255--    --leak-check=full
--255--    --errors-for-leak-kinds=all
--255--    --show-leak-kinds=all
--255--    --verbose
--255--    --sigill-diagnostics=no
--255--    --log-file=valgrind-out.txt
--255-- Contents of /proc/version:
--255--   Linux version 5.10.16.3-microsoft-standard-WSL2 (oe-user@oe-host) (x86_64-msft-linux-gcc (GCC) 9.3.0, GNU ld (GNU Binutils) 2.34.0.20200220) #1 SMP Fri Apr 2 22:23:49 UTC 2021
--255-- 
--255-- Arch and hwcaps: AMD64, LittleEndian, amd64-cx16-lzcnt-rdtscp-sse3-ssse3-avx-avx2-bmi-f16c-rdrand-rdseed
--255-- Page sizes: currently 4096, max supported 4096
--255-- Valgrind library directory: /usr/libexec/valgrind
--255-- Reading syms from /src/tests/output/testMemory
--255-- Reading syms from /lib/ld-musl-x86_64.so.1
--255--    object doesn't have a symbol table
--255-- Reading syms from /usr/libexec/valgrind/memcheck-amd64-linux
--255--    object doesn't have a dynamic symbol table
--255-- Scheduler: using generic scheduler lock implementation.
--255-- Reading suppressions file: /usr/libexec/valgrind/default.supp
==255== embedded gdbserver: reading from /tmp/vgdb-pipe-from-vgdb-to-255-by-???-on-91ae10bb5054
==255== embedded gdbserver: writing to   /tmp/vgdb-pipe-to-vgdb-from-255-by-???-on-91ae10bb5054
==255== embedded gdbserver: shared mem   /tmp/vgdb-pipe-shared-mem-vgdb-255-by-???-on-91ae10bb5054
==255== 
==255== TO CONTROL THIS PROCESS USING vgdb (which you probably
==255== don't want to do, unless you know exactly what you're doing,
==255== or are doing some strange experiment):
==255==   /usr/libexec/valgrind/../../bin/vgdb --pid=255 ...command...
==255== 
==255== TO DEBUG THIS PROCESS USING GDB: start GDB like this
==255==   /path/to/gdb ./output/testMemory
==255== and then give GDB the following command
==255==   target remote | /usr/libexec/valgrind/../../bin/vgdb --pid=255
==255== --pid is optional if only one valgrind process is running
==255== 
--255-- Reading syms from /usr/libexec/valgrind/vgpreload_core-amd64-linux.so
--255--    object doesn't have a symbol table
--255-- Reading syms from /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so
--255--    object doesn't have a symbol table
--255-- REDIR: 0x405082f (libc.musl-x86_64.so.1:strlen) redirected to 0x48a7b10 (strlen)
--255-- REDIR: 0x40505f1 (libc.musl-x86_64.so.1:strcpy) redirected to 0x48a7b72 (strcpy)
--255-- REDIR: 0x4050534 (libc.musl-x86_64.so.1:strchr) redirected to 0x48a787c (strchr)
--255-- REDIR: 0x4050935 (libc.musl-x86_64.so.1:strncmp) redirected to 0x48a7f6a (strncmp)
--255-- REDIR: 0x4050a80 (libc.musl-x86_64.so.1:strspn) redirected to 0x48ab61a (strspn)
--255-- REDIR: 0x4050601 (libc.musl-x86_64.so.1:strcspn) redirected to 0x48ab5ba (strcspn)
--255-- REDIR: 0x40509bd (libc.musl-x86_64.so.1:strnlen) redirected to 0x48a7aea (strnlen)
--255-- Reading syms from /usr/lib/liblog4cplus-2.0.so.3.4.6
--255--    object doesn't have a symbol table
--255-- REDIR: 0x40509f9 (libc.musl-x86_64.so.1:strrchr) redirected to 0x48a77e9 (strrchr)
--255-- Reading syms from /usr/lib/openssl/lib/libcrypto.so.3
--255-- Reading syms from /usr/local/lib/librestclient-cpp.so.1.1.1
--255-- Reading syms from /usr/lib/libstdc++.so.6.0.29
--255--    object doesn't have a symbol table
--255-- Reading syms from /usr/lib/libgcc_s.so.1
--255--    object doesn't have a symbol table
--255-- Reading syms from /usr/local/lib/libcurl.so.4.8.0
--255-- Reading syms from /usr/lib/openssl/lib/libssl.so.3
--255-- REDIR: 0x4023529 (libc.musl-x86_64.so.1:malloc) redirected to 0x48a2650 (malloc)
--255-- REDIR: 0x4e5c68e (libstdc++.so.6:operator new(unsigned long)) redirected to 0x48a2de0 (operator new(unsigned long))
--255-- REDIR: 0x40505d9 (libc.musl-x86_64.so.1:strcmp) redirected to 0x48a847c (strcmp)
--255-- REDIR: 0x404ff8d (libc.musl-x86_64.so.1:memcmp) redirected to 0x48a9ff3 (memcmp)
--255-- REDIR: 0x4050544 (libc.musl-x86_64.so.1:strchrnul) redirected to 0x48aaf8d (strchrnul)
--255-- REDIR: 0x4e5ae18 (libstdc++.so.6:operator delete(void*, unsigned long)) redirected to 0x48a51f4 (operator delete(void*, unsigned long))
--255-- REDIR: 0x4e5c70e (libstdc++.so.6:operator new[](unsigned long)) redirected to 0x48a3dc4 (operator new[](unsigned long))
--255-- REDIR: 0x404fefe (libc.musl-x86_64.so.1:memchr) redirected to 0x48a8542 (memchr)
--255-- REDIR: 0x4e5ae2a (libstdc++.so.6:operator delete[](void*)) redirected to 0x48a5e80 (operator delete[](void*))
--255-- REDIR: 0x4023460 (libc.musl-x86_64.so.1:free) redirected to 0x48a4a8a (free)
--255-- REDIR: 0x402519f (libc.musl-x86_64.so.1:realloc) redirected to 0x48a6e29 (realloc)
--255-- REDIR: 0x40233a1 (libc.musl-x86_64.so.1:calloc) redirected to 0x48a6b5a (calloc)
--255-- REDIR: 0x4e5ae0f (libstdc++.so.6:operator delete(void*)) redirected to 0x48a4fac (operator delete(void*))
--255-- REDIR: 0x4050d40 (libc.musl-x86_64.so.1:strstr) redirected to 0x48ab4a4 (strstr)
--255-- REDIR: 0x4050972 (libc.musl-x86_64.so.1:strncpy) redirected to 0x48a7cae (strncpy)
--255-- memcheck GC: 1000 nodes, 315 survivors (31.5%)
--255-- memcheck GC: 1014 new table size (driftup)
==255== 
==255== HEAP SUMMARY:
==255==     in use at exit: 72,704 bytes in 1 blocks
==255==   total heap usage: 9,136,810 allocs, 9,136,809 frees, 369,272,065 bytes allocated
==255== 
==255== Searching for pointers to 1 not-freed blocks
==255== Checked 134,080 bytes
==255== 
==255== 72,704 bytes in 1 blocks are still reachable in loss record 1 of 1
==255==    at 0x48A26D5: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==255==    by 0x4E59557: ??? (in /usr/lib/libstdc++.so.6.0.29)
==255==    by 0x4059D8A: ??? (in /lib/ld-musl-x86_64.so.1)
==255==    by 0x409693F: ???
==255==    by 0x4F5B51F: ??? (in /usr/lib/libstdc++.so.6.0.29)
==255==    by 0xB907FED: ???
==255==    by 0x5C1A2: ???
==255==    by 0xCE9F: ???
==255==    by 0x1CEAEF: ??? (in /src/tests/output/testMemory)
==255== 
==255== LEAK SUMMARY:
==255==    definitely lost: 0 bytes in 0 blocks
==255==    indirectly lost: 0 bytes in 0 blocks
==255==      possibly lost: 0 bytes in 0 blocks
==255==    still reachable: 72,704 bytes in 1 blocks
==255==         suppressed: 0 bytes in 0 blocks
==255== 
==255== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

I can add that I run this in a docker container based on alpine 3.16.2 (with valgrind, g++, etc...)

For people who knew it, it's a program ran with cxxtest (v4.4). But it shouldn't impact because all sources files are compiled like mine and are in my program folders. So valgrind should found symbols (there are part of lotOfFiles.h and lotOfFiles.cpp)

So my question is : what I can add to help valgrind finding symbols ? (obviously I don't want details from libstdc++, but just a clue in my code)


Solution

  • Not a great answer but a trick to avoid this problem. For now (until valgrind will fix this bug), I create a suppression file with this :

    {
       default_iostream
       Memcheck:Leak
       match-leak-kinds: reachable
       fun:malloc
       obj:/usr/lib/libstdc++.so.6.0.29
       obj:/lib/ld-musl-x86_64.so.1
       obj:*
       obj:/usr/lib/libstdc++.so.6.0.29
       obj:*
       obj:*
       ...
    }
    

    And it hide the problem because valgrind will not report the fake error