Bug Summary

File:build/../torch/csrc/serialization.cpp
Warning:line 45, column 19
PyObject ownership leak with reference count of 1

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name serialization.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -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 -analyzer-output=html -analyzer-checker=python -analyzer-disable-checker=deadcode -analyzer-config prune-paths=true,suppress-c++-stdlib=true,suppress-inlined-defensive-checks=false,suppress-null-return-paths=false,crosscheck-with-z3=true,model-path=/opt/pyrefcon/lib/pyrefcon/models/models -analyzer-config experimental-enable-naive-ctu-analysis=true,ctu-dir=/tmp/pyrefcon/pytorch/csa-scan,ctu-index-name=/tmp/pyrefcon/pytorch/csa-scan/externalDefMap.txt,ctu-invocation-list=/tmp/pyrefcon/pytorch/csa-scan/invocations.yaml,display-ctu-progress=false -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=none -relaxed-aliasing -fno-rounding-math -ffp-exception-behavior=ignore -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/tmp/pyrefcon/pytorch/build -resource-dir /opt/pyrefcon/lib/clang/13.0.0 -isystem third_party/gloo -isystem ../cmake/../third_party/gloo -isystem ../cmake/../third_party/googletest/googlemock/include -isystem ../cmake/../third_party/googletest/googletest/include -isystem ../third_party/protobuf/src -isystem ../third_party/gemmlowp -isystem ../third_party/neon2sse -isystem ../third_party/XNNPACK/include -isystem ../third_party -isystem ../cmake/../third_party/eigen -isystem /opt/pyrefcon/lib/pyrefcon/models/python3.8 -isystem /usr/lib/python3/dist-packages/numpy/core/include -isystem ../cmake/../third_party/pybind11/include -isystem /usr/lib/x86_64-linux-gnu/openmpi/include/openmpi -isystem /usr/lib/x86_64-linux-gnu/openmpi/include -isystem ../third_party/ideep/mkl-dnn/include -isystem ../third_party/ideep/include -D BUILDING_TESTS -D FMT_HEADER_ONLY=1 -D HAVE_MALLOC_USABLE_SIZE=1 -D HAVE_MMAP=1 -D HAVE_SHM_OPEN=1 -D HAVE_SHM_UNLINK=1 -D MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS -D ONNXIFI_ENABLE_EXT=1 -D ONNX_ML=1 -D ONNX_NAMESPACE=onnx_torch -D THP_BUILD_MAIN_LIB -D USE_C10D -D USE_C10D_GLOO -D USE_C10D_MPI -D USE_DISTRIBUTED -D USE_EXTERNAL_MZCRC -D USE_NUMPY -D USE_RPC -D USE_TENSORPIPE -D USE_VALGRIND -D _FILE_OFFSET_BITS=64 -D torch_python_EXPORTS -I aten/src -I ../aten/src -I . -I ../ -I ../cmake/../third_party/benchmark/include -I caffe2/contrib/aten -I ../third_party/onnx -I third_party/onnx -I ../third_party/foxi -I third_party/foxi -I ../torch/.. -I ../torch/../aten/src -I ../torch/../aten/src/TH -I caffe2/aten/src -I third_party -I ../torch/../third_party/valgrind-headers -I ../torch/../third_party/gloo -I ../torch/../third_party/onnx -I ../torch/csrc -I ../torch/csrc/api/include -I ../torch/lib -I ../torch/lib/libshm -I ../torch/csrc/distributed -I ../torch/csrc/api -I ../c10/.. -I third_party/ideep/mkl-dnn/include -I ../third_party/ideep/mkl-dnn/src/../include -I ../torch/lib/libshm/../../../torch/lib -I ../third_party/fmt/include -D USE_PTHREADPOOL -D NDEBUG -D USE_KINETO -D LIBKINETO_NOCUPTI -D USE_FBGEMM -D USE_QNNPACK -D USE_PYTORCH_QNNPACK -D USE_XNNPACK -D SYMBOLICATE_MOBILE_DEBUG_HANDLE -D HAVE_AVX_CPU_DEFINITION -D HAVE_AVX2_CPU_DEFINITION -D NDEBUG -D NDEBUG -D CAFFE2_USE_GLOO -D HAVE_GCC_GET_CPUID -D USE_AVX -D USE_AVX2 -D TH_HAVE_THREAD -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/x86_64-linux-gnu/c++/10 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/backward -internal-isystem /opt/pyrefcon/lib/clang/13.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O3 -Wno-narrowing -Wall -Wextra -Werror=return-type -Wno-missing-field-initializers -Wno-type-limits -Wno-array-bounds -Wno-unknown-pragmas -Wno-sign-compare -Wno-unused-parameter -Wno-unused-variable -Wno-unused-function -Wno-unused-result -Wno-unused-local-typedefs -Wno-strict-overflow -Wno-strict-aliasing -Wno-error=deprecated-declarations -Wno-stringop-overflow -Wno-psabi -Wno-error=pedantic -Wno-error=redundant-decls -Wno-error=old-style-cast -Wno-unused-but-set-variable -Wno-maybe-uninitialized -Werror=format -Werror=cast-function-type -Wno-stringop-overflow -Wno-write-strings -Wno-strict-aliasing -w -std=gnu++14 -fdeprecated-macro -fdebug-compilation-dir=/tmp/pyrefcon/pytorch/build -ferror-limit 19 -fvisibility-inlines-hidden -fopenmp -fopenmp-cuda-parallel-target-regions -pthread -fgnuc-version=4.2.1 -fcxx-exceptions -fexceptions -faligned-allocation -fcolor-diagnostics -vectorize-loops -vectorize-slp -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/pyrefcon/pytorch/csa-scan/reports -x c++ ../torch/csrc/serialization.cpp

