Bug Summary

File:tools/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp
Warning:line 179, 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_i386.h"
22#include "Plugins/Process/Utility/RegisterContextLinux_s390x.h"
23#include "Plugins/Process/Utility/RegisterContextLinux_x86_64.h"
24#include "Plugins/Process/Utility/RegisterInfoPOSIX_arm.h"
25#include "Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h"
26#include "ProcessElfCore.h"
27#include "RegisterContextPOSIXCore_arm.h"
28#include "RegisterContextPOSIXCore_arm64.h"
29#include "RegisterContextPOSIXCore_mips64.h"
30#include "RegisterContextPOSIXCore_powerpc.h"
31#include "RegisterContextPOSIXCore_s390x.h"
32#include "RegisterContextPOSIXCore_x86_64.h"
33#include "ThreadElfCore.h"
34
35using namespace lldb;
36using namespace lldb_private;
37
38//----------------------------------------------------------------------
39// Construct a Thread object with given data
40//----------------------------------------------------------------------
41ThreadElfCore::ThreadElfCore(Process &process, const ThreadData &td)
42 : Thread(process, td.tid), m_thread_name(td.name), m_thread_reg_ctx_sp(),
43 m_signo(td.signo), m_gpregset_data(td.gpregset),
44 m_fpregset_data(td.fpregset), m_vregset_data(td.vregset) {}
45
46ThreadElfCore::~ThreadElfCore() { DestroyThread(); }
47
48void ThreadElfCore::RefreshStateAfterStop() {
49 GetRegisterContext()->InvalidateIfNeeded(false);
1
Calling 'ThreadElfCore::GetRegisterContext'
50}
51
52void ThreadElfCore::ClearStackFrames() {
53 Unwind *unwinder = GetUnwinder();
54 if (unwinder)
55 unwinder->Clear();
56 Thread::ClearStackFrames();
57}
58
59RegisterContextSP ThreadElfCore::GetRegisterContext() {
60 if (m_reg_context_sp.get() == NULL__null) {
2
Assuming the condition is true
3
Taking true branch
61 m_reg_context_sp = CreateRegisterContextForFrame(NULL__null);
4
Calling 'ThreadElfCore::CreateRegisterContextForFrame'
62 }
63 return m_reg_context_sp;
64}
65
66RegisterContextSP
67ThreadElfCore::CreateRegisterContextForFrame(StackFrame *frame) {
68 RegisterContextSP reg_ctx_sp;
69 uint32_t concrete_frame_idx = 0;
70 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD(1u << 2)));
71
72 if (frame)
5
Taking false branch
73 concrete_frame_idx = frame->GetConcreteFrameIndex();
74
75 if (concrete_frame_idx == 0) {
6
Taking true branch
76 if (m_thread_reg_ctx_sp)
7
Taking false branch
77 return m_thread_reg_ctx_sp;
78
79 ProcessElfCore *process = static_cast<ProcessElfCore *>(GetProcess().get());
80 ArchSpec arch = process->GetArchitecture();
81 RegisterInfoInterface *reg_interface = NULL__null;
82
83 switch (arch.GetTriple().getOS()) {
8
Control jumps to 'case Linux:' at line 113
84 case llvm::Triple::FreeBSD: {
85 switch (arch.GetMachine()) {
86 case llvm::Triple::aarch64:
87 reg_interface = new RegisterInfoPOSIX_arm64(arch);
88 break;
89 case llvm::Triple::arm:
90 reg_interface = new RegisterInfoPOSIX_arm(arch);
91 break;
92 case llvm::Triple::ppc:
93 reg_interface = new RegisterContextFreeBSD_powerpc32(arch);
94 break;
95 case llvm::Triple::ppc64:
96 reg_interface = new RegisterContextFreeBSD_powerpc64(arch);
97 break;
98 case llvm::Triple::mips64:
99 reg_interface = new RegisterContextFreeBSD_mips64(arch);
100 break;
101 case llvm::Triple::x86:
102 reg_interface = new RegisterContextFreeBSD_i386(arch);
103 break;
104 case llvm::Triple::x86_64:
105 reg_interface = new RegisterContextFreeBSD_x86_64(arch);
106 break;
107 default:
108 break;
109 }
110 break;
111 }
112
113 case llvm::Triple::Linux: {
114 switch (arch.GetMachine()) {
9
Control jumps to 'case x86_64:' at line 127
115 case llvm::Triple::arm:
116 reg_interface = new RegisterInfoPOSIX_arm(arch);
117 break;
118 case llvm::Triple::aarch64:
119 reg_interface = new RegisterInfoPOSIX_arm64(arch);
120 break;
121 case llvm::Triple::systemz:
122 reg_interface = new RegisterContextLinux_s390x(arch);
123 break;
124 case llvm::Triple::x86:
125 reg_interface = new RegisterContextLinux_i386(arch);
126 break;
127 case llvm::Triple::x86_64:
128 reg_interface = new RegisterContextLinux_x86_64(arch);
10
Memory is allocated
129 break;
11
Execution continues on line 133
130 default:
131 break;
132 }
133 break;
12
Execution continues on line 140
134 }
135
136 default:
137 break;
138 }
139
140 if (!reg_interface) {
13
Taking false branch
141 if (log)
142 log->Printf("elf-core::%s:: Architecture(%d) or OS(%d) not supported",
143 __FUNCTION__, arch.GetMachine(), arch.GetTriple().getOS());
144 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\""
, "/tmp/buildd/llvm-toolchain-snapshot-5.0~svn298304/tools/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp"
, 144, __PRETTY_FUNCTION__))
;
145 }
146
147 switch (arch.GetMachine()) {
14
Control jumps to the 'default' case at line 175
148 case llvm::Triple::aarch64:
149 m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_arm64(
150 *this, reg_interface, m_gpregset_data, m_fpregset_data));
151 break;
152 case llvm::Triple::arm:
153 m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_arm(
154 *this, reg_interface, m_gpregset_data, m_fpregset_data));
155 break;
156 case llvm::Triple::mips64:
157 m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_mips64(
158 *this, reg_interface, m_gpregset_data, m_fpregset_data));
159 break;
160 case llvm::Triple::ppc:
161 case llvm::Triple::ppc64:
162 m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_powerpc(
163 *this, reg_interface, m_gpregset_data, m_fpregset_data,
164 m_vregset_data));
165 break;
166 case llvm::Triple::systemz:
167 m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_s390x(
168 *this, reg_interface, m_gpregset_data, m_fpregset_data));
169 break;
170 case llvm::Triple::x86:
171 case llvm::Triple::x86_64:
172 m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_x86_64(
173 *this, reg_interface, m_gpregset_data, m_fpregset_data));
174 break;
175 default:
176 break;
15
Execution continues on line 179
177 }
178
179 reg_ctx_sp = m_thread_reg_ctx_sp;
16
Potential leak of memory pointed to by 'reg_interface'
180 } else if (m_unwinder_ap.get()) {
181 reg_ctx_sp = m_unwinder_ap->CreateRegisterContextForFrame(frame);
182 }
183 return reg_ctx_sp;
184}
185
186bool ThreadElfCore::CalculateStopInfo() {
187 ProcessSP process_sp(GetProcess());
188 if (process_sp) {
189 SetStopInfo(StopInfo::CreateStopReasonWithSignal(*this, m_signo));
190 return true;
191 }
192 return false;
193}
194
195//----------------------------------------------------------------
196// Parse PRSTATUS from NOTE entry
197//----------------------------------------------------------------
198ELFLinuxPrStatus::ELFLinuxPrStatus() {
199 memset(this, 0, sizeof(ELFLinuxPrStatus));
200}
201
202Error ELFLinuxPrStatus::Parse(DataExtractor &data, ArchSpec &arch) {
203 Error error;
204 if (GetSize(arch) > data.GetByteSize()) {
205 error.SetErrorStringWithFormat(
206 "NT_PRSTATUS size should be %zu, but the remaining bytes are: %" PRIu64"l" "u",
207 GetSize(arch), data.GetByteSize());
208 return error;
209 }
210
211 // Read field by field to correctly account for endianess
212 // of both the core dump and the platform running lldb.
213 offset_t offset = 0;
214 si_signo = data.GetU32(&offset);
215 si_code = data.GetU32(&offset);
216 si_errno = data.GetU32(&offset);
217
218 pr_cursig = data.GetU16(&offset);
219 offset += 2; // pad
220
221 pr_sigpend = data.GetPointer(&offset);
222 pr_sighold = data.GetPointer(&offset);
223
224 pr_pid = data.GetU32(&offset);
225 pr_ppid = data.GetU32(&offset);
226 pr_pgrp = data.GetU32(&offset);
227 pr_sid = data.GetU32(&offset);
228
229 pr_utime.tv_sec = data.GetPointer(&offset);
230 pr_utime.tv_usec = data.GetPointer(&offset);
231
232 pr_stime.tv_sec = data.GetPointer(&offset);
233 pr_stime.tv_usec = data.GetPointer(&offset);
234
235 pr_cutime.tv_sec = data.GetPointer(&offset);
236 pr_cutime.tv_usec = data.GetPointer(&offset);
237
238 pr_cstime.tv_sec = data.GetPointer(&offset);
239 pr_cstime.tv_usec = data.GetPointer(&offset);
240
241
242 return error;
243}
244
245//----------------------------------------------------------------
246// Parse PRPSINFO from NOTE entry
247//----------------------------------------------------------------
248ELFLinuxPrPsInfo::ELFLinuxPrPsInfo() {
249 memset(this, 0, sizeof(ELFLinuxPrPsInfo));
250}
251
252Error ELFLinuxPrPsInfo::Parse(DataExtractor &data, ArchSpec &arch) {
253 Error error;
254 ByteOrder byteorder = data.GetByteOrder();
255 if (GetSize(arch) > data.GetByteSize()) {
256 error.SetErrorStringWithFormat(
257 "NT_PRPSINFO size should be %zu, but the remaining bytes are: %" PRIu64"l" "u",
258 GetSize(arch), data.GetByteSize());
259 return error;
260 }
261 size_t size = 0;
262 offset_t offset = 0;
263
264 pr_state = data.GetU8(&offset);
265 pr_sname = data.GetU8(&offset);
266 pr_zomb = data.GetU8(&offset);
267 pr_nice = data.GetU8(&offset);
268 if (data.GetAddressByteSize() == 8) {
269 // Word align the next field on 64 bit.
270 offset += 4;
271 }
272
273 pr_flag = data.GetPointer(&offset);
274
275 // 16 bit on 32 bit platforms, 32 bit on 64 bit platforms
276 pr_uid = data.GetMaxU64(&offset, data.GetAddressByteSize() >> 1);
277 pr_gid = data.GetMaxU64(&offset, data.GetAddressByteSize() >> 1);
278
279 pr_pid = data.GetU32(&offset);
280 pr_ppid = data.GetU32(&offset);
281 pr_pgrp = data.GetU32(&offset);
282 pr_sid = data.GetU32(&offset);
283
284 size = 16;
285 data.ExtractBytes(offset, size, byteorder, pr_fname);
286 offset += size;
287
288 size = 80;
289 data.ExtractBytes(offset, size, byteorder, pr_psargs);
290 offset += size;
291
292 return error;
293}
294
295//----------------------------------------------------------------
296// Parse SIGINFO from NOTE entry
297//----------------------------------------------------------------
298ELFLinuxSigInfo::ELFLinuxSigInfo() {
299 memset(this, 0, sizeof(ELFLinuxSigInfo));
300}
301
302Error ELFLinuxSigInfo::Parse(DataExtractor &data, const ArchSpec &arch) {
303 Error error;
304 if (GetSize(arch) > data.GetByteSize()) {
305 error.SetErrorStringWithFormat(
306 "NT_SIGINFO size should be %zu, but the remaining bytes are: %" PRIu64"l" "u",
307 GetSize(arch), data.GetByteSize());
308 return error;
309 }
310
311 // Parsing from a 32 bit ELF core file, and populating/reusing the structure
312 // properly, because the struct is for the 64 bit version
313 offset_t offset = 0;
314 si_signo = data.GetU32(&offset);
315 si_code = data.GetU32(&offset);
316 si_errno = data.GetU32(&offset);
317
318 return error;
319}