Bug Summary

File:lldb/source/Core/ValueObjectRegister.cpp
Warning:line 181, column 10
Potential memory leak

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name ValueObjectRegister.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 -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -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 -ffunction-sections -fdata-sections -fcoverage-compilation-dir=/build/llvm-toolchain-snapshot-14~++20220119111520+da61cb019eb2/build-llvm/tools/clang/stage2-bins -resource-dir /usr/lib/llvm-14/lib/clang/14.0.0 -isystem /usr/include/libxml2 -D HAVE_ROUND -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I tools/lldb/source/Core -I /build/llvm-toolchain-snapshot-14~++20220119111520+da61cb019eb2/lldb/source/Core -I /build/llvm-toolchain-snapshot-14~++20220119111520+da61cb019eb2/lldb/include -I tools/lldb/include -I include -I /build/llvm-toolchain-snapshot-14~++20220119111520+da61cb019eb2/llvm/include -I /usr/include/python3.9 -I /build/llvm-toolchain-snapshot-14~++20220119111520+da61cb019eb2/clang/include -I tools/lldb/../clang/include -I /build/llvm-toolchain-snapshot-14~++20220119111520+da61cb019eb2/lldb/source -I tools/lldb/source -D _FORTIFY_SOURCE=2 -D NDEBUG -U NDEBUG -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 /usr/lib/llvm-14/lib/clang/14.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 -fmacro-prefix-map=/build/llvm-toolchain-snapshot-14~++20220119111520+da61cb019eb2/build-llvm/tools/clang/stage2-bins=build-llvm/tools/clang/stage2-bins -fmacro-prefix-map=/build/llvm-toolchain-snapshot-14~++20220119111520+da61cb019eb2/= -fcoverage-prefix-map=/build/llvm-toolchain-snapshot-14~++20220119111520+da61cb019eb2/build-llvm/tools/clang/stage2-bins=build-llvm/tools/clang/stage2-bins -fcoverage-prefix-map=/build/llvm-toolchain-snapshot-14~++20220119111520+da61cb019eb2/= -O3 -Wno-unused-command-line-argument -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-maybe-uninitialized -Wno-class-memaccess -Wno-redundant-move -Wno-pessimizing-move -Wno-noexcept-type -Wno-comment -Wno-deprecated-declarations -Wno-unknown-pragmas -Wno-strict-aliasing -Wno-deprecated-register -Wno-vla-extension -std=c++14 -fdeprecated-macro -fdebug-compilation-dir=/build/llvm-toolchain-snapshot-14~++20220119111520+da61cb019eb2/build-llvm/tools/clang/stage2-bins -fdebug-prefix-map=/build/llvm-toolchain-snapshot-14~++20220119111520+da61cb019eb2/build-llvm/tools/clang/stage2-bins=build-llvm/tools/clang/stage2-bins -fdebug-prefix-map=/build/llvm-toolchain-snapshot-14~++20220119111520+da61cb019eb2/= -ferror-limit 19 -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -fcolor-diagnostics -vectorize-loops -vectorize-slp -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2022-01-19-134126-35450-1 -x c++ /build/llvm-toolchain-snapshot-14~++20220119111520+da61cb019eb2/lldb/source/Core/ValueObjectRegister.cpp
1//===-- ValueObjectRegister.cpp -------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "lldb/Core/ValueObjectRegister.h"
10
11#include "lldb/Core/Module.h"
12#include "lldb/Core/Value.h"
13#include "lldb/Symbol/CompilerType.h"
14#include "lldb/Symbol/TypeSystem.h"
15#include "lldb/Target/ExecutionContext.h"
16#include "lldb/Target/Process.h"
17#include "lldb/Target/RegisterContext.h"
18#include "lldb/Target/StackFrame.h"
19#include "lldb/Target/Target.h"
20#include "lldb/Utility/DataExtractor.h"
21#include "lldb/Utility/Log.h"
22#include "lldb/Utility/Scalar.h"
23#include "lldb/Utility/Status.h"
24#include "lldb/Utility/Stream.h"
25
26#include "llvm/ADT/StringRef.h"
27
28#include <cassert>
29#include <memory>
30
31namespace lldb_private {
32class ExecutionContextScope;
33}
34
35using namespace lldb;
36using namespace lldb_private;
37
38#pragma mark ValueObjectRegisterSet
39
40ValueObjectSP
41ValueObjectRegisterSet::Create(ExecutionContextScope *exe_scope,
42 lldb::RegisterContextSP &reg_ctx_sp,
43 uint32_t set_idx) {
44 auto manager_sp = ValueObjectManager::Create();
45 return (new ValueObjectRegisterSet(exe_scope, *manager_sp, reg_ctx_sp,
46 set_idx))
47 ->GetSP();
48}
49
50ValueObjectRegisterSet::ValueObjectRegisterSet(ExecutionContextScope *exe_scope,
51 ValueObjectManager &manager,
52 lldb::RegisterContextSP &reg_ctx,
53 uint32_t reg_set_idx)
54 : ValueObject(exe_scope, manager), m_reg_ctx_sp(reg_ctx),
55 m_reg_set(nullptr), m_reg_set_idx(reg_set_idx) {
56 assert(reg_ctx)(static_cast <bool> (reg_ctx) ? void (0) : __assert_fail
("reg_ctx", "lldb/source/Core/ValueObjectRegister.cpp", 56, __extension__
__PRETTY_FUNCTION__))
;
57 m_reg_set = reg_ctx->GetRegisterSet(m_reg_set_idx);
58 if (m_reg_set) {
59 m_name.SetCString(m_reg_set->name);
60 }
61}
62
63ValueObjectRegisterSet::~ValueObjectRegisterSet() = default;
64
65CompilerType ValueObjectRegisterSet::GetCompilerTypeImpl() {
66 return CompilerType();
67}
68
69ConstString ValueObjectRegisterSet::GetTypeName() { return ConstString(); }
70
71ConstString ValueObjectRegisterSet::GetQualifiedTypeName() {
72 return ConstString();
73}
74
75size_t ValueObjectRegisterSet::CalculateNumChildren(uint32_t max) {
76 const RegisterSet *reg_set = m_reg_ctx_sp->GetRegisterSet(m_reg_set_idx);
77 if (reg_set) {
78 auto reg_count = reg_set->num_registers;
79 return reg_count <= max ? reg_count : max;
80 }
81 return 0;
82}
83
84llvm::Optional<uint64_t> ValueObjectRegisterSet::GetByteSize() { return 0; }
85
86bool ValueObjectRegisterSet::UpdateValue() {
87 m_error.Clear();
88 SetValueDidChange(false);
89 ExecutionContext exe_ctx(GetExecutionContextRef());
90 StackFrame *frame = exe_ctx.GetFramePtr();
91 if (frame == nullptr)
92 m_reg_ctx_sp.reset();
93 else {
94 m_reg_ctx_sp = frame->GetRegisterContext();
95 if (m_reg_ctx_sp) {
96 const RegisterSet *reg_set = m_reg_ctx_sp->GetRegisterSet(m_reg_set_idx);
97 if (reg_set == nullptr)
98 m_reg_ctx_sp.reset();
99 else if (m_reg_set != reg_set) {
100 SetValueDidChange(true);
101 m_name.SetCString(reg_set->name);
102 }
103 }
104 }
105 if (m_reg_ctx_sp) {
106 SetValueIsValid(true);
107 } else {
108 SetValueIsValid(false);
109 m_error.SetErrorToGenericError();
110 m_children.Clear();
111 }
112 return m_error.Success();
113}
114
115ValueObject *ValueObjectRegisterSet::CreateChildAtIndex(
116 size_t idx, bool synthetic_array_member, int32_t synthetic_index) {
117 ValueObject *valobj = nullptr;
118 if (m_reg_ctx_sp && m_reg_set) {
119 const size_t num_children = GetNumChildren();
120 if (idx < num_children)
121 valobj = new ValueObjectRegister(
122 *this, m_reg_ctx_sp,
123 m_reg_ctx_sp->GetRegisterInfoAtIndex(m_reg_set->registers[idx]));
124 }
125 return valobj;
126}
127
128lldb::ValueObjectSP
129ValueObjectRegisterSet::GetChildMemberWithName(ConstString name,
130 bool can_create) {
131 ValueObject *valobj = nullptr;
132 if (m_reg_ctx_sp && m_reg_set) {
133 const RegisterInfo *reg_info =
134 m_reg_ctx_sp->GetRegisterInfoByName(name.GetStringRef());
135 if (reg_info != nullptr)
136 valobj = new ValueObjectRegister(*this, m_reg_ctx_sp, reg_info);
137 }
138 if (valobj)
139 return valobj->GetSP();
140 else
141 return ValueObjectSP();
142}
143
144size_t
145ValueObjectRegisterSet::GetIndexOfChildWithName(ConstString name) {
146 if (m_reg_ctx_sp && m_reg_set) {
147 const RegisterInfo *reg_info =
148 m_reg_ctx_sp->GetRegisterInfoByName(name.GetStringRef());
149 if (reg_info != nullptr)
150 return reg_info->kinds[eRegisterKindLLDB];
151 }
152 return UINT32_MAX(4294967295U);
153}
154
155#pragma mark -
156#pragma mark ValueObjectRegister
157
158void ValueObjectRegister::ConstructObject(const RegisterInfo *reg_info) {
159 if (reg_info) {
160 m_reg_info = *reg_info;
161 if (reg_info->name)
162 m_name.SetCString(reg_info->name);
163 else if (reg_info->alt_name)
164 m_name.SetCString(reg_info->alt_name);
165 }
166}
167
168ValueObjectRegister::ValueObjectRegister(ValueObject &parent,
169 lldb::RegisterContextSP &reg_ctx_sp,
170 const RegisterInfo *reg_info)
171 : ValueObject(parent), m_reg_ctx_sp(reg_ctx_sp), m_reg_info(),
172 m_reg_value(), m_type_name(), m_compiler_type() {
173 assert(reg_ctx_sp.get())(static_cast <bool> (reg_ctx_sp.get()) ? void (0) : __assert_fail
("reg_ctx_sp.get()", "lldb/source/Core/ValueObjectRegister.cpp"
, 173, __extension__ __PRETTY_FUNCTION__))
;
174 ConstructObject(reg_info);
175}
176
177ValueObjectSP ValueObjectRegister::Create(ExecutionContextScope *exe_scope,
178 lldb::RegisterContextSP &reg_ctx_sp,
179 const RegisterInfo *reg_info) {
180 auto manager_sp = ValueObjectManager::Create();
181 return (new ValueObjectRegister(exe_scope, *manager_sp, reg_ctx_sp, reg_info))
1
Memory is allocated
2
Potential memory leak
182 ->GetSP();
183}
184
185ValueObjectRegister::ValueObjectRegister(ExecutionContextScope *exe_scope,
186 ValueObjectManager &manager,
187 lldb::RegisterContextSP &reg_ctx,
188 const RegisterInfo *reg_info)
189 : ValueObject(exe_scope, manager), m_reg_ctx_sp(reg_ctx), m_reg_info(),
190 m_reg_value(), m_type_name(), m_compiler_type() {
191 assert(reg_ctx)(static_cast <bool> (reg_ctx) ? void (0) : __assert_fail
("reg_ctx", "lldb/source/Core/ValueObjectRegister.cpp", 191,
__extension__ __PRETTY_FUNCTION__))
;
192 ConstructObject(reg_info);
193}
194
195ValueObjectRegister::~ValueObjectRegister() = default;
196
197CompilerType ValueObjectRegister::GetCompilerTypeImpl() {
198 if (!m_compiler_type.IsValid()) {
199 ExecutionContext exe_ctx(GetExecutionContextRef());
200 if (auto *target = exe_ctx.GetTargetPtr()) {
201 if (auto *exe_module = target->GetExecutableModulePointer()) {
202 auto type_system_or_err =
203 exe_module->GetTypeSystemForLanguage(eLanguageTypeC);
204 if (auto err = type_system_or_err.takeError()) {
205 LLDB_LOG_ERROR(do { ::lldb_private::Log *log_private = (lldb_private::GetLogIfAnyCategoriesSet
((1u << 19))); ::llvm::Error error_private = (std::move
(err)); if (log_private && error_private) { log_private
->FormatError(::std::move(error_private), "lldb/source/Core/ValueObjectRegister.cpp"
, __func__, "Unable to get CompilerType from TypeSystem"); } else
::llvm::consumeError(::std::move(error_private)); } while (0
)
206 lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_TYPES),do { ::lldb_private::Log *log_private = (lldb_private::GetLogIfAnyCategoriesSet
((1u << 19))); ::llvm::Error error_private = (std::move
(err)); if (log_private && error_private) { log_private
->FormatError(::std::move(error_private), "lldb/source/Core/ValueObjectRegister.cpp"
, __func__, "Unable to get CompilerType from TypeSystem"); } else
::llvm::consumeError(::std::move(error_private)); } while (0
)
207 std::move(err), "Unable to get CompilerType from TypeSystem")do { ::lldb_private::Log *log_private = (lldb_private::GetLogIfAnyCategoriesSet
((1u << 19))); ::llvm::Error error_private = (std::move
(err)); if (log_private && error_private) { log_private
->FormatError(::std::move(error_private), "lldb/source/Core/ValueObjectRegister.cpp"
, __func__, "Unable to get CompilerType from TypeSystem"); } else
::llvm::consumeError(::std::move(error_private)); } while (0
)
;
208 } else {
209 m_compiler_type =
210 type_system_or_err->GetBuiltinTypeForEncodingAndBitSize(
211 m_reg_info.encoding, m_reg_info.byte_size * 8);
212 }
213 }
214 }
215 }
216 return m_compiler_type;
217}
218
219ConstString ValueObjectRegister::GetTypeName() {
220 if (m_type_name.IsEmpty())
221 m_type_name = GetCompilerType().GetTypeName();
222 return m_type_name;
223}
224
225size_t ValueObjectRegister::CalculateNumChildren(uint32_t max) {
226 ExecutionContext exe_ctx(GetExecutionContextRef());
227 auto children_count = GetCompilerType().GetNumChildren(true, &exe_ctx);
228 return children_count <= max ? children_count : max;
229}
230
231llvm::Optional<uint64_t> ValueObjectRegister::GetByteSize() {
232 return m_reg_info.byte_size;
233}
234
235bool ValueObjectRegister::UpdateValue() {
236 m_error.Clear();
237 ExecutionContext exe_ctx(GetExecutionContextRef());
238 StackFrame *frame = exe_ctx.GetFramePtr();
239 if (frame == nullptr) {
240 m_reg_ctx_sp.reset();
241 m_reg_value.Clear();
242 }
243
244 if (m_reg_ctx_sp) {
245 RegisterValue m_old_reg_value(m_reg_value);
246 if (m_reg_ctx_sp->ReadRegister(&m_reg_info, m_reg_value)) {
247 if (m_reg_value.GetData(m_data)) {
248 Process *process = exe_ctx.GetProcessPtr();
249 if (process)
250 m_data.SetAddressByteSize(process->GetAddressByteSize());
251 m_value.SetContext(Value::ContextType::RegisterInfo,
252 (void *)&m_reg_info);
253 m_value.SetValueType(Value::ValueType::HostAddress);
254 m_value.GetScalar() = (uintptr_t)m_data.GetDataStart();
255 SetValueIsValid(true);
256 SetValueDidChange(!(m_old_reg_value == m_reg_value));
257 return true;
258 }
259 }
260 }
261
262 SetValueIsValid(false);
263 m_error.SetErrorToGenericError();
264 return false;
265}
266
267bool ValueObjectRegister::SetValueFromCString(const char *value_str,
268 Status &error) {
269 // The new value will be in the m_data. Copy that into our register value.
270 error =
271 m_reg_value.SetValueFromString(&m_reg_info, llvm::StringRef(value_str));
272 if (error.Success()) {
273 if (m_reg_ctx_sp->WriteRegister(&m_reg_info, m_reg_value)) {
274 SetNeedsUpdate();
275 return true;
276 } else
277 return false;
278 } else
279 return false;
280}
281
282bool ValueObjectRegister::SetData(DataExtractor &data, Status &error) {
283 error = m_reg_value.SetValueFromData(&m_reg_info, data, 0, false);
284 if (error.Success()) {
285 if (m_reg_ctx_sp->WriteRegister(&m_reg_info, m_reg_value)) {
286 SetNeedsUpdate();
287 return true;
288 } else
289 return false;
290 } else
291 return false;
292}
293
294bool ValueObjectRegister::ResolveValue(Scalar &scalar) {
295 if (UpdateValueIfNeeded(
296 false)) // make sure that you are up to date before returning anything
297 return m_reg_value.GetScalarValue(scalar);
298 return false;
299}
300
301void ValueObjectRegister::GetExpressionPath(Stream &s,
302 GetExpressionPathFormat epformat) {
303 s.Printf("$%s", m_reg_info.name);
304}