@@ -28,6 +28,7 @@ where the value inside the `==` is the `pid` of your program. The rest of the me
If you're using `memcheck`, then you will get lots of messages at the end, relating to memory leaks. The following information (more info at [FAQ](https://valgrind.org/docs/manual/faq.html)) might be useful:
==3208576== by 0x7C1FFBB7: CaloClusterMaker::execute(EventContext const&) const (CaloClusterMaker.cxx:164)
==3208576== by 0x3DE924AF: Gaudi::Algorithm::sysExecute(EventContext const&) (in /cvmfs/atlas-nightlies.cern.ch/repo/sw/main--dev4LCG_Athena_x86_64-el9-gcc13-opt/2025-01-29T0815/AthenaExternals/25.0.25/InstallArea/x86_64-el9-gcc13-opt/lib/libGaudiKernel.so)
==3208576== by 0x7A2507EE: AthSequencer::executeAlgorithm(Gaudi::Algorithm*, EventContext const&) const (in /cvmfs/atlas-nightlies.cern.ch/repo/sw/main--dev4LCG_Athena_x86_64-el9-gcc13-opt/2025-01-29T0815/Athena/25.0.25/InstallArea/x86_64-el9-gcc13-opt/lib/libGaudiSequencer.so)
==3208576== by 0x7A250BE5: AthSequencer::execute(EventContext const&) const (in /cvmfs/atlas-nightlies.cern.ch/repo/sw/main--dev4LCG_Athena_x86_64-el9-gcc13-opt/2025-01-29T0815/Athena/25.0.25/InstallArea/x86_64-el9-gcc13-opt/lib/libGaudiSequencer.so)
==3208576== by 0x3DE924AF: Gaudi::Algorithm::sysExecute(EventContext const&) (in /cvmfs/atlas-nightlies.cern.ch/repo/sw/main--dev4LCG_Athena_x86_64-el9-gcc13-opt/2025-01-29T0815/AthenaExternals/25.0.25/InstallArea/x86_64-el9-gcc13-opt/lib/libGaudiKernel.so)
==3208576== by 0x7A2507EE: AthSequencer::executeAlgorithm(Gaudi::Algorithm*, EventContext const&) const (in /cvmfs/atlas-nightlies.cern.ch/repo/sw/main--dev4LCG_Athena_x86_64-el9-gcc13-opt/2025-01-29T0815/Athena/25.0.25/InstallArea/x86_64-el9-gcc13-opt/lib/libGaudiSequencer.so)
==3208576== by 0x7A250BE5: AthSequencer::execute(EventContext const&) const (in /cvmfs/atlas-nightlies.cern.ch/repo/sw/main--dev4LCG_Athena_x86_64-el9-gcc13-opt/2025-01-29T0815/Athena/25.0.25/InstallArea/x86_64-el9-gcc13-opt/lib/libGaudiSequencer.so)
==3208576== by 0x3DE924AF: Gaudi::Algorithm::sysExecute(EventContext const&) (in /cvmfs/atlas-nightlies.cern.ch/repo/sw/main--dev4LCG_Athena_x86_64-el9-gcc13-opt/2025-01-29T0815/AthenaExternals/25.0.25/InstallArea/x86_64-el9-gcc13-opt/lib/libGaudiKernel.so)
==3208576== by 0x7A2507EE: AthSequencer::executeAlgorithm(Gaudi::Algorithm*, EventContext const&) const (in /cvmfs/atlas-nightlies.cern.ch/repo/sw/main--dev4LCG_Athena_x86_64-el9-gcc13-opt/2025-01-29T0815/Athena/25.0.25/InstallArea/x86_64-el9-gcc13-opt/lib/libGaudiSequencer.so)
==3208576== by 0x7A250BE5: AthSequencer::execute(EventContext const&) const (in /cvmfs/atlas-nightlies.cern.ch/repo/sw/main--dev4LCG_Athena_x86_64-el9-gcc13-opt/2025-01-29T0815/Athena/25.0.25/InstallArea/x86_64-el9-gcc13-opt/lib/libGaudiSequencer.so)
==3208576== by 0x3DE924AF: Gaudi::Algorithm::sysExecute(EventContext const&) (in /cvmfs/atlas-nightlies.cern.ch/repo/sw/main--dev4LCG_Athena_x86_64-el9-gcc13-opt/2025-01-29T0815/AthenaExternals/25.0.25/InstallArea/x86_64-el9-gcc13-opt/lib/libGaudiKernel.so)
==3208576== by 0x7A2507EE: AthSequencer::executeAlgorithm(Gaudi::Algorithm*, EventContext const&) const (in /cvmfs/atlas-nightlies.cern.ch/repo/sw/main--dev4LCG_Athena_x86_64-el9-gcc13-opt/2025-01-29T0815/Athena/25.0.25/InstallArea/x86_64-el9-gcc13-opt/lib/libGaudiSequencer.so)
==3208576== by 0x7A250BE5: AthSequencer::execute(EventContext const&) const (in /cvmfs/atlas-nightlies.cern.ch/repo/sw/main--dev4LCG_Athena_x86_64-el9-gcc13-opt/2025-01-29T0815/Athena/25.0.25/InstallArea/x86_64-el9-gcc13-opt/lib/libGaudiSequencer.so)
==3208576== by 0x3DE924AF: Gaudi::Algorithm::sysExecute(EventContext const&) (in /cvmfs/atlas-nightlies.cern.ch/repo/sw/main--dev4LCG_Athena_x86_64-el9-gcc13-opt/2025-01-29T0815/AthenaExternals/25.0.25/InstallArea/x86_64-el9-gcc13-opt/lib/libGaudiKernel.so)
==3208576== by 0x40D7D5BE: AthenaEventLoopMgr::executeAlgorithms(EventContext const&) (in /cvmfs/atlas-nightlies.cern.ch/repo/sw/main--dev4LCG_Athena_x86_64-el9-gcc13-opt/2025-01-29T0815/Athena/25.0.25/InstallArea/x86_64-el9-gcc13-opt/lib/libAthenaServices.so)
==3208576== by 0x40D85406: AthenaEventLoopMgr::executeEvent(EventContext&&) (in /cvmfs/atlas-nightlies.cern.ch/repo/sw/main--dev4LCG_Athena_x86_64-el9-gcc13-opt/2025-01-29T0815/Athena/25.0.25/InstallArea/x86_64-el9-gcc13-opt/lib/libAthenaServices.so)
==3208576== by 0x40D83151: AthenaEventLoopMgr::nextEvent(int) (in /cvmfs/atlas-nightlies.cern.ch/repo/sw/main--dev4LCG_Athena_x86_64-el9-gcc13-opt/2025-01-29T0815/Athena/25.0.25/InstallArea/x86_64-el9-gcc13-opt/lib/libAthenaServices.so)
==3208576== by 0x40D7E7DC: AthenaEventLoopMgr::executeRun(int) (in /cvmfs/atlas-nightlies.cern.ch/repo/sw/main--dev4LCG_Athena_x86_64-el9-gcc13-opt/2025-01-29T0815/Athena/25.0.25/InstallArea/x86_64-el9-gcc13-opt/lib/libAthenaServices.so)
==3208576== by 0x40820304: ApplicationMgr::executeRun(int) (in /cvmfs/atlas-nightlies.cern.ch/repo/sw/main--dev4LCG_Athena_x86_64-el9-gcc13-opt/2025-01-29T0815/AthenaExternals/25.0.25/InstallArea/x86_64-el9-gcc13-opt/lib/libGaudiCoreSvc.so)
==3208576== by 0x3DEC4CF5: py_bootstrap_app_run (in /cvmfs/atlas-nightlies.cern.ch/repo/sw/main--dev4LCG_Athena_x86_64-el9-gcc13-opt/2025-01-29T0815/AthenaExternals/25.0.25/InstallArea/x86_64-el9-gcc13-opt/lib/libGaudiKernel.so)
==3208576== by 0x105B7051: ffi_call_unix64 (in /cvmfs/sft.cern.ch/lcg/releases/libffi/3.4.2-a3607/x86_64-el9-gcc13-opt/lib64/libffi.so.8.1.0)
==3208576== by 0x105B5C78: ffi_call_int (in /cvmfs/sft.cern.ch/lcg/releases/libffi/3.4.2-a3607/x86_64-el9-gcc13-opt/lib64/libffi.so.8.1.0)
==3208576== by 0x1059E0B0: _call_function_pointer (callproc.c:923)
==3208576== by 0x1059E0B0: _ctypes_callproc (callproc.c:1262)
==3208576== by 0x10598D76: PyCFuncPtr_call (_ctypes.c:4201)
==3208576== by 0x49B855C: _PyObject_MakeTpCall (call.c:214)
==3208576== by 0x495D86E: _PyEval_EvalFrameDefault (ceval.c:4769)
==3208576== by 0x4AAF753: _PyEval_EvalFrame (pycore_ceval.h:73)
==3208576== by 0x4AAF753: _PyEval_Vector (ceval.c:6434)
==3208576== by 0x4AAF753: PyEval_EvalCode (ceval.c:1148)
==3208576== by 0x4AF7DF8: run_eval_code_obj (pythonrun.c:1741)
==3208576== by 0x4AF7DF8: run_mod (pythonrun.c:1762)
```
This tells us that there is a 300 byte leak coming from `Trk::TrackSummaryTool::createSummary(Trk::Track const&)`, which was called by `InDet::PriVxTopAlg::m_preselect(Trk::Track const\*)` etc. (i.e. the last/latest call is at the top, and first at the bottom).
It might be useful to have some more detailed output - such as line numbers, for that last method. So we can check out and build just that package with debug info (see [here](https://twiki.cern.ch/twiki/bin/view/AtlasComputing/UsingDebugBuiltPackagesWithOptBuild#Rebuild_the_packages) for details on how to do this).
Now re-run ... the new output is:
This indicates a 268,656-byte memory leak originating from the function `CaloTopoClusterMaker::execute(EventContext const&, DataVector<xAOD::CaloCluster_v1, ...>*)`, which was called by `Gaudi::Algorithm::sysExecute(EventContext const&)`, and so on.
Note that the most recent call appears at the top, and the earliest at the bottom of the trace.
The default Athena build includes debug symbols, so the Valgrind output contains source line references (e.g., `CaloClusterMaker.cxx:164`).
In the example, a memory leak is caused by a `CaloProtoCluster` allocation introduced in `CaloTopoClusterMaker` but never freed:
```
CaloProtoCluster* myCluster = new CaloProtoCluster(cellCollLink);
```
==8807== 20 bytes in 1 blocks are definitely lost in loss record 242 of 2341
==8807== at 0x3414C6D6: operator new(unsigned) (vg_replace_malloc.c:133)
==8807== by 0x3EB1894B: Trk::TrackSummaryTool::createSummary(Trk::Track const&) (TrackSummaryTool.cxx:171)
==8807== by 0x3F91A769: Trk::TrackScoringTool::score(Trk::Track const&) (in /afs/cern.ch/user/e/emoyse/
auto myCluster = std::make_unique<CaloProtoCluster>(cellCollLink);
```
The answer is now clear -`extrapParameters` was never deleted. Fixing this and checking again with valgrind confirms that the bug is gone.
After applying the fix and re-running the check with Valgrind, the memory leak is confirmed to be resolved.
### Special issue with object factory design in Tracking
Especially in the tracking realm, many tools employ a cascaded object factory design pattern. That means they create an object and instead of deleting it before the method reaches the end, they give it back to the calling client, hereby passing the ownership (and responsibility to delete it or add it to StoreGate) onto the calling client, and even further on (cascade). The TrackSummaryTool in the example above is such a factory, and if it shows up in a valgrind leak report it needs some investigation to find out if the tool is 'leaking' objects internally or if the tool is working correctly but the calling client failed to take over the ownership. This investigation is complicated by the fact that often the factory tools have an internal structure with such ownership transfer, and the clients can themselves again employ a factory design to add the (potentially leaking) object onto the next bigger object. For instance, a track summary is first made (by factory, the TrackSummaryTool) and then added to a track, but the track is leaked. In such a case the developer of the TrackSummaryTool will not enjoy getting a bug report filed, for which the tool is not responsible.
@@ -27,7 +27,7 @@ There are other possibilities, such as
-`Addrcheck` - a lightweight (faster) version of `memcheck`
-`Cachegrind` - is a cache profiler
-`Callgrind` - a call graph profiler (extended version of `Cachegrind`)
* You can use this to profile only your algorithm, using [Valkyrie](https://atlas-sw-doxygen.web.cern.ch/atlas-sw-doxygen/atlas_22.0.X-DOX/docs//html/da/dcc/Valkyrie_page.html)
* You can use this to profile only your algorithm, using [Valkyrie](https://atlas-sw-doxygen.web.cern.ch/atlas-sw-doxygen/atlas_main--Doxygen/docs/html/da/dcc/Valkyrie_page.html)
-`Massif` - a heap memory profiler
-`Helgrind` - data races in multithreaded programs