Bug Summary

File:tools/lldb/source/Plugins/Language/CPlusPlus/BlockPointer.cpp
Warning:line 185, column 34
Potential leak of memory pointed to by 'synthetic_children'

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name BlockPointer.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 -mrelocation-model pic -pic-level 2 -mthread-model posix -fmath-errno -masm-verbose -mconstructor-aliases -munwind-tables -fuse-init-array -target-cpu x86-64 -dwarf-column-info -debugger-tuning=gdb -momit-leaf-frame-pointer -ffunction-sections -fdata-sections -resource-dir /usr/lib/llvm-8/lib/clang/8.0.0 -D HAVE_ROUND -D LLDB_CONFIGURATION_RELEASE -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /build/llvm-toolchain-snapshot-8~svn345461/build-llvm/tools/lldb/source/Plugins/Language/CPlusPlus -I /build/llvm-toolchain-snapshot-8~svn345461/tools/lldb/source/Plugins/Language/CPlusPlus -I /build/llvm-toolchain-snapshot-8~svn345461/build-llvm/tools/lldb/include -I /build/llvm-toolchain-snapshot-8~svn345461/tools/lldb/include -I /build/llvm-toolchain-snapshot-8~svn345461/build-llvm/include -I /build/llvm-toolchain-snapshot-8~svn345461/include -I /usr/include/python2.7 -I /build/llvm-toolchain-snapshot-8~svn345461/tools/clang/include -I /build/llvm-toolchain-snapshot-8~svn345461/build-llvm/tools/lldb/../clang/include -I /build/llvm-toolchain-snapshot-8~svn345461/tools/lldb/source/. -U NDEBUG -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/x86_64-linux-gnu/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/x86_64-linux-gnu/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0/backward -internal-isystem /usr/include/clang/8.0.0/include/ -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-8/lib/clang/8.0.0/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-maybe-uninitialized -Wno-comment -Wno-deprecated-declarations -Wno-unknown-pragmas -Wno-strict-aliasing -Wno-deprecated-register -Wno-vla-extension -std=c++11 -fdeprecated-macro -fdebug-compilation-dir /build/llvm-toolchain-snapshot-8~svn345461/build-llvm/tools/lldb/source/Plugins/Language/CPlusPlus -ferror-limit 19 -fmessage-length 0 -fvisibility-inlines-hidden -fobjc-runtime=gcc -fdiagnostics-show-option -vectorize-loops -vectorize-slp -analyzer-output=html -analyzer-config stable-report-filename=true -o /tmp/scan-build-2018-10-27-211344-32123-1 -x c++ /build/llvm-toolchain-snapshot-8~svn345461/tools/lldb/source/Plugins/Language/CPlusPlus/BlockPointer.cpp -faddrsig
1//===-- BlockPointer.cpp ----------------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10// C Includes
11// C++ Includes
12// Other libraries and framework includes
13// Project includes
14#include "BlockPointer.h"
15
16#include "lldb/Core/ValueObject.h"
17#include "lldb/DataFormatters/FormattersHelpers.h"
18#include "lldb/Symbol/ClangASTContext.h"
19#include "lldb/Symbol/ClangASTImporter.h"
20#include "lldb/Symbol/CompilerType.h"
21#include "lldb/Symbol/TypeSystem.h"
22#include "lldb/Target/Target.h"
23
24#include "lldb/Utility/LLDBAssert.h"
25
26using namespace lldb;
27using namespace lldb_private;
28using namespace lldb_private::formatters;
29
30namespace lldb_private {
31namespace formatters {
32
33class BlockPointerSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
34public:
35 BlockPointerSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
36 : SyntheticChildrenFrontEnd(*valobj_sp), m_block_struct_type() {
37 CompilerType block_pointer_type(m_backend.GetCompilerType());
38 CompilerType function_pointer_type;
39 block_pointer_type.IsBlockPointerType(&function_pointer_type);
40
41 TargetSP target_sp(m_backend.GetTargetSP());
42
43 if (!target_sp) {
44 return;
45 }
46
47 Status err;
48 TypeSystem *type_system = target_sp->GetScratchTypeSystemForLanguage(
49 &err, lldb::eLanguageTypeC_plus_plus);
50
51 if (!err.Success() || !type_system) {
52 return;
53 }
54
55 ClangASTContext *clang_ast_context =
56 llvm::dyn_cast<ClangASTContext>(type_system);
57
58 if (!clang_ast_context) {
59 return;
60 }
61
62 ClangASTImporterSP clang_ast_importer = target_sp->GetClangASTImporter();
63
64 if (!clang_ast_importer) {
65 return;
66 }
67
68 const char *const isa_name("__isa");
69 const CompilerType isa_type =
70 clang_ast_context->GetBasicType(lldb::eBasicTypeObjCClass);
71 const char *const flags_name("__flags");
72 const CompilerType flags_type =
73 clang_ast_context->GetBasicType(lldb::eBasicTypeInt);
74 const char *const reserved_name("__reserved");
75 const CompilerType reserved_type =
76 clang_ast_context->GetBasicType(lldb::eBasicTypeInt);
77 const char *const FuncPtr_name("__FuncPtr");
78 const CompilerType FuncPtr_type =
79 clang_ast_importer->CopyType(*clang_ast_context, function_pointer_type);
80
81 m_block_struct_type = clang_ast_context->CreateStructForIdentifier(
82 ConstString(), {{isa_name, isa_type},
83 {flags_name, flags_type},
84 {reserved_name, reserved_type},
85 {FuncPtr_name, FuncPtr_type}});
86 }
87
88 ~BlockPointerSyntheticFrontEnd() override = default;
89
90 size_t CalculateNumChildren() override {
91 const bool omit_empty_base_classes = false;
92 return m_block_struct_type.GetNumChildren(omit_empty_base_classes);
93 }
94
95 lldb::ValueObjectSP GetChildAtIndex(size_t idx) override {
96 if (!m_block_struct_type.IsValid()) {
97 return lldb::ValueObjectSP();
98 }
99
100 if (idx >= CalculateNumChildren()) {
101 return lldb::ValueObjectSP();
102 }
103
104 const bool thread_and_frame_only_if_stopped = true;
105 ExecutionContext exe_ctx = m_backend.GetExecutionContextRef().Lock(
106 thread_and_frame_only_if_stopped);
107 const bool transparent_pointers = false;
108 const bool omit_empty_base_classes = false;
109 const bool ignore_array_bounds = false;
110 ValueObject *value_object = nullptr;
111
112 std::string child_name;
113 uint32_t child_byte_size = 0;
114 int32_t child_byte_offset = 0;
115 uint32_t child_bitfield_bit_size = 0;
116 uint32_t child_bitfield_bit_offset = 0;
117 bool child_is_base_class = false;
118 bool child_is_deref_of_parent = false;
119 uint64_t language_flags = 0;
120
121 const CompilerType child_type =
122 m_block_struct_type.GetChildCompilerTypeAtIndex(
123 &exe_ctx, idx, transparent_pointers, omit_empty_base_classes,
124 ignore_array_bounds, child_name, child_byte_size, child_byte_offset,
125 child_bitfield_bit_size, child_bitfield_bit_offset,
126 child_is_base_class, child_is_deref_of_parent, value_object,
127 language_flags);
128
129 ValueObjectSP struct_pointer_sp =
130 m_backend.Cast(m_block_struct_type.GetPointerType());
131
132 if (!struct_pointer_sp) {
133 return lldb::ValueObjectSP();
134 }
135
136 Status err;
137 ValueObjectSP struct_sp = struct_pointer_sp->Dereference(err);
138
139 if (!struct_sp || !err.Success()) {
140 return lldb::ValueObjectSP();
141 }
142
143 ValueObjectSP child_sp(struct_sp->GetSyntheticChildAtOffset(
144 child_byte_offset, child_type, true,
145 ConstString(child_name.c_str(), child_name.size())));
146
147 return child_sp;
148 }
149
150 // return true if this object is now safe to use forever without ever
151 // updating again; the typical (and tested) answer here is 'false'
152 bool Update() override { return false; }
153
154 // maybe return false if the block pointer is, say, null
155 bool MightHaveChildren() override { return true; }
156
157 size_t GetIndexOfChildWithName(const ConstString &name) override {
158 if (!m_block_struct_type.IsValid())
159 return UINT32_MAX(4294967295U);
160
161 const bool omit_empty_base_classes = false;
162 return m_block_struct_type.GetIndexOfChildWithName(name.AsCString(),
163 omit_empty_base_classes);
164 }
165
166private:
167 CompilerType m_block_struct_type;
168};
169
170} // namespace formatters
171} // namespace lldb_private
172
173bool lldb_private::formatters::BlockPointerSummaryProvider(
174 ValueObject &valobj, Stream &s, const TypeSummaryOptions &) {
175 lldb_private::SyntheticChildrenFrontEnd *synthetic_children =
176 BlockPointerSyntheticFrontEndCreator(nullptr, valobj.GetSP());
1
Calling 'BlockPointerSyntheticFrontEndCreator'
4
Returned allocated memory
177 if (!synthetic_children) {
5
Taking false branch
178 return false;
179 }
180
181 synthetic_children->Update();
182
183 static const ConstString s_FuncPtr_name("__FuncPtr");
184
185 lldb::ValueObjectSP child_sp = synthetic_children->GetChildAtIndex(
6
Potential leak of memory pointed to by 'synthetic_children'
186 synthetic_children->GetIndexOfChildWithName(s_FuncPtr_name));
187
188 if (!child_sp) {
189 return false;
190 }
191
192 lldb::ValueObjectSP qualified_child_representation_sp =
193 child_sp->GetQualifiedRepresentationIfAvailable(
194 lldb::eDynamicDontRunTarget, true);
195
196 const char *child_value =
197 qualified_child_representation_sp->GetValueAsCString();
198
199 s.Printf("%s", child_value);
200
201 return true;
202}
203
204lldb_private::SyntheticChildrenFrontEnd *
205lldb_private::formatters::BlockPointerSyntheticFrontEndCreator(
206 CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
207 if (!valobj_sp)
2
Taking false branch
208 return nullptr;
209 return new BlockPointerSyntheticFrontEnd(valobj_sp);
3
Memory is allocated
210}