Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Section on how to find memory leaks in FreeCAD #43

Open
luzpaz opened this issue Apr 26, 2023 · 1 comment
Open

Section on how to find memory leaks in FreeCAD #43

luzpaz opened this issue Apr 26, 2023 · 1 comment

Comments

@luzpaz
Copy link

luzpaz commented Apr 26, 2023

FreeCAD/FreeCAD#9339 (comment)

@xtemp09
Copy link

xtemp09 commented Apr 28, 2023

I think some information is required. When a tester compiles for testing purposes, I would recommend the following gcc parameters:

cmake .. -G Ninja \
-D CMAKE_BUILD_TYPE=Debug \
-D CMAKE_INSTALL_PREFIX=/home/xtemp09/path-test/ \
\
-D CMAKE_C_FLAGS_DEBUG="-fanalyzer -g -Og"       \
-D CMAKE_CXX_FLAGS_DEBUG="-fanalyzer -g -Og"

-fanalyzer performs static analysis of the source code during compilation, increasing compilation time, but its prolix output is worth reading.
-g adds debugging information
-Og turns on non-interfering optimizations


Configuration with gcc to find memory leaks:

cmake .. -G Ninja \
-D CMAKE_BUILD_TYPE=Debug \
-D CMAKE_INSTALL_PREFIX=/home/xtemp09/path-test/ \
\
-D CMAKE_C_FLAGS_DEBUG="-g -fno-omit-frame-pointer -fsanitize=leak"   \
-D CMAKE_CXX_FLAGS_DEBUG="-g -fno-omit-frame-pointer -fsanitize=leak"

In some cases stack trace information can be cut. -fno-omit-frame-pointer gives the uncut output of sanitizer's report.

I recommend to launch FreeCAD with the following command:

./FreeCAD > leak-report.txt 2>&1

It redirects output to leak-report.txt.

Corresponding clang-16 configuration
cmake .. -G Ninja \
-D CMAKE_BUILD_TYPE=Debug \
-D CMAKE_INSTALL_PREFIX=/home/xtemp09/path-test/ \
\
-D CMAKE_C_COMPILER=clang -D CMAKE_CXX_COMPILER=clang++                   \
-D CMAKE_C_FLAGS_DEBUG="-glldb -fno-omit-frame-pointer -fsanitize=leak"   \
-D CMAKE_CXX_FLAGS_DEBUG="-glldb -fno-omit-frame-pointer -fsanitize=leak" \
\
-D LINK_FLAGS_DEBUG="-fsanitize=leak -fuse-ld=lld"                        \
\
-D CMAKE_AR=/usr/lib/llvm-16/bin/llvm-ar               \
-D CMAKE_ADDR2LINE=/usr/lib/llvm-16/bin/llvm-addr2line \
-D CMAKE_MT=/usr/lib/llvm-16/bin/llvm-mt               \
-D CMAKE_NM=/usr/lib/llvm-16/bin/llvm-nm               \
-D CMAKE_OBJCOPY=/usr/lib/llvm-16/bin/llvm-objcopy     \
-D CMAKE_OBJDUMP=/usr/lib/llvm-16/bin/llvm-objdump     \
-D CMAKE_RANLIB=/usr/lib/llvm-16/bin/llvm-ranlib       \
-D CMAKE_READELF=/usr/lib/llvm-16/bin/llvm-readelf     \
-D CMAKE_RC_COMPILER=/usr/lib/llvm-16/bin/llvm-rc      \
-D CMAKE_STRIP=/usr/lib/llvm-16/bin/llvm-strip
  • Note that -fsanitize=leak is set twice, in compilation and linking flags
  • -fuse-ld=lld sets lld instead of ld. I use mold.
  • Also note that I set -glldb, because I intend to use lldb here (-glldb sets -g automatically)
  • -D CMAKE_AR is required, the lines below it, probably, are not.

Address sanitizer also detects memory leaks by default. One can set

cmake .. -G Ninja \
-D CMAKE_BUILD_TYPE=Debug \
-D CMAKE_INSTALL_PREFIX=/home/xtemp09/fc-test/ \
\
-D CMAKE_C_FLAGS_DEBUG="-g -fno-omit-frame-pointer -fvar-tracking -fsanitize=address"   \
-D CMAKE_CXX_FLAGS_DEBUG="-g -fno-omit-frame-pointer -fvar-tracking -fsanitize=address"

-fvar-tracking gives better debug information when it comes to variables.

FreeCAD will crash on start because of alloc/dealloc mismatch, so one should run FreeCAD with the command:

ASAN_OPTIONS=alloc_dealloc_mismatch=0 ./FreeCAD
Corresponding clang-16 configuration
cmake .. -G Ninja \
-D CMAKE_BUILD_TYPE=Debug \
-D CMAKE_INSTALL_PREFIX=/home/xtemp09/fc-test/ \
\
-D CMAKE_C_COMPILER=clang -D CMAKE_CXX_COMPILER=clang++     \
-D CMAKE_C_FLAGS_DEBUG="-glldb -fno-omit-frame-pointer -fsanitize=address -Xclang -fexperimental-assignment-tracking"   \
-D CMAKE_CXX_FLAGS_DEBUG="-glldb -fno-omit-frame-pointer -fsanitize=address -Xclang -fexperimental-assignment-tracking" \
\
-D LINK_FLAGS_DEBUG="-fsanitize=address -fuse-ld=lld"  \
\
-D CMAKE_AR=/usr/lib/llvm-16/bin/llvm-ar               \
-D CMAKE_ADDR2LINE=/usr/lib/llvm-16/bin/llvm-addr2line \
-D CMAKE_MT=/usr/lib/llvm-16/bin/llvm-mt               \
-D CMAKE_NM=/usr/lib/llvm-16/bin/llvm-nm               \
-D CMAKE_OBJCOPY=/usr/lib/llvm-16/bin/llvm-objcopy     \
-D CMAKE_OBJDUMP=/usr/lib/llvm-16/bin/llvm-objdump     \
-D CMAKE_RANLIB=/usr/lib/llvm-16/bin/llvm-ranlib       \
-D CMAKE_READELF=/usr/lib/llvm-16/bin/llvm-readelf     \
-D CMAKE_RC_COMPILER=/usr/lib/llvm-16/bin/llvm-rc      \
-D CMAKE_STRIP=/usr/lib/llvm-16/bin/llvm-strip

If one pursues memory leaks, he should avoid -Og option, since it impedes detection. Compiler optimizes the final binary, fixing some memory leaks or making them undetectable.

If one has interest in Python, he can link against the debug version of libpython

-D PYTHON_LIBRARY_DEBUG=/usr/lib/x86_64-linux-gnu/libpython3.10d.so

In this case FreeCAD crashes more frequent and ASAN_OPTIONS=alloc_dealloc_mismatch=0 won't help.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants