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