../torch/csrc/serialization.cpp

1#include <torch/csrc/python_headers.h>
2#include <system_error>
3
4#include <torch/csrc/THP.h>
5#include <torch/csrc/serialization.h>
6
7template <class io>
8ssize_t doPartialRead(io fildes, void* buf, size_t nbytes);
9
10template <class io>
11ssize_t doPartialWrite(io fildes, void* buf, size_t nbytes);
12
13static ssize_t doPartialPythonReadBuffered(PyObject* fildes, void* buf, size_t nbytes);
14static ssize_t doPartialPythonReadInto(PyObject* fildes, void* buf, size_t nbytes);
15static ssize_t doPartialPythonWrite(PyObject* fildes, void* buf, size_t nbytes);
16
17template <>
18ssize_t doPartialRead<int>(int fildes, void* buf, size_t nbytes) {
19 return read(fildes, buf, nbytes);
20}
21
22template <>
23ssize_t doPartialRead<PyObject*>(PyObject* fildes, void* buf, size_t nbytes) {
24 // Try to use fildes.readinto() instead of fildes.read()
25 // because it is more memory efficient.
26 // TODO: Stop calling PyObject_HasAttrString() in a loop on our read loop
27 auto has_readinto = PyObject_HasAttrString(fildes, "readinto") == 1;
4
Assuming the condition is true
28 if (has_readinto
4.1
'has_readinto' is true
4.1
'has_readinto' is true
) {
5
Taking true branch
29 return doPartialPythonReadInto(fildes, buf, nbytes);
6
Calling 'doPartialPythonReadInto'
30 }
31 return doPartialPythonReadBuffered(fildes, buf, nbytes);
32}
33
34template <>
35ssize_t doPartialWrite<int>(int fildes, void* buf, size_t nbytes) {
36 return write(fildes, buf, nbytes);
37}
38
39template <>
40ssize_t doPartialWrite<PyObject*>(PyObject* fildes, void* buf, size_t nbytes) {
41 return doPartialPythonWrite(fildes, buf, nbytes);
42}
43
44static inline bool isUnsupportedOperation() {
45 THPObjectPtr io(PyImport_ImportModule("io"));
15
Calling 'PyImport_ImportModule'
17
Returning from 'PyImport_ImportModule'
22
PyObject ownership leak with reference count of 1
46 if (!io) throw python_error();
18
Assuming the condition is false
19
Taking false branch
47 THPObjectPtr exception(PyObject_GetAttrString(io, "UnsupportedOperation"));
48 if (!exception) throw python_error();
20
Assuming the condition is true
21
Taking true branch
49 return PyErr_ExceptionMatches(exception.get());
50}
51
52// Call Python fildes.read(nbytes) and copy it to buf.
53static inline ssize_t doPartialPythonReadBuffered(PyObject* fildes, void* buf, size_t raw_nbytes) {
54 // If we request a large amount of data, f.read() will internally try to
55 // allocate a buffer of that size. This is counterproductive, because
56 // it's not the buffer we ultimately want to write the data into. Read
57 // less than that and avoid allocating too much extra memory.
58 // TODO: Maybe 260 KB is a bit small...
59 const size_t nbytes = std::min<size_t>(raw_nbytes, 262144u); // 2^18 (~260 KB)
60
61 THPObjectPtr r(PyObject_CallMethod(fildes, "read", "i", nbytes));
62 if (!r) throw python_error();
63
64 auto size = PyBytes_GET_SIZE(r.get())((((PyVarObject*)(r.get()))->ob_size));
65 const void* py_buf = PyBytes_AsString(r.get());
66
67 // we read EOF
68 if (size == 0) {
69 return 0;
70 }
71
72 // Slurp it into the buffer we actually want
73 memcpy(buf, py_buf, size);
74
75 return size;
76}
77
78// Either does fildes.readinto(buf) or fildes.write(buf)
79static inline ssize_t doPartialPythonIO(PyObject* fildes, void* buf, size_t nbytes, bool is_read) {
80 auto rw_flag = is_read
7.1
'is_read' is true
7.1
'is_read' is true
? PyBUF_WRITE0x200 : PyBUF_READ0x100;
8
'?' condition is true
81 THPObjectPtr memview(PyMemoryView_FromMemory(
82 reinterpret_cast<char*>(buf), nbytes, rw_flag));
83 if (!memview) throw python_error();
9
Assuming the condition is false
10
Taking false branch
84
85 std::string method = "write";
86 if (is_read
10.1
'is_read' is true
10.1
'is_read' is true
) {
11
Taking true branch
87 method = "readinto";
88 }
89 THPObjectPtr r(PyObject_CallMethod(fildes, method.c_str(), "O", memview.get()));
90 if (r) {
12
Assuming the condition is false
13
Taking false branch
91 return PyLong_AsSsize_t(r.get());
92 }
93
94 // fildes.readinto can return UnsupportedOperation so fall back to fildes.read.
95 if (is_read
13.1
'is_read' is true
13.1
'is_read' is true
&& isUnsupportedOperation()) {
14
Calling 'isUnsupportedOperation'
96 PyErr_Clear();
97 return doPartialPythonReadBuffered(fildes, buf, nbytes);
98 }
99 throw python_error();
100}
101
102// Call Python fildes.readinto(buf)
103static ssize_t doPartialPythonReadInto(PyObject* fildes, void* buf, size_t nbytes) {
104 return doPartialPythonIO(fildes, buf, nbytes, /* is_read */ true);
7
Calling 'doPartialPythonIO'
105}
106
107// Call Python fildes.write(buf)
108static ssize_t doPartialPythonWrite(PyObject* fildes, void* buf, size_t nbytes) {
109 return doPartialPythonIO(fildes, buf, nbytes, /* is_read */ false);
110}
111
112// Requires that we read EXACTLY nbytes; fails if we don't.
113template <typename io>
114void doRead(io fildes, void* raw_buf, size_t nbytes) {
115 char* buf = static_cast<char*>(raw_buf);
116 while (nbytes > 0) {
1
Assuming 'nbytes' is > 0
2
Loop condition is true. Entering loop body
117 errno(*__errno_location ()) = 0; // doPartialRead may not set errno
118 // we read in 1GB blocks to avoid bugs on Mac OS X Lion
119 // see https://github.com/pytorch/pytorch/issues/1031 for more details
120 ssize_t r = doPartialRead(fildes, buf, std::min<size_t>(nbytes, 1073741824));
3
Calling 'doPartialRead<_object *>'
121 if (r < 0) {
122 int err = errno(*__errno_location ());
123 TORCH_INTERNAL_ASSERT(err != 0, "read(): impossible! r < 0, but no errno was set")if ((__builtin_expect(static_cast<bool>(!(err != 0)), 0
))) { ::c10::detail::torchInternalAssertFail( __func__, "../torch/csrc/serialization.cpp"
, static_cast<uint32_t>(123), "err != 0" "INTERNAL ASSERT FAILED at "
"\"../torch/csrc/serialization.cpp\"" ":" "123" ", please report a bug to PyTorch. "
, c10::str("read(): impossible! r < 0, but no errno was set"
)); }
;
124 TORCH_INTERNAL_ASSERT(err != EAGAIN, "read(): non-blocking fd ", fildes,if ((__builtin_expect(static_cast<bool>(!(err != 11)), 0
))) { ::c10::detail::torchInternalAssertFail( __func__, "../torch/csrc/serialization.cpp"
, static_cast<uint32_t>(125), "err != EAGAIN" "INTERNAL ASSERT FAILED at "
"\"../torch/csrc/serialization.cpp\"" ":" "125" ", please report a bug to PyTorch. "
, c10::str("read(): non-blocking fd ", fildes, " read EAGAIN; cowardly refusing to spin-wait"
)); }
125 " read EAGAIN; cowardly refusing to spin-wait")if ((__builtin_expect(static_cast<bool>(!(err != 11)), 0
))) { ::c10::detail::torchInternalAssertFail( __func__, "../torch/csrc/serialization.cpp"
, static_cast<uint32_t>(125), "err != EAGAIN" "INTERNAL ASSERT FAILED at "
"\"../torch/csrc/serialization.cpp\"" ":" "125" ", please report a bug to PyTorch. "
, c10::str("read(): non-blocking fd ", fildes, " read EAGAIN; cowardly refusing to spin-wait"
)); }
;
126 if (err == EINTR4) {
127 continue;
128 } else {
129 AT_ERROR("read(): fd ", fildes, " failed with ", strerror(err))do { ::c10::detail::deprecated_AT_ERROR(); if ((__builtin_expect
(static_cast<bool>(!(false)), 0))) { ::c10::detail::torchCheckFail
( __func__, "../torch/csrc/serialization.cpp", static_cast<
uint32_t>(129), (::c10::detail::torchCheckMsgImpl( "Expected "
"false" " to be true, but got false. " "(Could this error message be improved? If so, "
"please report an enhancement request to PyTorch.)", ::c10::
str("read(): fd ", fildes, " failed with ", strerror(err)))))
; }; } while (false)
;
130 }
131 } else if (r == 0) {
132 break;
133 }
134 buf += r;
135 // This is guaranteed by POSIX, but I just want to be double-sure
136 // to not underflow a signed integer.
137 AT_ASSERT(static_cast<size_t>(r) <= nbytes)do { ::c10::detail::deprecated_AT_ASSERT(); if ((__builtin_expect
(static_cast<bool>(!(static_cast<size_t>(r) <=
nbytes)), 0))) { ::c10::detail::torchInternalAssertFail( __func__
, "../torch/csrc/serialization.cpp", static_cast<uint32_t>
(137), "static_cast<size_t>(r) <= nbytes" "INTERNAL ASSERT FAILED at "
"\"../torch/csrc/serialization.cpp\"" ":" "137" ", please report a bug to PyTorch. "
, c10::str()); }; } while (false)
;
138 nbytes -= r;
139 }
140 if (nbytes != 0) {
141 AT_ERROR("unexpected EOF, expected ", nbytes, " more bytes. The file might be corrupted.")do { ::c10::detail::deprecated_AT_ERROR(); if ((__builtin_expect
(static_cast<bool>(!(false)), 0))) { ::c10::detail::torchCheckFail
( __func__, "../torch/csrc/serialization.cpp", static_cast<
uint32_t>(141), (::c10::detail::torchCheckMsgImpl( "Expected "
"false" " to be true, but got false. " "(Could this error message be improved? If so, "
"please report an enhancement request to PyTorch.)", ::c10::
str("unexpected EOF, expected ", nbytes, " more bytes. The file might be corrupted."
)))); }; } while (false)
;
142 }
143}
144
145template <typename io>
146void doWrite(io fildes, void* raw_buf, size_t nbytes) {
147 char* buf = static_cast<char*>(raw_buf);
148 while (nbytes > 0) {
149 errno(*__errno_location ()) = 0; // doPartialWrite may not set errno
150 // we write in 1GB blocks to avoid bugs on Mac OS X Lion
151 // see https://github.com/pytorch/pytorch/issues/1031 for more details
152 ssize_t r = doPartialWrite(fildes, buf, std::min<size_t>(nbytes, 1073741824));
153 if (r < 0) {
154 int err = errno(*__errno_location ());
155 TORCH_INTERNAL_ASSERT(err != 0, "write(): impossible! r < 0, but no errno was set")if ((__builtin_expect(static_cast<bool>(!(err != 0)), 0
))) { ::c10::detail::torchInternalAssertFail( __func__, "../torch/csrc/serialization.cpp"
, static_cast<uint32_t>(155), "err != 0" "INTERNAL ASSERT FAILED at "
"\"../torch/csrc/serialization.cpp\"" ":" "155" ", please report a bug to PyTorch. "
, c10::str("write(): impossible! r < 0, but no errno was set"
)); }
;
156 TORCH_INTERNAL_ASSERT(err != EAGAIN, "write(): non-blocking fd ", fildes,if ((__builtin_expect(static_cast<bool>(!(err != 11)), 0
))) { ::c10::detail::torchInternalAssertFail( __func__, "../torch/csrc/serialization.cpp"
, static_cast<uint32_t>(157), "err != EAGAIN" "INTERNAL ASSERT FAILED at "
"\"../torch/csrc/serialization.cpp\"" ":" "157" ", please report a bug to PyTorch. "
, c10::str("write(): non-blocking fd ", fildes, " read EAGAIN; cowardly refusing to spin-wait"
)); }
157 " read EAGAIN; cowardly refusing to spin-wait")if ((__builtin_expect(static_cast<bool>(!(err != 11)), 0
))) { ::c10::detail::torchInternalAssertFail( __func__, "../torch/csrc/serialization.cpp"
, static_cast<uint32_t>(157), "err != EAGAIN" "INTERNAL ASSERT FAILED at "
"\"../torch/csrc/serialization.cpp\"" ":" "157" ", please report a bug to PyTorch. "
, c10::str("write(): non-blocking fd ", fildes, " read EAGAIN; cowardly refusing to spin-wait"
)); }
;
158 if (err == EINTR4) {
159 continue;
160 } else {
161 AT_ERROR("write(): fd ", fildes, " failed with ", strerror(err))do { ::c10::detail::deprecated_AT_ERROR(); if ((__builtin_expect
(static_cast<bool>(!(false)), 0))) { ::c10::detail::torchCheckFail
( __func__, "../torch/csrc/serialization.cpp", static_cast<
uint32_t>(161), (::c10::detail::torchCheckMsgImpl( "Expected "
"false" " to be true, but got false. " "(Could this error message be improved? If so, "
"please report an enhancement request to PyTorch.)", ::c10::
str("write(): fd ", fildes, " failed with ", strerror(err))))
); }; } while (false)
;
162 }
163 }
164 buf += r;
165 AT_ASSERT(static_cast<size_t>(r) <= nbytes)do { ::c10::detail::deprecated_AT_ASSERT(); if ((__builtin_expect
(static_cast<bool>(!(static_cast<size_t>(r) <=
nbytes)), 0))) { ::c10::detail::torchInternalAssertFail( __func__
, "../torch/csrc/serialization.cpp", static_cast<uint32_t>
(165), "static_cast<size_t>(r) <= nbytes" "INTERNAL ASSERT FAILED at "
"\"../torch/csrc/serialization.cpp\"" ":" "165" ", please report a bug to PyTorch. "
, c10::str()); }; } while (false)
;
166 nbytes -= r;
167 }
168}
169
170// NOLINTNEXTLINE(bugprone-suspicious-include)
171#include <torch/csrc/generic/serialization.cpp>
172#include <TH/THGenerateAllTypes.h>
173
174// NOLINTNEXTLINE(bugprone-suspicious-include)
175#include <torch/csrc/generic/serialization.cpp>
176#include <TH/THGenerateComplexTypes.h>
177
178// NOLINTNEXTLINE(bugprone-suspicious-include)
179#include <torch/csrc/generic/serialization.cpp>
180#include <TH/THGenerateHalfType.h>
181
182// NOLINTNEXTLINE(bugprone-suspicious-include)
183#include <torch/csrc/generic/serialization.cpp>
184#include <TH/THGenerateBFloat16Type.h>
185
186// NOLINTNEXTLINE(bugprone-suspicious-include)
187#include <torch/csrc/generic/serialization.cpp>
188#include <TH/THGenerateBoolType.h>
189
190// NOLINTNEXTLINE(bugprone-suspicious-include)
191#include <torch/csrc/generic/serialization.cpp>
192#include <TH/THGenerateQTypes.h>

/opt/pyrefcon/lib/pyrefcon/models/models/PyImport_ImportModule.model

1#ifndef PyImport_ImportModule
2struct _object;
3typedef struct _object PyObject;
4PyObject* clang_analyzer_PyObject_New_Reference();
5PyObject* PyImport_ImportModule(const char *name) {
6 return clang_analyzer_PyObject_New_Reference();
16
Setting reference count to 1
7}
8#else
9#warning "API PyImport_ImportModule is defined as a macro."
10#endif