Bug Summary

File:tools/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp
Warning:line 229, column 16
Potential leak of memory pointed to by 'reg_interface'

Annotated Source Code

1//===-- ThreadElfCore.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#include "lldb/Target/RegisterContext.h"
11#include "lldb/Target/StopInfo.h"
12#include "lldb/Target/Target.h"
13#include "lldb/Target/Unwind.h"
14#include "lldb/Utility/DataExtractor.h"
15#include "lldb/Utility/Log.h"
16
17#include "Plugins/Process/Utility/RegisterContextFreeBSD_i386.h"
18#include "Plugins/Process/Utility/RegisterContextFreeBSD_mips64.h"
19#include "Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.h"
20#include "Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.h"
21#include "Plugins/Process/Utility/RegisterContextLinux_mips64.h"
22#include "Plugins/Process/Utility/RegisterContextLinux_mips.h"
23#include "Plugins/Process/Utility/RegisterContextLinux_i386.h"
24#include "Plugins/Process/Utility/RegisterContextLinux_s390x.h"
25#include "Plugins/Process/Utility/RegisterContextLinux_x86_64.h"
26#include "Plugins/Process/Utility/RegisterContextNetBSD_x86_64.h"
27#include "Plugins/Process/Utility/RegisterContextOpenBSD_i386.h"
28#include "Plugins/Process/Utility/RegisterContextOpenBSD_x86_64.h"
29#include "Plugins/Process/Utility/RegisterInfoPOSIX_arm.h"
30#include "Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h"
31#include "ProcessElfCore.h"
32#include "RegisterContextPOSIXCore_arm.h"
33#include "RegisterContextPOSIXCore_arm64.h"
34#include "RegisterContextPOSIXCore_mips64.h"
35#include "RegisterContextPOSIXCore_powerpc.h"
36#include "RegisterContextPOSIXCore_s390x.h"
37#include "RegisterContextPOSIXCore_x86_64.h"
38#include "ThreadElfCore.h"
39
40using namespace lldb;
41using namespace lldb_private;
42
43//----------------------------------------------------------------------
44// Construct a Thread object with given data
45//----------------------------------------------------------------------
46ThreadElfCore::ThreadElfCore(Process &process, const ThreadData &td)
47 : Thread(process, td.tid), m_thread_name(td.name), m_thread_reg_ctx_sp(),
48 m_signo(td.signo), m_gpregset_data(td.gpregset),
49 m_fpregset_data(td.fpregset), m_vregset_data(td.vregset) {}
50
51ThreadElfCore::~ThreadElfCore() { DestroyThread(); }
52
53void ThreadElfCore::RefreshStateAfterStop() {
54 GetRegisterContext()->InvalidateIfNeeded(false);
1
Calling 'ThreadElfCore::GetRegisterContext'
55}
56
57void ThreadElfCore::ClearStackFrames() {
58 Unwind *unwinder = GetUnwinder();
59 if (unwinder)
60 unwinder->Clear();
61 Thread::ClearStackFrames();
62}
63
64RegisterContextSP ThreadElfCore::GetRegisterContext() {
65 if (m_reg_context_sp.get() == NULL__null) {
2
Assuming the condition is true
3
Taking true branch
66 m_reg_context_sp = CreateRegisterContextForFrame(NULL__null);
4
Calling 'ThreadElfCore::CreateRegisterContextForFrame'
67 }
68 return m_reg_context_sp;
69}
70
71RegisterContextSP
72ThreadElfCore::CreateRegisterContextForFrame(StackFrame *frame) {
73 RegisterContextSP reg_ctx_sp;
74 uint32_t concrete_frame_idx = 0;
75 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD(1u << 2)));
76
77 if (frame)
5
Taking false branch
78 concrete_frame_idx = frame->GetConcreteFrameIndex();
79
80 if (concrete_frame_idx == 0) {
6
Taking true branch
81 if (m_thread_reg_ctx_sp)
7
Taking false branch
82 return m_thread_reg_ctx_sp;
83
84 ProcessElfCore *process = static_cast<ProcessElfCore *>(GetProcess().get());
85 ArchSpec arch = process->GetArchitecture();
86 RegisterInfoInterface *reg_interface = NULL__null;
87
88 switch (arch.GetTriple().getOS()) {
8
Control jumps to 'case OpenBSD:' at line 160
89 case llvm::Triple::FreeBSD: {
90 switch (arch.GetMachine()) {
91 case llvm::Triple::aarch64:
92 reg_interface = new RegisterInfoPOSIX_arm64(arch);
93 break;
94 case llvm::Triple::arm:
95 reg_interface = new RegisterInfoPOSIX_arm(arch);
96 break;
97 case llvm::Triple::ppc:
98 reg_interface = new RegisterContextFreeBSD_powerpc32(arch);
99 break;
100 case llvm::Triple::ppc64:
101 reg_interface = new RegisterContextFreeBSD_powerpc64(arch);
102 break;
103 case llvm::Triple::mips64:
104 reg_interface = new RegisterContextFreeBSD_mips64(arch);
105 break;
106 case llvm::Triple::x86:
107 reg_interface = new RegisterContextFreeBSD_i386(arch);
108 break;
109 case llvm::Triple::x86_64:
110 reg_interface = new RegisterContextFreeBSD_x86_64(arch);
111 break;
112 default:
113 break;
114 }
115 break;
116 }
117
118 case llvm::Triple::NetBSD: {
119 switch (arch.GetMachine()) {
120 case llvm::Triple::x86_64:
121 reg_interface = new RegisterContextNetBSD_x86_64(arch);
122 break;
123 default:
124 break;
125 }
126 break;
127 }
128
129 case llvm::Triple::Linux: {
130 switch (arch.GetMachine()) {
131 case llvm::Triple::arm:
132 reg_interface = new RegisterInfoPOSIX_arm(arch);
133 break;
134 case llvm::Triple::aarch64:
135 reg_interface = new RegisterInfoPOSIX_arm64(arch);
136 break;
137 case llvm::Triple::mipsel:
138 case llvm::Triple::mips:
139 reg_interface = new RegisterContextLinux_mips(arch);
140 break;
141 case llvm::Triple::mips64el:
142 case llvm::Triple::mips64:
143 reg_interface = new RegisterContextLinux_mips64(arch);
144 break;
145 case llvm::Triple::systemz:
146 reg_interface = new RegisterContextLinux_s390x(arch);
147 break;
148 case llvm::Triple::x86:
149 reg_interface = new RegisterContextLinux_i386(arch);
150 break;
151 case llvm::Triple::x86_64:
152 reg_interface = new RegisterContextLinux_x86_64(arch);
153 break;
154 default:
155 break;
156 }
157 break;
158 }
159
160 case llvm::Triple::OpenBSD: {
161 switch (arch.GetMachine()) {
9
Control jumps to 'case x86_64:' at line 171
162 case llvm::Triple::aarch64:
163 reg_interface = new RegisterInfoPOSIX_arm64(arch);
164 break;
165 case llvm::Triple::arm:
166 reg_interface = new RegisterInfoPOSIX_arm(arch);
167 break;
168 case llvm::Triple::x86:
169 reg_interface = new RegisterContextOpenBSD_i386(arch);
170 break;
171 case llvm::Triple::x86_64:
172 reg_interface = new RegisterContextOpenBSD_x86_64(arch);
10
Memory is allocated
173 break;
11
Execution continues on line 177
174 default:
175 break;
176 }
177 break;
12
Execution continues on line 184
178 }
179
180 default:
181 break;
182 }
183
184 if (!reg_interface) {
13
Taking false branch
185 if (log)
186 log->Printf("elf-core::%s:: Architecture(%d) or OS(%d) not supported",
187 __FUNCTION__, arch.GetMachine(), arch.GetTriple().getOS());
188 assert(false && "Architecture or OS not supported")((false && "Architecture or OS not supported") ? static_cast
<void> (0) : __assert_fail ("false && \"Architecture or OS not supported\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/tools/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp"
, 188, __PRETTY_FUNCTION__))
;
189 }
190
191 switch (arch.GetMachine()) {
14
Control jumps to the 'default' case at line 225
192 case llvm::Triple::aarch64:
193 m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_arm64(
194 *this, reg_interface, m_gpregset_data, m_fpregset_data));
195 break;
196 case llvm::Triple::arm:
197 m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_arm(
198 *this, reg_interface, m_gpregset_data, m_fpregset_data));
199 break;
200 case llvm::Triple::mipsel:
201 case llvm::Triple::mips:
202 m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_mips64(
203 *this, reg_interface, m_gpregset_data, m_fpregset_data));
204 break;
205 case llvm::Triple::mips64:
206 case llvm::Triple::mips64el:
207 m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_mips64(
208 *this, reg_interface, m_gpregset_data, m_fpregset_data));
209 break;
210 case llvm::Triple::ppc:
211 case llvm::Triple::ppc64:
212 m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_powerpc(
213 *this, reg_interface, m_gpregset_data, m_fpregset_data,
214 m_vregset_data));
215 break;
216 case llvm::Triple::systemz:
217 m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_s390x(
218 *this, reg_interface, m_gpregset_data, m_fpregset_data));
219 break;
220 case llvm::Triple::x86:
221 case llvm::Triple::x86_64:
222 m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_x86_64(
223 *this, reg_interface, m_gpregset_data, m_fpregset_data));
224 break;
225 default:
226 break;
15
Execution continues on line 229
227 }
228
229 reg_ctx_sp = m_thread_reg_ctx_sp;
16
Potential leak of memory pointed to by 'reg_interface'
230 } else if (m_unwinder_ap.get()) {
231 reg_ctx_sp = m_unwinder_ap->CreateRegisterContextForFrame(frame);
232 }
233 return reg_ctx_sp;
234}
235
236bool ThreadElfCore::CalculateStopInfo() {
237 ProcessSP process_sp(GetProcess());
238 if (process_sp) {
239 SetStopInfo(StopInfo::CreateStopReasonWithSignal(*this, m_signo));
240 return true;
241 }
242 return false;
243}
244
245//----------------------------------------------------------------
246// Parse PRSTATUS from NOTE entry
247//----------------------------------------------------------------
248ELFLinuxPrStatus::ELFLinuxPrStatus() {
249 memset(this, 0, sizeof(ELFLinuxPrStatus));
250}
251
252size_t ELFLinuxPrStatus::GetSize(lldb_private::ArchSpec &arch) {
253 constexpr size_t mips_linux_pr_status_size_o32 = 96;
254 constexpr size_t mips_linux_pr_status_size_n32 = 72;
255 if (arch.IsMIPS()) {
256 std::string abi = arch.GetTargetABI();
257 assert(!abi.empty() && "ABI is not set")((!abi.empty() && "ABI is not set") ? static_cast<
void> (0) : __assert_fail ("!abi.empty() && \"ABI is not set\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/tools/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp"
, 257, __PRETTY_FUNCTION__))
;
258 if (!abi.compare("n64"))
259 return sizeof(ELFLinuxPrStatus);
260 else if (!abi.compare("o32"))
261 return mips_linux_pr_status_size_o32;
262 // N32 ABI
263 return mips_linux_pr_status_size_n32;
264 }
265 switch (arch.GetCore()) {
266 case lldb_private::ArchSpec::eCore_s390x_generic:
267 case lldb_private::ArchSpec::eCore_x86_64_x86_64:
268 return sizeof(ELFLinuxPrStatus);
269 case lldb_private::ArchSpec::eCore_x86_32_i386:
270 case lldb_private::ArchSpec::eCore_x86_32_i486:
271 return 72;
272 default:
273 return 0;
274 }
275}
276
277Status ELFLinuxPrStatus::Parse(DataExtractor &data, ArchSpec &arch) {
278 Status error;
279 if (GetSize(arch) > data.GetByteSize()) {
280 error.SetErrorStringWithFormat(
281 "NT_PRSTATUS size should be %zu, but the remaining bytes are: %" PRIu64"l" "u",
282 GetSize(arch), data.GetByteSize());
283 return error;
284 }
285
286 // Read field by field to correctly account for endianess
287 // of both the core dump and the platform running lldb.
288 offset_t offset = 0;
289 si_signo = data.GetU32(&offset);
290 si_code = data.GetU32(&offset);
291 si_errno = data.GetU32(&offset);
292
293 pr_cursig = data.GetU16(&offset);
294 offset += 2; // pad
295
296 pr_sigpend = data.GetPointer(&offset);
297 pr_sighold = data.GetPointer(&offset);
298
299 pr_pid = data.GetU32(&offset);
300 pr_ppid = data.GetU32(&offset);
301 pr_pgrp = data.GetU32(&offset);
302 pr_sid = data.GetU32(&offset);
303
304 pr_utime.tv_sec = data.GetPointer(&offset);
305 pr_utime.tv_usec = data.GetPointer(&offset);
306
307 pr_stime.tv_sec = data.GetPointer(&offset);
308 pr_stime.tv_usec = data.GetPointer(&offset);
309
310 pr_cutime.tv_sec = data.GetPointer(&offset);
311 pr_cutime.tv_usec = data.GetPointer(&offset);
312
313 pr_cstime.tv_sec = data.GetPointer(&offset);
314 pr_cstime.tv_usec = data.GetPointer(&offset);
315
316 return error;
317}
318
319//----------------------------------------------------------------
320// Parse PRPSINFO from NOTE entry
321//----------------------------------------------------------------
322ELFLinuxPrPsInfo::ELFLinuxPrPsInfo() {
323 memset(this, 0, sizeof(ELFLinuxPrPsInfo));
324}
325
326size_t ELFLinuxPrPsInfo::GetSize(lldb_private::ArchSpec &arch) {
327 constexpr size_t mips_linux_pr_psinfo_size_o32_n32 = 128;
328 if (arch.IsMIPS()) {
329 uint8_t address_byte_size = arch.GetAddressByteSize();
330 if (address_byte_size == 8)
331 return sizeof(ELFLinuxPrPsInfo);
332 return mips_linux_pr_psinfo_size_o32_n32;
333 }
334
335 switch (arch.GetCore()) {
336 case lldb_private::ArchSpec::eCore_s390x_generic:
337 case lldb_private::ArchSpec::eCore_x86_64_x86_64:
338 return sizeof(ELFLinuxPrPsInfo);
339 case lldb_private::ArchSpec::eCore_x86_32_i386:
340 case lldb_private::ArchSpec::eCore_x86_32_i486:
341 return 124;
342 default:
343 return 0;
344 }
345}
346
347Status ELFLinuxPrPsInfo::Parse(DataExtractor &data, ArchSpec &arch) {
348 Status error;
349 ByteOrder byteorder = data.GetByteOrder();
350 if (GetSize(arch) > data.GetByteSize()) {
351 error.SetErrorStringWithFormat(
352 "NT_PRPSINFO size should be %zu, but the remaining bytes are: %" PRIu64"l" "u",
353 GetSize(arch), data.GetByteSize());
354 return error;
355 }
356 size_t size = 0;
357 offset_t offset = 0;
358
359 pr_state = data.GetU8(&offset);
360 pr_sname = data.GetU8(&offset);
361 pr_zomb = data.GetU8(&offset);
362 pr_nice = data.GetU8(&offset);
363 if (data.GetAddressByteSize() == 8) {
364 // Word align the next field on 64 bit.
365 offset += 4;
366 }
367
368 pr_flag = data.GetPointer(&offset);
369
370 if (arch.IsMIPS()) {
371 // The pr_uid and pr_gid is always 32 bit irrespective of platforms
372 pr_uid = data.GetU32(&offset);
373 pr_gid = data.GetU32(&offset);
374 } else {
375 // 16 bit on 32 bit platforms, 32 bit on 64 bit platforms
376 pr_uid = data.GetMaxU64(&offset, data.GetAddressByteSize() >> 1);
377 pr_gid = data.GetMaxU64(&offset, data.GetAddressByteSize() >> 1);
378 }
379
380 pr_pid = data.GetU32(&offset);
381 pr_ppid = data.GetU32(&offset);
382 pr_pgrp = data.GetU32(&offset);
383 pr_sid = data.GetU32(&offset);
384
385 size = 16;
386 data.ExtractBytes(offset, size, byteorder, pr_fname);
387 offset += size;
388
389 size = 80;
390 data.ExtractBytes(offset, size, byteorder, pr_psargs);
391 offset += size;
392
393 return error;
394}
395
396//----------------------------------------------------------------
397// Parse SIGINFO from NOTE entry
398//----------------------------------------------------------------
399ELFLinuxSigInfo::ELFLinuxSigInfo() { memset(this, 0, sizeof(ELFLinuxSigInfo)); }
400
401size_t ELFLinuxSigInfo::GetSize(const lldb_private::ArchSpec &arch) {
402 if (arch.IsMIPS())
403 return sizeof(ELFLinuxSigInfo);
404 switch (arch.GetCore()) {
405 case lldb_private::ArchSpec::eCore_x86_64_x86_64:
406 return sizeof(ELFLinuxSigInfo);
407 case lldb_private::ArchSpec::eCore_s390x_generic:
408 case lldb_private::ArchSpec::eCore_x86_32_i386:
409 case lldb_private::ArchSpec::eCore_x86_32_i486:
410 return 12;
411 default:
412 return 0;
413 }
414}
415
416Status ELFLinuxSigInfo::Parse(DataExtractor &data, const ArchSpec &arch) {
417 Status error;
418 if (GetSize(arch) > data.GetByteSize()) {
419 error.SetErrorStringWithFormat(
420 "NT_SIGINFO size should be %zu, but the remaining bytes are: %" PRIu64"l" "u",
421 GetSize(arch), data.GetByteSize());
422 return error;
423 }
424
425 // Parsing from a 32 bit ELF core file, and populating/reusing the structure
426 // properly, because the struct is for the 64 bit version
427 offset_t offset = 0;
428 si_signo = data.GetU32(&offset);
429 si_code = data.GetU32(&offset);
430 si_errno = data.GetU32(&offset);
431
432 return error;
433}