File: | build/llvm-toolchain-snapshot-15~++20220420111733+e13d2efed663/lldb/source/API/SBFrame.cpp |
Warning: | line 421, column 15 Value stored to 'frame' during its initialization is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | //===-- SBFrame.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 <algorithm> |
10 | #include <set> |
11 | #include <string> |
12 | |
13 | #include "lldb/API/SBFrame.h" |
14 | |
15 | #include "lldb/lldb-types.h" |
16 | |
17 | #include "Utils.h" |
18 | #include "lldb/Core/Address.h" |
19 | #include "lldb/Core/StreamFile.h" |
20 | #include "lldb/Core/ValueObjectRegister.h" |
21 | #include "lldb/Core/ValueObjectVariable.h" |
22 | #include "lldb/Expression/ExpressionVariable.h" |
23 | #include "lldb/Expression/UserExpression.h" |
24 | #include "lldb/Host/Host.h" |
25 | #include "lldb/Symbol/Block.h" |
26 | #include "lldb/Symbol/Function.h" |
27 | #include "lldb/Symbol/Symbol.h" |
28 | #include "lldb/Symbol/SymbolContext.h" |
29 | #include "lldb/Symbol/Variable.h" |
30 | #include "lldb/Symbol/VariableList.h" |
31 | #include "lldb/Target/ExecutionContext.h" |
32 | #include "lldb/Target/Process.h" |
33 | #include "lldb/Target/RegisterContext.h" |
34 | #include "lldb/Target/StackFrame.h" |
35 | #include "lldb/Target/StackFrameRecognizer.h" |
36 | #include "lldb/Target/StackID.h" |
37 | #include "lldb/Target/Target.h" |
38 | #include "lldb/Target/Thread.h" |
39 | #include "lldb/Utility/ConstString.h" |
40 | #include "lldb/Utility/Instrumentation.h" |
41 | #include "lldb/Utility/LLDBLog.h" |
42 | #include "lldb/Utility/Stream.h" |
43 | |
44 | #include "lldb/API/SBAddress.h" |
45 | #include "lldb/API/SBDebugger.h" |
46 | #include "lldb/API/SBExpressionOptions.h" |
47 | #include "lldb/API/SBStream.h" |
48 | #include "lldb/API/SBSymbolContext.h" |
49 | #include "lldb/API/SBThread.h" |
50 | #include "lldb/API/SBValue.h" |
51 | #include "lldb/API/SBVariablesOptions.h" |
52 | |
53 | #include "llvm/Support/PrettyStackTrace.h" |
54 | |
55 | using namespace lldb; |
56 | using namespace lldb_private; |
57 | |
58 | SBFrame::SBFrame() : m_opaque_sp(new ExecutionContextRef()) { |
59 | LLDB_INSTRUMENT_VA(this)lldb_private::instrumentation::Instrumenter _instr( __PRETTY_FUNCTION__ , lldb_private::instrumentation::stringify_args(this));; |
60 | } |
61 | |
62 | SBFrame::SBFrame(const StackFrameSP &lldb_object_sp) |
63 | : m_opaque_sp(new ExecutionContextRef(lldb_object_sp)) { |
64 | LLDB_INSTRUMENT_VA(this, lldb_object_sp)lldb_private::instrumentation::Instrumenter _instr( __PRETTY_FUNCTION__ , lldb_private::instrumentation::stringify_args(this, lldb_object_sp ));; |
65 | } |
66 | |
67 | SBFrame::SBFrame(const SBFrame &rhs) { |
68 | LLDB_INSTRUMENT_VA(this, rhs)lldb_private::instrumentation::Instrumenter _instr( __PRETTY_FUNCTION__ , lldb_private::instrumentation::stringify_args(this, rhs));; |
69 | |
70 | m_opaque_sp = clone(rhs.m_opaque_sp); |
71 | } |
72 | |
73 | SBFrame::~SBFrame() = default; |
74 | |
75 | const SBFrame &SBFrame::operator=(const SBFrame &rhs) { |
76 | LLDB_INSTRUMENT_VA(this, rhs)lldb_private::instrumentation::Instrumenter _instr( __PRETTY_FUNCTION__ , lldb_private::instrumentation::stringify_args(this, rhs));; |
77 | |
78 | if (this != &rhs) |
79 | m_opaque_sp = clone(rhs.m_opaque_sp); |
80 | return *this; |
81 | } |
82 | |
83 | StackFrameSP SBFrame::GetFrameSP() const { |
84 | return (m_opaque_sp ? m_opaque_sp->GetFrameSP() : StackFrameSP()); |
85 | } |
86 | |
87 | void SBFrame::SetFrameSP(const StackFrameSP &lldb_object_sp) { |
88 | return m_opaque_sp->SetFrameSP(lldb_object_sp); |
89 | } |
90 | |
91 | bool SBFrame::IsValid() const { |
92 | LLDB_INSTRUMENT_VA(this)lldb_private::instrumentation::Instrumenter _instr( __PRETTY_FUNCTION__ , lldb_private::instrumentation::stringify_args(this));; |
93 | return this->operator bool(); |
94 | } |
95 | SBFrame::operator bool() const { |
96 | LLDB_INSTRUMENT_VA(this)lldb_private::instrumentation::Instrumenter _instr( __PRETTY_FUNCTION__ , lldb_private::instrumentation::stringify_args(this));; |
97 | |
98 | std::unique_lock<std::recursive_mutex> lock; |
99 | ExecutionContext exe_ctx(m_opaque_sp.get(), lock); |
100 | |
101 | Target *target = exe_ctx.GetTargetPtr(); |
102 | Process *process = exe_ctx.GetProcessPtr(); |
103 | if (target && process) { |
104 | Process::StopLocker stop_locker; |
105 | if (stop_locker.TryLock(&process->GetRunLock())) |
106 | return GetFrameSP().get() != nullptr; |
107 | } |
108 | |
109 | // Without a target & process we can't have a valid stack frame. |
110 | return false; |
111 | } |
112 | |
113 | SBSymbolContext SBFrame::GetSymbolContext(uint32_t resolve_scope) const { |
114 | LLDB_INSTRUMENT_VA(this, resolve_scope)lldb_private::instrumentation::Instrumenter _instr( __PRETTY_FUNCTION__ , lldb_private::instrumentation::stringify_args(this, resolve_scope ));; |
115 | |
116 | SBSymbolContext sb_sym_ctx; |
117 | std::unique_lock<std::recursive_mutex> lock; |
118 | ExecutionContext exe_ctx(m_opaque_sp.get(), lock); |
119 | SymbolContextItem scope = static_cast<SymbolContextItem>(resolve_scope); |
120 | Target *target = exe_ctx.GetTargetPtr(); |
121 | Process *process = exe_ctx.GetProcessPtr(); |
122 | if (target && process) { |
123 | Process::StopLocker stop_locker; |
124 | if (stop_locker.TryLock(&process->GetRunLock())) { |
125 | if (StackFrame *frame = exe_ctx.GetFramePtr()) |
126 | sb_sym_ctx = frame->GetSymbolContext(scope); |
127 | } |
128 | } |
129 | |
130 | return sb_sym_ctx; |
131 | } |
132 | |
133 | SBModule SBFrame::GetModule() const { |
134 | LLDB_INSTRUMENT_VA(this)lldb_private::instrumentation::Instrumenter _instr( __PRETTY_FUNCTION__ , lldb_private::instrumentation::stringify_args(this));; |
135 | |
136 | SBModule sb_module; |
137 | ModuleSP module_sp; |
138 | std::unique_lock<std::recursive_mutex> lock; |
139 | ExecutionContext exe_ctx(m_opaque_sp.get(), lock); |
140 | |
141 | StackFrame *frame = nullptr; |
142 | Target *target = exe_ctx.GetTargetPtr(); |
143 | Process *process = exe_ctx.GetProcessPtr(); |
144 | if (target && process) { |
145 | Process::StopLocker stop_locker; |
146 | if (stop_locker.TryLock(&process->GetRunLock())) { |
147 | frame = exe_ctx.GetFramePtr(); |
148 | if (frame) { |
149 | module_sp = frame->GetSymbolContext(eSymbolContextModule).module_sp; |
150 | sb_module.SetSP(module_sp); |
151 | } |
152 | } |
153 | } |
154 | |
155 | return sb_module; |
156 | } |
157 | |
158 | SBCompileUnit SBFrame::GetCompileUnit() const { |
159 | LLDB_INSTRUMENT_VA(this)lldb_private::instrumentation::Instrumenter _instr( __PRETTY_FUNCTION__ , lldb_private::instrumentation::stringify_args(this));; |
160 | |
161 | SBCompileUnit sb_comp_unit; |
162 | std::unique_lock<std::recursive_mutex> lock; |
163 | ExecutionContext exe_ctx(m_opaque_sp.get(), lock); |
164 | |
165 | StackFrame *frame = nullptr; |
166 | Target *target = exe_ctx.GetTargetPtr(); |
167 | Process *process = exe_ctx.GetProcessPtr(); |
168 | if (target && process) { |
169 | Process::StopLocker stop_locker; |
170 | if (stop_locker.TryLock(&process->GetRunLock())) { |
171 | frame = exe_ctx.GetFramePtr(); |
172 | if (frame) { |
173 | sb_comp_unit.reset( |
174 | frame->GetSymbolContext(eSymbolContextCompUnit).comp_unit); |
175 | } |
176 | } |
177 | } |
178 | |
179 | return sb_comp_unit; |
180 | } |
181 | |
182 | SBFunction SBFrame::GetFunction() const { |
183 | LLDB_INSTRUMENT_VA(this)lldb_private::instrumentation::Instrumenter _instr( __PRETTY_FUNCTION__ , lldb_private::instrumentation::stringify_args(this));; |
184 | |
185 | SBFunction sb_function; |
186 | std::unique_lock<std::recursive_mutex> lock; |
187 | ExecutionContext exe_ctx(m_opaque_sp.get(), lock); |
188 | |
189 | StackFrame *frame = nullptr; |
190 | Target *target = exe_ctx.GetTargetPtr(); |
191 | Process *process = exe_ctx.GetProcessPtr(); |
192 | if (target && process) { |
193 | Process::StopLocker stop_locker; |
194 | if (stop_locker.TryLock(&process->GetRunLock())) { |
195 | frame = exe_ctx.GetFramePtr(); |
196 | if (frame) { |
197 | sb_function.reset( |
198 | frame->GetSymbolContext(eSymbolContextFunction).function); |
199 | } |
200 | } |
201 | } |
202 | |
203 | return sb_function; |
204 | } |
205 | |
206 | SBSymbol SBFrame::GetSymbol() const { |
207 | LLDB_INSTRUMENT_VA(this)lldb_private::instrumentation::Instrumenter _instr( __PRETTY_FUNCTION__ , lldb_private::instrumentation::stringify_args(this));; |
208 | |
209 | SBSymbol sb_symbol; |
210 | std::unique_lock<std::recursive_mutex> lock; |
211 | ExecutionContext exe_ctx(m_opaque_sp.get(), lock); |
212 | |
213 | StackFrame *frame = nullptr; |
214 | Target *target = exe_ctx.GetTargetPtr(); |
215 | Process *process = exe_ctx.GetProcessPtr(); |
216 | if (target && process) { |
217 | Process::StopLocker stop_locker; |
218 | if (stop_locker.TryLock(&process->GetRunLock())) { |
219 | frame = exe_ctx.GetFramePtr(); |
220 | if (frame) { |
221 | sb_symbol.reset(frame->GetSymbolContext(eSymbolContextSymbol).symbol); |
222 | } |
223 | } |
224 | } |
225 | |
226 | return sb_symbol; |
227 | } |
228 | |
229 | SBBlock SBFrame::GetBlock() const { |
230 | LLDB_INSTRUMENT_VA(this)lldb_private::instrumentation::Instrumenter _instr( __PRETTY_FUNCTION__ , lldb_private::instrumentation::stringify_args(this));; |
231 | |
232 | SBBlock sb_block; |
233 | std::unique_lock<std::recursive_mutex> lock; |
234 | ExecutionContext exe_ctx(m_opaque_sp.get(), lock); |
235 | |
236 | StackFrame *frame = nullptr; |
237 | Target *target = exe_ctx.GetTargetPtr(); |
238 | Process *process = exe_ctx.GetProcessPtr(); |
239 | if (target && process) { |
240 | Process::StopLocker stop_locker; |
241 | if (stop_locker.TryLock(&process->GetRunLock())) { |
242 | frame = exe_ctx.GetFramePtr(); |
243 | if (frame) |
244 | sb_block.SetPtr(frame->GetSymbolContext(eSymbolContextBlock).block); |
245 | } |
246 | } |
247 | return sb_block; |
248 | } |
249 | |
250 | SBBlock SBFrame::GetFrameBlock() const { |
251 | LLDB_INSTRUMENT_VA(this)lldb_private::instrumentation::Instrumenter _instr( __PRETTY_FUNCTION__ , lldb_private::instrumentation::stringify_args(this));; |
252 | |
253 | SBBlock sb_block; |
254 | std::unique_lock<std::recursive_mutex> lock; |
255 | ExecutionContext exe_ctx(m_opaque_sp.get(), lock); |
256 | |
257 | StackFrame *frame = nullptr; |
258 | Target *target = exe_ctx.GetTargetPtr(); |
259 | Process *process = exe_ctx.GetProcessPtr(); |
260 | if (target && process) { |
261 | Process::StopLocker stop_locker; |
262 | if (stop_locker.TryLock(&process->GetRunLock())) { |
263 | frame = exe_ctx.GetFramePtr(); |
264 | if (frame) |
265 | sb_block.SetPtr(frame->GetFrameBlock()); |
266 | } |
267 | } |
268 | return sb_block; |
269 | } |
270 | |
271 | SBLineEntry SBFrame::GetLineEntry() const { |
272 | LLDB_INSTRUMENT_VA(this)lldb_private::instrumentation::Instrumenter _instr( __PRETTY_FUNCTION__ , lldb_private::instrumentation::stringify_args(this));; |
273 | |
274 | SBLineEntry sb_line_entry; |
275 | std::unique_lock<std::recursive_mutex> lock; |
276 | ExecutionContext exe_ctx(m_opaque_sp.get(), lock); |
277 | |
278 | StackFrame *frame = nullptr; |
279 | Target *target = exe_ctx.GetTargetPtr(); |
280 | Process *process = exe_ctx.GetProcessPtr(); |
281 | if (target && process) { |
282 | Process::StopLocker stop_locker; |
283 | if (stop_locker.TryLock(&process->GetRunLock())) { |
284 | frame = exe_ctx.GetFramePtr(); |
285 | if (frame) { |
286 | sb_line_entry.SetLineEntry( |
287 | frame->GetSymbolContext(eSymbolContextLineEntry).line_entry); |
288 | } |
289 | } |
290 | } |
291 | return sb_line_entry; |
292 | } |
293 | |
294 | uint32_t SBFrame::GetFrameID() const { |
295 | LLDB_INSTRUMENT_VA(this)lldb_private::instrumentation::Instrumenter _instr( __PRETTY_FUNCTION__ , lldb_private::instrumentation::stringify_args(this));; |
296 | |
297 | uint32_t frame_idx = UINT32_MAX(4294967295U); |
298 | |
299 | std::unique_lock<std::recursive_mutex> lock; |
300 | ExecutionContext exe_ctx(m_opaque_sp.get(), lock); |
301 | |
302 | StackFrame *frame = exe_ctx.GetFramePtr(); |
303 | if (frame) |
304 | frame_idx = frame->GetFrameIndex(); |
305 | |
306 | return frame_idx; |
307 | } |
308 | |
309 | lldb::addr_t SBFrame::GetCFA() const { |
310 | LLDB_INSTRUMENT_VA(this)lldb_private::instrumentation::Instrumenter _instr( __PRETTY_FUNCTION__ , lldb_private::instrumentation::stringify_args(this));; |
311 | |
312 | std::unique_lock<std::recursive_mutex> lock; |
313 | ExecutionContext exe_ctx(m_opaque_sp.get(), lock); |
314 | |
315 | StackFrame *frame = exe_ctx.GetFramePtr(); |
316 | if (frame) |
317 | return frame->GetStackID().GetCallFrameAddress(); |
318 | return LLDB_INVALID_ADDRESS(18446744073709551615UL); |
319 | } |
320 | |
321 | addr_t SBFrame::GetPC() const { |
322 | LLDB_INSTRUMENT_VA(this)lldb_private::instrumentation::Instrumenter _instr( __PRETTY_FUNCTION__ , lldb_private::instrumentation::stringify_args(this));; |
323 | |
324 | addr_t addr = LLDB_INVALID_ADDRESS(18446744073709551615UL); |
325 | std::unique_lock<std::recursive_mutex> lock; |
326 | ExecutionContext exe_ctx(m_opaque_sp.get(), lock); |
327 | |
328 | StackFrame *frame = nullptr; |
329 | Target *target = exe_ctx.GetTargetPtr(); |
330 | Process *process = exe_ctx.GetProcessPtr(); |
331 | if (target && process) { |
332 | Process::StopLocker stop_locker; |
333 | if (stop_locker.TryLock(&process->GetRunLock())) { |
334 | frame = exe_ctx.GetFramePtr(); |
335 | if (frame) { |
336 | addr = frame->GetFrameCodeAddress().GetOpcodeLoadAddress( |
337 | target, AddressClass::eCode); |
338 | } |
339 | } |
340 | } |
341 | |
342 | return addr; |
343 | } |
344 | |
345 | bool SBFrame::SetPC(addr_t new_pc) { |
346 | LLDB_INSTRUMENT_VA(this, new_pc)lldb_private::instrumentation::Instrumenter _instr( __PRETTY_FUNCTION__ , lldb_private::instrumentation::stringify_args(this, new_pc) );; |
347 | |
348 | bool ret_val = false; |
349 | std::unique_lock<std::recursive_mutex> lock; |
350 | ExecutionContext exe_ctx(m_opaque_sp.get(), lock); |
351 | |
352 | Target *target = exe_ctx.GetTargetPtr(); |
353 | Process *process = exe_ctx.GetProcessPtr(); |
354 | if (target && process) { |
355 | Process::StopLocker stop_locker; |
356 | if (stop_locker.TryLock(&process->GetRunLock())) { |
357 | if (StackFrame *frame = exe_ctx.GetFramePtr()) { |
358 | if (RegisterContextSP reg_ctx_sp = frame->GetRegisterContext()) { |
359 | ret_val = reg_ctx_sp->SetPC(new_pc); |
360 | } |
361 | } |
362 | } |
363 | } |
364 | |
365 | return ret_val; |
366 | } |
367 | |
368 | addr_t SBFrame::GetSP() const { |
369 | LLDB_INSTRUMENT_VA(this)lldb_private::instrumentation::Instrumenter _instr( __PRETTY_FUNCTION__ , lldb_private::instrumentation::stringify_args(this));; |
370 | |
371 | addr_t addr = LLDB_INVALID_ADDRESS(18446744073709551615UL); |
372 | std::unique_lock<std::recursive_mutex> lock; |
373 | ExecutionContext exe_ctx(m_opaque_sp.get(), lock); |
374 | |
375 | Target *target = exe_ctx.GetTargetPtr(); |
376 | Process *process = exe_ctx.GetProcessPtr(); |
377 | if (target && process) { |
378 | Process::StopLocker stop_locker; |
379 | if (stop_locker.TryLock(&process->GetRunLock())) { |
380 | if (StackFrame *frame = exe_ctx.GetFramePtr()) { |
381 | if (RegisterContextSP reg_ctx_sp = frame->GetRegisterContext()) { |
382 | addr = reg_ctx_sp->GetSP(); |
383 | } |
384 | } |
385 | } |
386 | } |
387 | |
388 | return addr; |
389 | } |
390 | |
391 | addr_t SBFrame::GetFP() const { |
392 | LLDB_INSTRUMENT_VA(this)lldb_private::instrumentation::Instrumenter _instr( __PRETTY_FUNCTION__ , lldb_private::instrumentation::stringify_args(this));; |
393 | |
394 | addr_t addr = LLDB_INVALID_ADDRESS(18446744073709551615UL); |
395 | std::unique_lock<std::recursive_mutex> lock; |
396 | ExecutionContext exe_ctx(m_opaque_sp.get(), lock); |
397 | |
398 | Target *target = exe_ctx.GetTargetPtr(); |
399 | Process *process = exe_ctx.GetProcessPtr(); |
400 | if (target && process) { |
401 | Process::StopLocker stop_locker; |
402 | if (stop_locker.TryLock(&process->GetRunLock())) { |
403 | if (StackFrame *frame = exe_ctx.GetFramePtr()) { |
404 | if (RegisterContextSP reg_ctx_sp = frame->GetRegisterContext()) { |
405 | addr = reg_ctx_sp->GetFP(); |
406 | } |
407 | } |
408 | } |
409 | } |
410 | |
411 | return addr; |
412 | } |
413 | |
414 | SBAddress SBFrame::GetPCAddress() const { |
415 | LLDB_INSTRUMENT_VA(this)lldb_private::instrumentation::Instrumenter _instr( __PRETTY_FUNCTION__ , lldb_private::instrumentation::stringify_args(this));; |
416 | |
417 | SBAddress sb_addr; |
418 | std::unique_lock<std::recursive_mutex> lock; |
419 | ExecutionContext exe_ctx(m_opaque_sp.get(), lock); |
420 | |
421 | StackFrame *frame = exe_ctx.GetFramePtr(); |
Value stored to 'frame' during its initialization is never read | |
422 | Target *target = exe_ctx.GetTargetPtr(); |
423 | Process *process = exe_ctx.GetProcessPtr(); |
424 | if (target && process) { |
425 | Process::StopLocker stop_locker; |
426 | if (stop_locker.TryLock(&process->GetRunLock())) { |
427 | frame = exe_ctx.GetFramePtr(); |
428 | if (frame) |
429 | sb_addr.SetAddress(frame->GetFrameCodeAddress()); |
430 | } |
431 | } |
432 | return sb_addr; |
433 | } |
434 | |
435 | void SBFrame::Clear() { |
436 | LLDB_INSTRUMENT_VA(this)lldb_private::instrumentation::Instrumenter _instr( __PRETTY_FUNCTION__ , lldb_private::instrumentation::stringify_args(this));; |
437 | |
438 | m_opaque_sp->Clear(); |
439 | } |
440 | |
441 | lldb::SBValue SBFrame::GetValueForVariablePath(const char *var_path) { |
442 | LLDB_INSTRUMENT_VA(this, var_path)lldb_private::instrumentation::Instrumenter _instr( __PRETTY_FUNCTION__ , lldb_private::instrumentation::stringify_args(this, var_path ));; |
443 | |
444 | SBValue sb_value; |
445 | std::unique_lock<std::recursive_mutex> lock; |
446 | ExecutionContext exe_ctx(m_opaque_sp.get(), lock); |
447 | |
448 | StackFrame *frame = exe_ctx.GetFramePtr(); |
449 | Target *target = exe_ctx.GetTargetPtr(); |
450 | if (frame && target) { |
451 | lldb::DynamicValueType use_dynamic = |
452 | frame->CalculateTarget()->GetPreferDynamicValue(); |
453 | sb_value = GetValueForVariablePath(var_path, use_dynamic); |
454 | } |
455 | return sb_value; |
456 | } |
457 | |
458 | lldb::SBValue SBFrame::GetValueForVariablePath(const char *var_path, |
459 | DynamicValueType use_dynamic) { |
460 | LLDB_INSTRUMENT_VA(this, var_path, use_dynamic)lldb_private::instrumentation::Instrumenter _instr( __PRETTY_FUNCTION__ , lldb_private::instrumentation::stringify_args(this, var_path , use_dynamic));; |
461 | |
462 | SBValue sb_value; |
463 | if (var_path == nullptr || var_path[0] == '\0') { |
464 | return sb_value; |
465 | } |
466 | |
467 | std::unique_lock<std::recursive_mutex> lock; |
468 | ExecutionContext exe_ctx(m_opaque_sp.get(), lock); |
469 | |
470 | StackFrame *frame = nullptr; |
471 | Target *target = exe_ctx.GetTargetPtr(); |
472 | Process *process = exe_ctx.GetProcessPtr(); |
473 | if (target && process) { |
474 | Process::StopLocker stop_locker; |
475 | if (stop_locker.TryLock(&process->GetRunLock())) { |
476 | frame = exe_ctx.GetFramePtr(); |
477 | if (frame) { |
478 | VariableSP var_sp; |
479 | Status error; |
480 | ValueObjectSP value_sp(frame->GetValueForVariableExpressionPath( |
481 | var_path, eNoDynamicValues, |
482 | StackFrame::eExpressionPathOptionCheckPtrVsMember | |
483 | StackFrame::eExpressionPathOptionsAllowDirectIVarAccess, |
484 | var_sp, error)); |
485 | sb_value.SetSP(value_sp, use_dynamic); |
486 | } |
487 | } |
488 | } |
489 | return sb_value; |
490 | } |
491 | |
492 | SBValue SBFrame::FindVariable(const char *name) { |
493 | LLDB_INSTRUMENT_VA(this, name)lldb_private::instrumentation::Instrumenter _instr( __PRETTY_FUNCTION__ , lldb_private::instrumentation::stringify_args(this, name));; |
494 | |
495 | SBValue value; |
496 | std::unique_lock<std::recursive_mutex> lock; |
497 | ExecutionContext exe_ctx(m_opaque_sp.get(), lock); |
498 | |
499 | StackFrame *frame = exe_ctx.GetFramePtr(); |
500 | Target *target = exe_ctx.GetTargetPtr(); |
501 | if (frame && target) { |
502 | lldb::DynamicValueType use_dynamic = |
503 | frame->CalculateTarget()->GetPreferDynamicValue(); |
504 | value = FindVariable(name, use_dynamic); |
505 | } |
506 | return value; |
507 | } |
508 | |
509 | SBValue SBFrame::FindVariable(const char *name, |
510 | lldb::DynamicValueType use_dynamic) { |
511 | LLDB_INSTRUMENT_VA(this, name, use_dynamic)lldb_private::instrumentation::Instrumenter _instr( __PRETTY_FUNCTION__ , lldb_private::instrumentation::stringify_args(this, name, use_dynamic ));; |
512 | |
513 | VariableSP var_sp; |
514 | SBValue sb_value; |
515 | |
516 | if (name == nullptr || name[0] == '\0') { |
517 | return sb_value; |
518 | } |
519 | |
520 | ValueObjectSP value_sp; |
521 | std::unique_lock<std::recursive_mutex> lock; |
522 | ExecutionContext exe_ctx(m_opaque_sp.get(), lock); |
523 | |
524 | StackFrame *frame = nullptr; |
525 | Target *target = exe_ctx.GetTargetPtr(); |
526 | Process *process = exe_ctx.GetProcessPtr(); |
527 | if (target && process) { |
528 | Process::StopLocker stop_locker; |
529 | if (stop_locker.TryLock(&process->GetRunLock())) { |
530 | frame = exe_ctx.GetFramePtr(); |
531 | if (frame) { |
532 | value_sp = frame->FindVariable(ConstString(name)); |
533 | |
534 | if (value_sp) |
535 | sb_value.SetSP(value_sp, use_dynamic); |
536 | } |
537 | } |
538 | } |
539 | |
540 | return sb_value; |
541 | } |
542 | |
543 | SBValue SBFrame::FindValue(const char *name, ValueType value_type) { |
544 | LLDB_INSTRUMENT_VA(this, name, value_type)lldb_private::instrumentation::Instrumenter _instr( __PRETTY_FUNCTION__ , lldb_private::instrumentation::stringify_args(this, name, value_type ));; |
545 | |
546 | SBValue value; |
547 | std::unique_lock<std::recursive_mutex> lock; |
548 | ExecutionContext exe_ctx(m_opaque_sp.get(), lock); |
549 | |
550 | StackFrame *frame = exe_ctx.GetFramePtr(); |
551 | Target *target = exe_ctx.GetTargetPtr(); |
552 | if (frame && target) { |
553 | lldb::DynamicValueType use_dynamic = |
554 | frame->CalculateTarget()->GetPreferDynamicValue(); |
555 | value = FindValue(name, value_type, use_dynamic); |
556 | } |
557 | return value; |
558 | } |
559 | |
560 | SBValue SBFrame::FindValue(const char *name, ValueType value_type, |
561 | lldb::DynamicValueType use_dynamic) { |
562 | LLDB_INSTRUMENT_VA(this, name, value_type, use_dynamic)lldb_private::instrumentation::Instrumenter _instr( __PRETTY_FUNCTION__ , lldb_private::instrumentation::stringify_args(this, name, value_type , use_dynamic));; |
563 | |
564 | SBValue sb_value; |
565 | |
566 | if (name == nullptr || name[0] == '\0') { |
567 | return sb_value; |
568 | } |
569 | |
570 | ValueObjectSP value_sp; |
571 | std::unique_lock<std::recursive_mutex> lock; |
572 | ExecutionContext exe_ctx(m_opaque_sp.get(), lock); |
573 | |
574 | StackFrame *frame = nullptr; |
575 | Target *target = exe_ctx.GetTargetPtr(); |
576 | Process *process = exe_ctx.GetProcessPtr(); |
577 | if (target && process) { |
578 | Process::StopLocker stop_locker; |
579 | if (stop_locker.TryLock(&process->GetRunLock())) { |
580 | frame = exe_ctx.GetFramePtr(); |
581 | if (frame) { |
582 | VariableList variable_list; |
583 | |
584 | switch (value_type) { |
585 | case eValueTypeVariableGlobal: // global variable |
586 | case eValueTypeVariableStatic: // static variable |
587 | case eValueTypeVariableArgument: // function argument variables |
588 | case eValueTypeVariableLocal: // function local variables |
589 | case eValueTypeVariableThreadLocal: // thread local variables |
590 | { |
591 | SymbolContext sc(frame->GetSymbolContext(eSymbolContextBlock)); |
592 | |
593 | const bool can_create = true; |
594 | const bool get_parent_variables = true; |
595 | const bool stop_if_block_is_inlined_function = true; |
596 | |
597 | if (sc.block) |
598 | sc.block->AppendVariables( |
599 | can_create, get_parent_variables, |
600 | stop_if_block_is_inlined_function, |
601 | [frame](Variable *v) { return v->IsInScope(frame); }, |
602 | &variable_list); |
603 | if (value_type == eValueTypeVariableGlobal) { |
604 | const bool get_file_globals = true; |
605 | VariableList *frame_vars = frame->GetVariableList(get_file_globals); |
606 | if (frame_vars) |
607 | frame_vars->AppendVariablesIfUnique(variable_list); |
608 | } |
609 | ConstString const_name(name); |
610 | VariableSP variable_sp( |
611 | variable_list.FindVariable(const_name, value_type)); |
612 | if (variable_sp) { |
613 | value_sp = frame->GetValueObjectForFrameVariable(variable_sp, |
614 | eNoDynamicValues); |
615 | sb_value.SetSP(value_sp, use_dynamic); |
616 | } |
617 | } break; |
618 | |
619 | case eValueTypeRegister: // stack frame register value |
620 | { |
621 | RegisterContextSP reg_ctx(frame->GetRegisterContext()); |
622 | if (reg_ctx) { |
623 | if (const RegisterInfo *reg_info = |
624 | reg_ctx->GetRegisterInfoByName(name)) { |
625 | value_sp = ValueObjectRegister::Create(frame, reg_ctx, reg_info); |
626 | sb_value.SetSP(value_sp); |
627 | } |
628 | } |
629 | } break; |
630 | |
631 | case eValueTypeRegisterSet: // A collection of stack frame register |
632 | // values |
633 | { |
634 | RegisterContextSP reg_ctx(frame->GetRegisterContext()); |
635 | if (reg_ctx) { |
636 | const uint32_t num_sets = reg_ctx->GetRegisterSetCount(); |
637 | for (uint32_t set_idx = 0; set_idx < num_sets; ++set_idx) { |
638 | const RegisterSet *reg_set = reg_ctx->GetRegisterSet(set_idx); |
639 | if (reg_set && |
640 | (llvm::StringRef(reg_set->name).equals_insensitive(name) || |
641 | llvm::StringRef(reg_set->short_name) |
642 | .equals_insensitive(name))) { |
643 | value_sp = |
644 | ValueObjectRegisterSet::Create(frame, reg_ctx, set_idx); |
645 | sb_value.SetSP(value_sp); |
646 | break; |
647 | } |
648 | } |
649 | } |
650 | } break; |
651 | |
652 | case eValueTypeConstResult: // constant result variables |
653 | { |
654 | ConstString const_name(name); |
655 | ExpressionVariableSP expr_var_sp( |
656 | target->GetPersistentVariable(const_name)); |
657 | if (expr_var_sp) { |
658 | value_sp = expr_var_sp->GetValueObject(); |
659 | sb_value.SetSP(value_sp, use_dynamic); |
660 | } |
661 | } break; |
662 | |
663 | default: |
664 | break; |
665 | } |
666 | } |
667 | } |
668 | } |
669 | |
670 | return sb_value; |
671 | } |
672 | |
673 | bool SBFrame::IsEqual(const SBFrame &that) const { |
674 | LLDB_INSTRUMENT_VA(this, that)lldb_private::instrumentation::Instrumenter _instr( __PRETTY_FUNCTION__ , lldb_private::instrumentation::stringify_args(this, that));; |
675 | |
676 | lldb::StackFrameSP this_sp = GetFrameSP(); |
677 | lldb::StackFrameSP that_sp = that.GetFrameSP(); |
678 | return (this_sp && that_sp && this_sp->GetStackID() == that_sp->GetStackID()); |
679 | } |
680 | |
681 | bool SBFrame::operator==(const SBFrame &rhs) const { |
682 | LLDB_INSTRUMENT_VA(this, rhs)lldb_private::instrumentation::Instrumenter _instr( __PRETTY_FUNCTION__ , lldb_private::instrumentation::stringify_args(this, rhs));; |
683 | |
684 | return IsEqual(rhs); |
685 | } |
686 | |
687 | bool SBFrame::operator!=(const SBFrame &rhs) const { |
688 | LLDB_INSTRUMENT_VA(this, rhs)lldb_private::instrumentation::Instrumenter _instr( __PRETTY_FUNCTION__ , lldb_private::instrumentation::stringify_args(this, rhs));; |
689 | |
690 | return !IsEqual(rhs); |
691 | } |
692 | |
693 | SBThread SBFrame::GetThread() const { |
694 | LLDB_INSTRUMENT_VA(this)lldb_private::instrumentation::Instrumenter _instr( __PRETTY_FUNCTION__ , lldb_private::instrumentation::stringify_args(this));; |
695 | |
696 | std::unique_lock<std::recursive_mutex> lock; |
697 | ExecutionContext exe_ctx(m_opaque_sp.get(), lock); |
698 | |
699 | ThreadSP thread_sp(exe_ctx.GetThreadSP()); |
700 | SBThread sb_thread(thread_sp); |
701 | |
702 | return sb_thread; |
703 | } |
704 | |
705 | const char *SBFrame::Disassemble() const { |
706 | LLDB_INSTRUMENT_VA(this)lldb_private::instrumentation::Instrumenter _instr( __PRETTY_FUNCTION__ , lldb_private::instrumentation::stringify_args(this));; |
707 | |
708 | const char *disassembly = nullptr; |
709 | std::unique_lock<std::recursive_mutex> lock; |
710 | ExecutionContext exe_ctx(m_opaque_sp.get(), lock); |
711 | |
712 | StackFrame *frame = nullptr; |
713 | Target *target = exe_ctx.GetTargetPtr(); |
714 | Process *process = exe_ctx.GetProcessPtr(); |
715 | if (target && process) { |
716 | Process::StopLocker stop_locker; |
717 | if (stop_locker.TryLock(&process->GetRunLock())) { |
718 | frame = exe_ctx.GetFramePtr(); |
719 | if (frame) { |
720 | disassembly = frame->Disassemble(); |
721 | } |
722 | } |
723 | } |
724 | |
725 | return disassembly; |
726 | } |
727 | |
728 | SBValueList SBFrame::GetVariables(bool arguments, bool locals, bool statics, |
729 | bool in_scope_only) { |
730 | LLDB_INSTRUMENT_VA(this, arguments, locals, statics, in_scope_only)lldb_private::instrumentation::Instrumenter _instr( __PRETTY_FUNCTION__ , lldb_private::instrumentation::stringify_args(this, arguments , locals, statics, in_scope_only));; |
731 | |
732 | SBValueList value_list; |
733 | std::unique_lock<std::recursive_mutex> lock; |
734 | ExecutionContext exe_ctx(m_opaque_sp.get(), lock); |
735 | |
736 | StackFrame *frame = exe_ctx.GetFramePtr(); |
737 | Target *target = exe_ctx.GetTargetPtr(); |
738 | if (frame && target) { |
739 | lldb::DynamicValueType use_dynamic = |
740 | frame->CalculateTarget()->GetPreferDynamicValue(); |
741 | const bool include_runtime_support_values = |
742 | target ? target->GetDisplayRuntimeSupportValues() : false; |
743 | |
744 | SBVariablesOptions options; |
745 | options.SetIncludeArguments(arguments); |
746 | options.SetIncludeLocals(locals); |
747 | options.SetIncludeStatics(statics); |
748 | options.SetInScopeOnly(in_scope_only); |
749 | options.SetIncludeRuntimeSupportValues(include_runtime_support_values); |
750 | options.SetUseDynamic(use_dynamic); |
751 | |
752 | value_list = GetVariables(options); |
753 | } |
754 | return value_list; |
755 | } |
756 | |
757 | lldb::SBValueList SBFrame::GetVariables(bool arguments, bool locals, |
758 | bool statics, bool in_scope_only, |
759 | lldb::DynamicValueType use_dynamic) { |
760 | LLDB_INSTRUMENT_VA(this, arguments, locals, statics, in_scope_only,lldb_private::instrumentation::Instrumenter _instr( __PRETTY_FUNCTION__ , lldb_private::instrumentation::stringify_args(this, arguments , locals, statics, in_scope_only, use_dynamic)); |
761 | use_dynamic)lldb_private::instrumentation::Instrumenter _instr( __PRETTY_FUNCTION__ , lldb_private::instrumentation::stringify_args(this, arguments , locals, statics, in_scope_only, use_dynamic));; |
762 | |
763 | std::unique_lock<std::recursive_mutex> lock; |
764 | ExecutionContext exe_ctx(m_opaque_sp.get(), lock); |
765 | |
766 | Target *target = exe_ctx.GetTargetPtr(); |
767 | const bool include_runtime_support_values = |
768 | target ? target->GetDisplayRuntimeSupportValues() : false; |
769 | SBVariablesOptions options; |
770 | options.SetIncludeArguments(arguments); |
771 | options.SetIncludeLocals(locals); |
772 | options.SetIncludeStatics(statics); |
773 | options.SetInScopeOnly(in_scope_only); |
774 | options.SetIncludeRuntimeSupportValues(include_runtime_support_values); |
775 | options.SetUseDynamic(use_dynamic); |
776 | return GetVariables(options); |
777 | } |
778 | |
779 | SBValueList SBFrame::GetVariables(const lldb::SBVariablesOptions &options) { |
780 | LLDB_INSTRUMENT_VA(this, options)lldb_private::instrumentation::Instrumenter _instr( __PRETTY_FUNCTION__ , lldb_private::instrumentation::stringify_args(this, options ));; |
781 | |
782 | SBValueList value_list; |
783 | std::unique_lock<std::recursive_mutex> lock; |
784 | ExecutionContext exe_ctx(m_opaque_sp.get(), lock); |
785 | |
786 | StackFrame *frame = nullptr; |
787 | Target *target = exe_ctx.GetTargetPtr(); |
788 | |
789 | const bool statics = options.GetIncludeStatics(); |
790 | const bool arguments = options.GetIncludeArguments(); |
791 | const bool recognized_arguments = |
792 | options.GetIncludeRecognizedArguments(SBTarget(exe_ctx.GetTargetSP())); |
793 | const bool locals = options.GetIncludeLocals(); |
794 | const bool in_scope_only = options.GetInScopeOnly(); |
795 | const bool include_runtime_support_values = |
796 | options.GetIncludeRuntimeSupportValues(); |
797 | const lldb::DynamicValueType use_dynamic = options.GetUseDynamic(); |
798 | |
799 | |
800 | std::set<VariableSP> variable_set; |
801 | Process *process = exe_ctx.GetProcessPtr(); |
802 | if (target && process) { |
803 | Process::StopLocker stop_locker; |
804 | if (stop_locker.TryLock(&process->GetRunLock())) { |
805 | frame = exe_ctx.GetFramePtr(); |
806 | if (frame) { |
807 | VariableList *variable_list = nullptr; |
808 | variable_list = frame->GetVariableList(true); |
809 | if (variable_list) { |
810 | const size_t num_variables = variable_list->GetSize(); |
811 | if (num_variables) { |
812 | for (const VariableSP &variable_sp : *variable_list) { |
813 | if (variable_sp) { |
814 | bool add_variable = false; |
815 | switch (variable_sp->GetScope()) { |
816 | case eValueTypeVariableGlobal: |
817 | case eValueTypeVariableStatic: |
818 | case eValueTypeVariableThreadLocal: |
819 | add_variable = statics; |
820 | break; |
821 | |
822 | case eValueTypeVariableArgument: |
823 | add_variable = arguments; |
824 | break; |
825 | |
826 | case eValueTypeVariableLocal: |
827 | add_variable = locals; |
828 | break; |
829 | |
830 | default: |
831 | break; |
832 | } |
833 | if (add_variable) { |
834 | // Only add variables once so we don't end up with duplicates |
835 | if (variable_set.find(variable_sp) == variable_set.end()) |
836 | variable_set.insert(variable_sp); |
837 | else |
838 | continue; |
839 | |
840 | if (in_scope_only && !variable_sp->IsInScope(frame)) |
841 | continue; |
842 | |
843 | ValueObjectSP valobj_sp(frame->GetValueObjectForFrameVariable( |
844 | variable_sp, eNoDynamicValues)); |
845 | |
846 | if (!include_runtime_support_values && valobj_sp != nullptr && |
847 | valobj_sp->IsRuntimeSupportValue()) |
848 | continue; |
849 | |
850 | SBValue value_sb; |
851 | value_sb.SetSP(valobj_sp, use_dynamic); |
852 | value_list.Append(value_sb); |
853 | } |
854 | } |
855 | } |
856 | } |
857 | } |
858 | if (recognized_arguments) { |
859 | auto recognized_frame = frame->GetRecognizedFrame(); |
860 | if (recognized_frame) { |
861 | ValueObjectListSP recognized_arg_list = |
862 | recognized_frame->GetRecognizedArguments(); |
863 | if (recognized_arg_list) { |
864 | for (auto &rec_value_sp : recognized_arg_list->GetObjects()) { |
865 | SBValue value_sb; |
866 | value_sb.SetSP(rec_value_sp, use_dynamic); |
867 | value_list.Append(value_sb); |
868 | } |
869 | } |
870 | } |
871 | } |
872 | } |
873 | } |
874 | } |
875 | |
876 | return value_list; |
877 | } |
878 | |
879 | SBValueList SBFrame::GetRegisters() { |
880 | LLDB_INSTRUMENT_VA(this)lldb_private::instrumentation::Instrumenter _instr( __PRETTY_FUNCTION__ , lldb_private::instrumentation::stringify_args(this));; |
881 | |
882 | SBValueList value_list; |
883 | std::unique_lock<std::recursive_mutex> lock; |
884 | ExecutionContext exe_ctx(m_opaque_sp.get(), lock); |
885 | |
886 | StackFrame *frame = nullptr; |
887 | Target *target = exe_ctx.GetTargetPtr(); |
888 | Process *process = exe_ctx.GetProcessPtr(); |
889 | if (target && process) { |
890 | Process::StopLocker stop_locker; |
891 | if (stop_locker.TryLock(&process->GetRunLock())) { |
892 | frame = exe_ctx.GetFramePtr(); |
893 | if (frame) { |
894 | RegisterContextSP reg_ctx(frame->GetRegisterContext()); |
895 | if (reg_ctx) { |
896 | const uint32_t num_sets = reg_ctx->GetRegisterSetCount(); |
897 | for (uint32_t set_idx = 0; set_idx < num_sets; ++set_idx) { |
898 | value_list.Append( |
899 | ValueObjectRegisterSet::Create(frame, reg_ctx, set_idx)); |
900 | } |
901 | } |
902 | } |
903 | } |
904 | } |
905 | |
906 | return value_list; |
907 | } |
908 | |
909 | SBValue SBFrame::FindRegister(const char *name) { |
910 | LLDB_INSTRUMENT_VA(this, name)lldb_private::instrumentation::Instrumenter _instr( __PRETTY_FUNCTION__ , lldb_private::instrumentation::stringify_args(this, name));; |
911 | |
912 | SBValue result; |
913 | ValueObjectSP value_sp; |
914 | std::unique_lock<std::recursive_mutex> lock; |
915 | ExecutionContext exe_ctx(m_opaque_sp.get(), lock); |
916 | |
917 | StackFrame *frame = nullptr; |
918 | Target *target = exe_ctx.GetTargetPtr(); |
919 | Process *process = exe_ctx.GetProcessPtr(); |
920 | if (target && process) { |
921 | Process::StopLocker stop_locker; |
922 | if (stop_locker.TryLock(&process->GetRunLock())) { |
923 | frame = exe_ctx.GetFramePtr(); |
924 | if (frame) { |
925 | RegisterContextSP reg_ctx(frame->GetRegisterContext()); |
926 | if (reg_ctx) { |
927 | if (const RegisterInfo *reg_info = |
928 | reg_ctx->GetRegisterInfoByName(name)) { |
929 | value_sp = ValueObjectRegister::Create(frame, reg_ctx, reg_info); |
930 | result.SetSP(value_sp); |
931 | } |
932 | } |
933 | } |
934 | } |
935 | } |
936 | |
937 | return result; |
938 | } |
939 | |
940 | bool SBFrame::GetDescription(SBStream &description) { |
941 | LLDB_INSTRUMENT_VA(this, description)lldb_private::instrumentation::Instrumenter _instr( __PRETTY_FUNCTION__ , lldb_private::instrumentation::stringify_args(this, description ));; |
942 | |
943 | Stream &strm = description.ref(); |
944 | |
945 | std::unique_lock<std::recursive_mutex> lock; |
946 | ExecutionContext exe_ctx(m_opaque_sp.get(), lock); |
947 | |
948 | StackFrame *frame; |
949 | Target *target = exe_ctx.GetTargetPtr(); |
950 | Process *process = exe_ctx.GetProcessPtr(); |
951 | if (target && process) { |
952 | Process::StopLocker stop_locker; |
953 | if (stop_locker.TryLock(&process->GetRunLock())) { |
954 | frame = exe_ctx.GetFramePtr(); |
955 | if (frame) { |
956 | frame->DumpUsingSettingsFormat(&strm); |
957 | } |
958 | } |
959 | |
960 | } else |
961 | strm.PutCString("No value"); |
962 | |
963 | return true; |
964 | } |
965 | |
966 | SBValue SBFrame::EvaluateExpression(const char *expr) { |
967 | LLDB_INSTRUMENT_VA(this, expr)lldb_private::instrumentation::Instrumenter _instr( __PRETTY_FUNCTION__ , lldb_private::instrumentation::stringify_args(this, expr));; |
968 | |
969 | SBValue result; |
970 | std::unique_lock<std::recursive_mutex> lock; |
971 | ExecutionContext exe_ctx(m_opaque_sp.get(), lock); |
972 | |
973 | StackFrame *frame = exe_ctx.GetFramePtr(); |
974 | Target *target = exe_ctx.GetTargetPtr(); |
975 | if (frame && target) { |
976 | SBExpressionOptions options; |
977 | lldb::DynamicValueType fetch_dynamic_value = |
978 | frame->CalculateTarget()->GetPreferDynamicValue(); |
979 | options.SetFetchDynamicValue(fetch_dynamic_value); |
980 | options.SetUnwindOnError(true); |
981 | options.SetIgnoreBreakpoints(true); |
982 | if (target->GetLanguage() != eLanguageTypeUnknown) |
983 | options.SetLanguage(target->GetLanguage()); |
984 | else |
985 | options.SetLanguage(frame->GetLanguage()); |
986 | return EvaluateExpression(expr, options); |
987 | } |
988 | return result; |
989 | } |
990 | |
991 | SBValue |
992 | SBFrame::EvaluateExpression(const char *expr, |
993 | lldb::DynamicValueType fetch_dynamic_value) { |
994 | LLDB_INSTRUMENT_VA(this, expr, fetch_dynamic_value)lldb_private::instrumentation::Instrumenter _instr( __PRETTY_FUNCTION__ , lldb_private::instrumentation::stringify_args(this, expr, fetch_dynamic_value ));; |
995 | |
996 | SBExpressionOptions options; |
997 | options.SetFetchDynamicValue(fetch_dynamic_value); |
998 | options.SetUnwindOnError(true); |
999 | options.SetIgnoreBreakpoints(true); |
1000 | std::unique_lock<std::recursive_mutex> lock; |
1001 | ExecutionContext exe_ctx(m_opaque_sp.get(), lock); |
1002 | |
1003 | StackFrame *frame = exe_ctx.GetFramePtr(); |
1004 | Target *target = exe_ctx.GetTargetPtr(); |
1005 | if (target && target->GetLanguage() != eLanguageTypeUnknown) |
1006 | options.SetLanguage(target->GetLanguage()); |
1007 | else if (frame) |
1008 | options.SetLanguage(frame->GetLanguage()); |
1009 | return EvaluateExpression(expr, options); |
1010 | } |
1011 | |
1012 | SBValue SBFrame::EvaluateExpression(const char *expr, |
1013 | lldb::DynamicValueType fetch_dynamic_value, |
1014 | bool unwind_on_error) { |
1015 | LLDB_INSTRUMENT_VA(this, expr, fetch_dynamic_value, unwind_on_error)lldb_private::instrumentation::Instrumenter _instr( __PRETTY_FUNCTION__ , lldb_private::instrumentation::stringify_args(this, expr, fetch_dynamic_value , unwind_on_error));; |
1016 | |
1017 | SBExpressionOptions options; |
1018 | std::unique_lock<std::recursive_mutex> lock; |
1019 | ExecutionContext exe_ctx(m_opaque_sp.get(), lock); |
1020 | |
1021 | options.SetFetchDynamicValue(fetch_dynamic_value); |
1022 | options.SetUnwindOnError(unwind_on_error); |
1023 | options.SetIgnoreBreakpoints(true); |
1024 | StackFrame *frame = exe_ctx.GetFramePtr(); |
1025 | Target *target = exe_ctx.GetTargetPtr(); |
1026 | if (target && target->GetLanguage() != eLanguageTypeUnknown) |
1027 | options.SetLanguage(target->GetLanguage()); |
1028 | else if (frame) |
1029 | options.SetLanguage(frame->GetLanguage()); |
1030 | return EvaluateExpression(expr, options); |
1031 | } |
1032 | |
1033 | lldb::SBValue SBFrame::EvaluateExpression(const char *expr, |
1034 | const SBExpressionOptions &options) { |
1035 | LLDB_INSTRUMENT_VA(this, expr, options)lldb_private::instrumentation::Instrumenter _instr( __PRETTY_FUNCTION__ , lldb_private::instrumentation::stringify_args(this, expr, options ));; |
1036 | |
1037 | Log *expr_log = GetLog(LLDBLog::Expressions); |
1038 | |
1039 | SBValue expr_result; |
1040 | |
1041 | if (expr == nullptr || expr[0] == '\0') { |
1042 | return expr_result; |
1043 | } |
1044 | |
1045 | ValueObjectSP expr_value_sp; |
1046 | |
1047 | std::unique_lock<std::recursive_mutex> lock; |
1048 | ExecutionContext exe_ctx(m_opaque_sp.get(), lock); |
1049 | |
1050 | |
1051 | StackFrame *frame = nullptr; |
1052 | Target *target = exe_ctx.GetTargetPtr(); |
1053 | Process *process = exe_ctx.GetProcessPtr(); |
1054 | |
1055 | if (target && process) { |
1056 | Process::StopLocker stop_locker; |
1057 | if (stop_locker.TryLock(&process->GetRunLock())) { |
1058 | frame = exe_ctx.GetFramePtr(); |
1059 | if (frame) { |
1060 | std::unique_ptr<llvm::PrettyStackTraceFormat> stack_trace; |
1061 | if (target->GetDisplayExpressionsInCrashlogs()) { |
1062 | StreamString frame_description; |
1063 | frame->DumpUsingSettingsFormat(&frame_description); |
1064 | stack_trace = std::make_unique<llvm::PrettyStackTraceFormat>( |
1065 | "SBFrame::EvaluateExpression (expr = \"%s\", fetch_dynamic_value " |
1066 | "= %u) %s", |
1067 | expr, options.GetFetchDynamicValue(), |
1068 | frame_description.GetData()); |
1069 | } |
1070 | |
1071 | target->EvaluateExpression(expr, frame, expr_value_sp, options.ref()); |
1072 | expr_result.SetSP(expr_value_sp, options.GetFetchDynamicValue()); |
1073 | } |
1074 | } |
1075 | } |
1076 | |
1077 | LLDB_LOGF(expr_log,do { ::lldb_private::Log *log_private = (expr_log); if (log_private ) log_private->Printf("** [SBFrame::EvaluateExpression] Expression result is " "%s, summary %s **", expr_result.GetValue(), expr_result.GetSummary ()); } while (0) |
1078 | "** [SBFrame::EvaluateExpression] Expression result is "do { ::lldb_private::Log *log_private = (expr_log); if (log_private ) log_private->Printf("** [SBFrame::EvaluateExpression] Expression result is " "%s, summary %s **", expr_result.GetValue(), expr_result.GetSummary ()); } while (0) |
1079 | "%s, summary %s **",do { ::lldb_private::Log *log_private = (expr_log); if (log_private ) log_private->Printf("** [SBFrame::EvaluateExpression] Expression result is " "%s, summary %s **", expr_result.GetValue(), expr_result.GetSummary ()); } while (0) |
1080 | expr_result.GetValue(), expr_result.GetSummary())do { ::lldb_private::Log *log_private = (expr_log); if (log_private ) log_private->Printf("** [SBFrame::EvaluateExpression] Expression result is " "%s, summary %s **", expr_result.GetValue(), expr_result.GetSummary ()); } while (0); |
1081 | |
1082 | return expr_result; |
1083 | } |
1084 | |
1085 | bool SBFrame::IsInlined() { |
1086 | LLDB_INSTRUMENT_VA(this)lldb_private::instrumentation::Instrumenter _instr( __PRETTY_FUNCTION__ , lldb_private::instrumentation::stringify_args(this));; |
1087 | |
1088 | return static_cast<const SBFrame *>(this)->IsInlined(); |
1089 | } |
1090 | |
1091 | bool SBFrame::IsInlined() const { |
1092 | LLDB_INSTRUMENT_VA(this)lldb_private::instrumentation::Instrumenter _instr( __PRETTY_FUNCTION__ , lldb_private::instrumentation::stringify_args(this));; |
1093 | |
1094 | std::unique_lock<std::recursive_mutex> lock; |
1095 | ExecutionContext exe_ctx(m_opaque_sp.get(), lock); |
1096 | |
1097 | StackFrame *frame = nullptr; |
1098 | Target *target = exe_ctx.GetTargetPtr(); |
1099 | Process *process = exe_ctx.GetProcessPtr(); |
1100 | if (target && process) { |
1101 | Process::StopLocker stop_locker; |
1102 | if (stop_locker.TryLock(&process->GetRunLock())) { |
1103 | frame = exe_ctx.GetFramePtr(); |
1104 | if (frame) { |
1105 | |
1106 | Block *block = frame->GetSymbolContext(eSymbolContextBlock).block; |
1107 | if (block) |
1108 | return block->GetContainingInlinedBlock() != nullptr; |
1109 | } |
1110 | } |
1111 | } |
1112 | return false; |
1113 | } |
1114 | |
1115 | bool SBFrame::IsArtificial() { |
1116 | LLDB_INSTRUMENT_VA(this)lldb_private::instrumentation::Instrumenter _instr( __PRETTY_FUNCTION__ , lldb_private::instrumentation::stringify_args(this));; |
1117 | |
1118 | return static_cast<const SBFrame *>(this)->IsArtificial(); |
1119 | } |
1120 | |
1121 | bool SBFrame::IsArtificial() const { |
1122 | LLDB_INSTRUMENT_VA(this)lldb_private::instrumentation::Instrumenter _instr( __PRETTY_FUNCTION__ , lldb_private::instrumentation::stringify_args(this));; |
1123 | |
1124 | std::unique_lock<std::recursive_mutex> lock; |
1125 | ExecutionContext exe_ctx(m_opaque_sp.get(), lock); |
1126 | |
1127 | StackFrame *frame = exe_ctx.GetFramePtr(); |
1128 | if (frame) |
1129 | return frame->IsArtificial(); |
1130 | |
1131 | return false; |
1132 | } |
1133 | |
1134 | const char *SBFrame::GetFunctionName() { |
1135 | LLDB_INSTRUMENT_VA(this)lldb_private::instrumentation::Instrumenter _instr( __PRETTY_FUNCTION__ , lldb_private::instrumentation::stringify_args(this));; |
1136 | |
1137 | return static_cast<const SBFrame *>(this)->GetFunctionName(); |
1138 | } |
1139 | |
1140 | lldb::LanguageType SBFrame::GuessLanguage() const { |
1141 | LLDB_INSTRUMENT_VA(this)lldb_private::instrumentation::Instrumenter _instr( __PRETTY_FUNCTION__ , lldb_private::instrumentation::stringify_args(this));; |
1142 | |
1143 | std::unique_lock<std::recursive_mutex> lock; |
1144 | ExecutionContext exe_ctx(m_opaque_sp.get(), lock); |
1145 | |
1146 | StackFrame *frame = nullptr; |
1147 | Target *target = exe_ctx.GetTargetPtr(); |
1148 | Process *process = exe_ctx.GetProcessPtr(); |
1149 | if (target && process) { |
1150 | Process::StopLocker stop_locker; |
1151 | if (stop_locker.TryLock(&process->GetRunLock())) { |
1152 | frame = exe_ctx.GetFramePtr(); |
1153 | if (frame) { |
1154 | return frame->GuessLanguage(); |
1155 | } |
1156 | } |
1157 | } |
1158 | return eLanguageTypeUnknown; |
1159 | } |
1160 | |
1161 | const char *SBFrame::GetFunctionName() const { |
1162 | LLDB_INSTRUMENT_VA(this)lldb_private::instrumentation::Instrumenter _instr( __PRETTY_FUNCTION__ , lldb_private::instrumentation::stringify_args(this));; |
1163 | |
1164 | const char *name = nullptr; |
1165 | std::unique_lock<std::recursive_mutex> lock; |
1166 | ExecutionContext exe_ctx(m_opaque_sp.get(), lock); |
1167 | |
1168 | StackFrame *frame = nullptr; |
1169 | Target *target = exe_ctx.GetTargetPtr(); |
1170 | Process *process = exe_ctx.GetProcessPtr(); |
1171 | if (target && process) { |
1172 | Process::StopLocker stop_locker; |
1173 | if (stop_locker.TryLock(&process->GetRunLock())) { |
1174 | frame = exe_ctx.GetFramePtr(); |
1175 | if (frame) { |
1176 | SymbolContext sc(frame->GetSymbolContext(eSymbolContextFunction | |
1177 | eSymbolContextBlock | |
1178 | eSymbolContextSymbol)); |
1179 | if (sc.block) { |
1180 | Block *inlined_block = sc.block->GetContainingInlinedBlock(); |
1181 | if (inlined_block) { |
1182 | const InlineFunctionInfo *inlined_info = |
1183 | inlined_block->GetInlinedFunctionInfo(); |
1184 | name = inlined_info->GetName().AsCString(); |
1185 | } |
1186 | } |
1187 | |
1188 | if (name == nullptr) { |
1189 | if (sc.function) |
1190 | name = sc.function->GetName().GetCString(); |
1191 | } |
1192 | |
1193 | if (name == nullptr) { |
1194 | if (sc.symbol) |
1195 | name = sc.symbol->GetName().GetCString(); |
1196 | } |
1197 | } |
1198 | } |
1199 | } |
1200 | return name; |
1201 | } |
1202 | |
1203 | const char *SBFrame::GetDisplayFunctionName() { |
1204 | LLDB_INSTRUMENT_VA(this)lldb_private::instrumentation::Instrumenter _instr( __PRETTY_FUNCTION__ , lldb_private::instrumentation::stringify_args(this));; |
1205 | |
1206 | const char *name = nullptr; |
1207 | |
1208 | std::unique_lock<std::recursive_mutex> lock; |
1209 | ExecutionContext exe_ctx(m_opaque_sp.get(), lock); |
1210 | |
1211 | StackFrame *frame = nullptr; |
1212 | Target *target = exe_ctx.GetTargetPtr(); |
1213 | Process *process = exe_ctx.GetProcessPtr(); |
1214 | if (target && process) { |
1215 | Process::StopLocker stop_locker; |
1216 | if (stop_locker.TryLock(&process->GetRunLock())) { |
1217 | frame = exe_ctx.GetFramePtr(); |
1218 | if (frame) { |
1219 | SymbolContext sc(frame->GetSymbolContext(eSymbolContextFunction | |
1220 | eSymbolContextBlock | |
1221 | eSymbolContextSymbol)); |
1222 | if (sc.block) { |
1223 | Block *inlined_block = sc.block->GetContainingInlinedBlock(); |
1224 | if (inlined_block) { |
1225 | const InlineFunctionInfo *inlined_info = |
1226 | inlined_block->GetInlinedFunctionInfo(); |
1227 | name = inlined_info->GetDisplayName().AsCString(); |
1228 | } |
1229 | } |
1230 | |
1231 | if (name == nullptr) { |
1232 | if (sc.function) |
1233 | name = sc.function->GetDisplayName().GetCString(); |
1234 | } |
1235 | |
1236 | if (name == nullptr) { |
1237 | if (sc.symbol) |
1238 | name = sc.symbol->GetDisplayName().GetCString(); |
1239 | } |
1240 | } |
1241 | } |
1242 | } |
1243 | return name; |
1244 | } |