Bug Summary

File:framework/utilities/src/Utils.cc
Warning:line 64, column 5
Value of 'errno' was not checked and may be overwritten by function 'fscanf'

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -O3 -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name Utils.cc -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/data/b2soft/buildbot/development/build -fcoverage-compilation-dir=/data/b2soft/buildbot/development/build -resource-dir /cvmfs/belle.cern.ch/el9/externals/v02-04-00/Linux_x86_64/common/lib/clang/21 -isystem /cvmfs/belle.cern.ch/el9/externals/v02-04-00/Linux_x86_64/common/include/c++ -isystem /cvmfs/belle.cern.ch/el9/externals/v02-04-00/Linux_x86_64/common/include/c++/x86_64-redhat-linux -isystem /cvmfs/belle.cern.ch/el9/externals/v02-04-00/Linux_x86_64/common/include/c++/backward -isystem /cvmfs/belle.cern.ch/el9/externals/v02-04-00/include -isystem /cvmfs/belle.cern.ch/el9/externals/v02-04-00/Linux_x86_64/common/include/python3.12 -isystem /cvmfs/belle.cern.ch/el9/externals/v02-04-00/include/CLHEP -isystem /cvmfs/belle.cern.ch/el9/externals/v02-04-00/Linux_x86_64/common/include/Geant4 -isystem /cvmfs/belle.cern.ch/el9/externals/v02-04-00/Linux_x86_64/common/include -isystem /cvmfs/belle.cern.ch/el9/externals/v02-04-00/include/root -isystem /cvmfs/belle.cern.ch/el9/externals/v02-04-00/include/belle_legacy -I include/ -D _PACKAGE_="framework" -D G4UI_USE_TCSH -D RaveDllExport= -D HAS_SQLITE -D HAS_CALLGRIND -D KeccakP200_excluded -D KeccakP400_excluded -D KeccakP800_excluded -I include -I /cvmfs/belle.cern.ch/el9/externals/v02-04-00/Linux_x86_64/common/include/libxml2 -internal-isystem /cvmfs/belle.cern.ch/el9/externals/v02-04-00/Linux_x86_64/common/bin/../lib64/gcc/x86_64-redhat-linux/15.2.0/../../../../include/c++ -internal-isystem /cvmfs/belle.cern.ch/el9/externals/v02-04-00/Linux_x86_64/common/bin/../lib64/gcc/x86_64-redhat-linux/15.2.0/../../../../include/c++/x86_64-redhat-linux -internal-isystem /cvmfs/belle.cern.ch/el9/externals/v02-04-00/Linux_x86_64/common/bin/../lib64/gcc/x86_64-redhat-linux/15.2.0/../../../../include/c++/backward -internal-isystem /cvmfs/belle.cern.ch/el9/externals/v02-04-00/Linux_x86_64/common/lib/clang/21/include -internal-isystem /usr/local/include -internal-isystem /cvmfs/belle.cern.ch/el9/externals/v02-04-00/Linux_x86_64/common/bin/../lib64/gcc/x86_64-redhat-linux/15.2.0/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wno-missing-braces -Wno-unused-command-line-argument -std=c++20 -fdeprecated-macro -ferror-limit 19 -fgnuc-version=4.2.1 -fno-implicit-modules -fskip-odr-check-in-gmf -fcxx-exceptions -fexceptions -vectorize-loops -vectorize-slp -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /scan_build/2026-05-31-004316-385593-1 -x c++ framework/utilities/src/Utils.cc
1/**************************************************************************
2 * basf2 (Belle II Analysis Software Framework) *
3 * Author: The Belle II Collaboration *
4 * *
5 * See git log for contributors and copyright holders. *
6 * This file is licensed under LGPL-3.0, see LICENSE.md. *
7 **************************************************************************/
8// weird bug in intel compiler and or boost::process: If we include boost
9// process intel compile fails. It seems that including sys/wait.h after
10// other c++ std:: headers triggers a weird behavior failing two static
11// asserts. We work around that by including it right away
12#include <sys/wait.h>
13
14#include <framework/utilities/Utils.h>
15
16#include <framework/gearbox/Unit.h>
17#include <framework/logging/Logger.h>
18
19#include <boost/process/v1/args.hpp>
20#include <boost/process/v1/child.hpp>
21#include <boost/process/v1/io.hpp>
22#include <boost/process/v1/pipe.hpp>
23#include <boost/process/v1/search_path.hpp>
24
25#include <sys/time.h>
26#include <unistd.h>
27
28#include <cstdio>
29#include <iomanip>
30#include <utility>
31#include <filesystem>
32
33using namespace Belle2;
34
35namespace {
36 /** get the Virtual and Resident memory size in KB
37 *
38 * This is done by reading /proc/PID/statm (kept open between calls)
39 *
40 * this is significantly faster than using TSystem::GetProcInfo()
41 *
42 * @return pair with virtual memory size in the first and resident memory
43 * size in the second entry.
44 */
45 std::pair<unsigned long, unsigned long> getStatmSize()
46 {
47 /** page size of system */
48 const static long pageSizeKb = sysconf(_SC_PAGESIZE_SC_PAGESIZE) / 1024;
49 static FILE* stream = nullptr;
50 static int pid = 0;
51 int currentPid = getpid();
52 if (currentPid != pid) {
2
Assuming 'currentPid' is not equal to 'pid'
3
Taking true branch
53 pid = currentPid;
54 std::string statm = "/proc/" + std::to_string(pid) + "/statm";
55 stream = fopen(statm.c_str(), "r");
56 // If we use buffering we might get the same value each time we read so
57 // disable buffering
58 setvbuf(stream, nullptr, _IONBF2, 0);
59 }
60 unsigned long vmSizePages{0};
61 unsigned long rssPages{0};
62 if (!stream
3.1
'stream' is non-null
) return std::make_pair(-1, -1);
4
Taking false branch
63 rewind(stream);
5
After calling 'rewind' reading 'errno' is required to find out if the call has failed
64 fscanf(stream, "%lu %lu", &vmSizePages, &rssPages);
6
Value of 'errno' was not checked and may be overwritten by function 'fscanf'
65 return std::make_pair(vmSizePages * pageSizeKb, rssPages * pageSizeKb);
66 }
67}
68
69namespace Belle2::Utils {
70
71 double getClock()
72 {
73 timespec ts;
74 clock_gettime(CLOCK_REALTIME0, &ts);
75 return (ts.tv_sec * Unit::s) + (ts.tv_nsec * Unit::ns);
76 }
77 double getCPUClock()
78 {
79 timespec ts;
80 clock_gettime(CLOCK_PROCESS_CPUTIME_ID2, &ts);
81 return (ts.tv_sec * Unit::s) + (ts.tv_nsec * Unit::ns);
82 }
83
84 unsigned long getVirtualMemoryKB()
85 {
86 return getStatmSize().first;
87 }
88
89 unsigned long getRssMemoryKB()
90 {
91 return getStatmSize().second;
1
Calling 'getStatmSize'
92 }
93
94 Timer::Timer(std::string text):
95 m_startTime(getClock()),
96 m_text(std::move(text))
97 { }
98
99 Timer::~Timer()
100 {
101 double elapsed = (getClock() - m_startTime) / Unit::ms;
102 B2INFO(m_text << " " << std::fixed << std::setprecision(3) << elapsed << " ms")do { if (Belle2::LogSystem::Instance().isLevelEnabled(Belle2::
LogConfig::c_Info, 0, "framework")) { { LogVariableStream varStream
; varStream << m_text << " " << std::fixed <<
std::setprecision(3) << elapsed << " ms"; Belle2
::LogSystem::Instance().sendMessage(Belle2::LogMessage(Belle2
::LogConfig::c_Info, std::move(varStream), "framework", __PRETTY_FUNCTION__
, "framework/utilities/src/Utils.cc", 102, 0)); }; } } while(
false)
;
103 }
104
105 std::string getCommandOutput(const std::string& command, const std::vector<std::string>& arguments,
106 bool searchPath)
107 {
108 namespace bp = boost::process::v1;
109 auto cmd = searchPath ? bp::search_path(command) : boost::filesystem::path(command);
110 bp::ipstream cmdOut;
111 bp::child child(cmd, bp::args(arguments), bp::std_in.close(), bp::std_out > cmdOut);
112 char buffer[4096];
113 std::string result;
114 while (child.running() && cmdOut.read(buffer, sizeof(buffer))) {
115 result.append(buffer, sizeof(buffer));
116 }
117 if (cmdOut.gcount()) result.append(buffer, cmdOut.gcount());
118 return result;
119 }
120}