1 //===-- SBFrame.cpp ---------------------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "lldb/API/SBFrame.h"
11 
12 #include <string>
13 #include <algorithm>
14 
15 #include "lldb/lldb-types.h"
16 
17 #include "lldb/Core/Address.h"
18 #include "lldb/Core/ConstString.h"
19 #include "lldb/Core/Log.h"
20 #include "lldb/Core/Stream.h"
21 #include "lldb/Core/StreamFile.h"
22 #include "lldb/Core/ValueObjectRegister.h"
23 #include "lldb/Core/ValueObjectVariable.h"
24 #include "lldb/Expression/ClangUserExpression.h"
25 #include "lldb/Host/Host.h"
26 #include "lldb/Symbol/Block.h"
27 #include "lldb/Symbol/SymbolContext.h"
28 #include "lldb/Symbol/VariableList.h"
29 #include "lldb/Symbol/Variable.h"
30 #include "lldb/Target/ExecutionContext.h"
31 #include "lldb/Target/Target.h"
32 #include "lldb/Target/Process.h"
33 #include "lldb/Target/RegisterContext.h"
34 #include "lldb/Target/StackFrame.h"
35 #include "lldb/Target/StackID.h"
36 #include "lldb/Target/Thread.h"
37 
38 #include "lldb/API/SBDebugger.h"
39 #include "lldb/API/SBValue.h"
40 #include "lldb/API/SBAddress.h"
41 #include "lldb/API/SBStream.h"
42 #include "lldb/API/SBSymbolContext.h"
43 #include "lldb/API/SBThread.h"
44 
45 namespace lldb_private {
46 
47     class StackFrameImpl
48     {
49     public:
50         StackFrameImpl (const lldb::StackFrameSP &frame_sp) :
51             m_frame_wp (frame_sp),
52             m_thread_wp (),
53             m_stack_id ()
54         {
55             if (frame_sp)
56             {
57                 m_thread_wp = frame_sp->GetThread().shared_from_this();
58                 m_stack_id = frame_sp->GetStackID();
59             }
60         }
61 
62         ~StackFrameImpl()
63         {
64         }
65 
66         lldb::StackFrameSP
67         GetFrameSP ()
68         {
69             lldb::StackFrameSP frame_sp;
70             // We have a weak pointer to our thread, which might
71             // be NULL'ed out if the thread went away, so first
72             // make sure our thread is still alive.
73             lldb::ThreadSP thread_sp (m_thread_wp.lock());
74             if (thread_sp)
75             {
76                 // Our thread is still here, check if our frame
77                 // is still alive as well.
78                 frame_sp = m_frame_wp.lock();
79                 if (frame_sp)
80                 {
81                     // Our frame is still alive, make sure that our thread
82                     // still has this exact frame...
83                     lldb::StackFrameSP tmp_frame_sp (thread_sp->GetStackFrameAtIndex (frame_sp->GetFrameIndex()));
84                     if (tmp_frame_sp.get() == frame_sp.get())
85                         return frame_sp;
86                 }
87                 // The original stack frame might have gone away,
88                 // we need to check for the stac
89                 frame_sp = thread_sp->GetFrameWithStackID (m_stack_id);
90                 m_frame_wp = frame_sp;
91             }
92             return frame_sp;
93         }
94 
95         void
96         SetFrameSP (const lldb::StackFrameSP &frame_sp)
97         {
98             if (frame_sp)
99             {
100                 m_frame_wp = frame_sp;
101                 m_thread_wp = frame_sp->GetThread().shared_from_this();
102                 m_stack_id = frame_sp->GetStackID();
103             }
104             else
105             {
106                 m_frame_wp.reset();
107                 m_thread_wp.reset();
108                 m_stack_id.Clear();
109             }
110         }
111 
112     protected:
113         lldb::StackFrameWP m_frame_wp;
114         lldb::ThreadWP m_thread_wp;
115         StackID m_stack_id;
116     };
117 } // namespace lldb_private
118 
119 using namespace lldb;
120 using namespace lldb_private;
121 
122 
123 SBFrame::SBFrame () :
124     m_opaque_sp ()
125 {
126 }
127 
128 SBFrame::SBFrame (const StackFrameSP &lldb_object_sp) :
129     m_opaque_sp (new StackFrameImpl (lldb_object_sp))
130 {
131     LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
132 
133     if (log)
134     {
135         SBStream sstr;
136         GetDescription (sstr);
137         log->Printf ("SBFrame::SBFrame (sp=%p) => SBFrame(%p): %s",
138                      lldb_object_sp.get(), lldb_object_sp.get(), sstr.GetData());
139 
140     }
141 }
142 
143 SBFrame::SBFrame(const SBFrame &rhs) :
144     m_opaque_sp (rhs.m_opaque_sp)
145 {
146 }
147 
148 const SBFrame &
149 SBFrame::operator = (const SBFrame &rhs)
150 {
151     if (this != &rhs)
152         m_opaque_sp = rhs.m_opaque_sp;
153     return *this;
154 }
155 
156 SBFrame::~SBFrame()
157 {
158 }
159 
160 StackFrameSP
161 SBFrame::GetFrameSP() const
162 {
163     StackFrameImplSP impl_sp (m_opaque_sp);
164     StackFrameSP frame_sp;
165     if (impl_sp)
166         frame_sp = impl_sp->GetFrameSP();
167     return frame_sp;
168 }
169 
170 void
171 SBFrame::SetFrameSP (const StackFrameSP &lldb_object_sp)
172 {
173     if (lldb_object_sp)
174     {
175         if (m_opaque_sp)
176         {
177             StackFrameImplSP impl_sp (m_opaque_sp);
178             if (impl_sp)
179                 impl_sp->SetFrameSP (lldb_object_sp);
180         }
181         else
182         {
183             m_opaque_sp = StackFrameImplSP (new StackFrameImpl(lldb_object_sp));
184         }
185     }
186     else
187     {
188         m_opaque_sp.reset();
189     }
190 }
191 
192 bool
193 SBFrame::IsValid() const
194 {
195     StackFrameImplSP impl_sp (m_opaque_sp);
196     if (impl_sp)
197         return (impl_sp->GetFrameSP().get() != NULL);
198     return false;
199 }
200 
201 SBSymbolContext
202 SBFrame::GetSymbolContext (uint32_t resolve_scope) const
203 {
204 
205     SBSymbolContext sb_sym_ctx;
206     StackFrameSP frame_sp(GetFrameSP());
207     if (frame_sp)
208     {
209         Mutex::Locker api_locker (frame_sp->GetThread().GetProcess().GetTarget().GetAPIMutex());
210         sb_sym_ctx.SetSymbolContext(&frame_sp->GetSymbolContext (resolve_scope));
211     }
212 
213     LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
214     if (log)
215         log->Printf ("SBFrame(%p)::GetSymbolContext (resolve_scope=0x%8.8x) => SBSymbolContext(%p)",
216                      frame_sp.get(), resolve_scope, sb_sym_ctx.get());
217 
218     return sb_sym_ctx;
219 }
220 
221 SBModule
222 SBFrame::GetModule () const
223 {
224     SBModule sb_module;
225     ModuleSP module_sp;
226     StackFrameSP frame_sp(GetFrameSP());
227     if (frame_sp)
228     {
229         Mutex::Locker api_locker (frame_sp->GetThread().GetProcess().GetTarget().GetAPIMutex());
230         module_sp = frame_sp->GetSymbolContext (eSymbolContextModule).module_sp;
231         sb_module.SetSP (module_sp);
232     }
233 
234     LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
235     if (log)
236         log->Printf ("SBFrame(%p)::GetModule () => SBModule(%p)",
237                      frame_sp.get(), module_sp.get());
238 
239     return sb_module;
240 }
241 
242 SBCompileUnit
243 SBFrame::GetCompileUnit () const
244 {
245     SBCompileUnit sb_comp_unit;
246     StackFrameSP frame_sp(GetFrameSP());
247     if (frame_sp)
248     {
249         Mutex::Locker api_locker (frame_sp->GetThread().GetProcess().GetTarget().GetAPIMutex());
250         sb_comp_unit.reset (frame_sp->GetSymbolContext (eSymbolContextCompUnit).comp_unit);
251     }
252     LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
253     if (log)
254         log->Printf ("SBFrame(%p)::GetModule () => SBCompileUnit(%p)",
255                      frame_sp.get(), sb_comp_unit.get());
256 
257     return sb_comp_unit;
258 }
259 
260 SBFunction
261 SBFrame::GetFunction () const
262 {
263     SBFunction sb_function;
264     StackFrameSP frame_sp(GetFrameSP());
265     if (frame_sp)
266     {
267         Mutex::Locker api_locker (frame_sp->GetThread().GetProcess().GetTarget().GetAPIMutex());
268         sb_function.reset(frame_sp->GetSymbolContext (eSymbolContextFunction).function);
269     }
270     LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
271     if (log)
272         log->Printf ("SBFrame(%p)::GetFunction () => SBFunction(%p)",
273                      frame_sp.get(), sb_function.get());
274 
275     return sb_function;
276 }
277 
278 SBSymbol
279 SBFrame::GetSymbol () const
280 {
281     SBSymbol sb_symbol;
282     StackFrameSP frame_sp(GetFrameSP());
283     if (frame_sp)
284     {
285         Mutex::Locker api_locker (frame_sp->GetThread().GetProcess().GetTarget().GetAPIMutex());
286         sb_symbol.reset(frame_sp->GetSymbolContext (eSymbolContextSymbol).symbol);
287     }
288     LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
289     if (log)
290         log->Printf ("SBFrame(%p)::GetSymbol () => SBSymbol(%p)",
291                      frame_sp.get(), sb_symbol.get());
292     return sb_symbol;
293 }
294 
295 SBBlock
296 SBFrame::GetBlock () const
297 {
298     SBBlock sb_block;
299     StackFrameSP frame_sp(GetFrameSP());
300     if (frame_sp)
301     {
302         Mutex::Locker api_locker (frame_sp->GetThread().GetProcess().GetTarget().GetAPIMutex());
303         sb_block.reset (frame_sp->GetSymbolContext (eSymbolContextBlock).block);
304     }
305     LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
306     if (log)
307         log->Printf ("SBFrame(%p)::GetBlock () => SBBlock(%p)",
308                      frame_sp.get(), sb_block.get());
309     return sb_block;
310 }
311 
312 SBBlock
313 SBFrame::GetFrameBlock () const
314 {
315     SBBlock sb_block;
316     StackFrameSP frame_sp(GetFrameSP());
317     if (frame_sp)
318     {
319         Mutex::Locker api_locker (frame_sp->GetThread().GetProcess().GetTarget().GetAPIMutex());
320         sb_block.reset(frame_sp->GetFrameBlock ());
321     }
322     LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
323     if (log)
324         log->Printf ("SBFrame(%p)::GetFrameBlock () => SBBlock(%p)",
325                      frame_sp.get(), sb_block.get());
326     return sb_block;
327 }
328 
329 SBLineEntry
330 SBFrame::GetLineEntry () const
331 {
332     SBLineEntry sb_line_entry;
333     StackFrameSP frame_sp(GetFrameSP());
334     if (frame_sp)
335     {
336         Mutex::Locker api_locker (frame_sp->GetThread().GetProcess().GetTarget().GetAPIMutex());
337         sb_line_entry.SetLineEntry (frame_sp->GetSymbolContext (eSymbolContextLineEntry).line_entry);
338     }
339     LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
340     if (log)
341         log->Printf ("SBFrame(%p)::GetLineEntry () => SBLineEntry(%p)",
342                      frame_sp.get(), sb_line_entry.get());
343     return sb_line_entry;
344 }
345 
346 uint32_t
347 SBFrame::GetFrameID () const
348 {
349     uint32_t frame_idx = UINT32_MAX;
350 
351 
352     StackFrameSP frame_sp(GetFrameSP());
353     if (frame_sp)
354         frame_idx = frame_sp->GetFrameIndex ();
355 
356     LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
357     if (log)
358         log->Printf ("SBFrame(%p)::GetFrameID () => %u",
359                      frame_sp.get(), frame_idx);
360     return frame_idx;
361 }
362 
363 addr_t
364 SBFrame::GetPC () const
365 {
366     addr_t addr = LLDB_INVALID_ADDRESS;
367     StackFrameSP frame_sp(GetFrameSP());
368     if (frame_sp)
369     {
370         Mutex::Locker api_locker (frame_sp->GetThread().GetProcess().GetTarget().GetAPIMutex());
371         addr = frame_sp->GetFrameCodeAddress().GetOpcodeLoadAddress (&frame_sp->GetThread().GetProcess().GetTarget());
372     }
373 
374     LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
375     if (log)
376         log->Printf ("SBFrame(%p)::GetPC () => 0x%llx", frame_sp.get(), addr);
377 
378     return addr;
379 }
380 
381 bool
382 SBFrame::SetPC (addr_t new_pc)
383 {
384     bool ret_val = false;
385     StackFrameSP frame_sp(GetFrameSP());
386     if (frame_sp)
387     {
388         Mutex::Locker api_locker (frame_sp->GetThread().GetProcess().GetTarget().GetAPIMutex());
389         ret_val = frame_sp->GetRegisterContext()->SetPC (new_pc);
390     }
391 
392     LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
393     if (log)
394         log->Printf ("SBFrame(%p)::SetPC (new_pc=0x%llx) => %i",
395                      frame_sp.get(), new_pc, ret_val);
396 
397     return ret_val;
398 }
399 
400 addr_t
401 SBFrame::GetSP () const
402 {
403     addr_t addr = LLDB_INVALID_ADDRESS;
404     StackFrameSP frame_sp(GetFrameSP());
405     if (frame_sp)
406     {
407         Mutex::Locker api_locker (frame_sp->GetThread().GetProcess().GetTarget().GetAPIMutex());
408         addr = frame_sp->GetRegisterContext()->GetSP();
409     }
410     LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
411     if (log)
412         log->Printf ("SBFrame(%p)::GetSP () => 0x%llx", frame_sp.get(), addr);
413 
414     return addr;
415 }
416 
417 
418 addr_t
419 SBFrame::GetFP () const
420 {
421     addr_t addr = LLDB_INVALID_ADDRESS;
422     StackFrameSP frame_sp(GetFrameSP());
423     if (frame_sp)
424     {
425         Mutex::Locker api_locker (frame_sp->GetThread().GetProcess().GetTarget().GetAPIMutex());
426         addr = frame_sp->GetRegisterContext()->GetFP();
427     }
428 
429     LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
430     if (log)
431         log->Printf ("SBFrame(%p)::GetFP () => 0x%llx", frame_sp.get(), addr);
432     return addr;
433 }
434 
435 
436 SBAddress
437 SBFrame::GetPCAddress () const
438 {
439     SBAddress sb_addr;
440     StackFrameSP frame_sp(GetFrameSP());
441     if (frame_sp)
442     {
443         Mutex::Locker api_locker (frame_sp->GetThread().GetProcess().GetTarget().GetAPIMutex());
444         sb_addr.SetAddress (&frame_sp->GetFrameCodeAddress());
445     }
446     LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
447     if (log)
448         log->Printf ("SBFrame(%p)::GetPCAddress () => SBAddress(%p)", frame_sp.get(), sb_addr.get());
449     return sb_addr;
450 }
451 
452 void
453 SBFrame::Clear()
454 {
455     m_opaque_sp.reset();
456 }
457 
458 SBValue
459 SBFrame::FindVariable (const char *name)
460 {
461     SBValue value;
462     StackFrameSP frame_sp(GetFrameSP());
463     if (frame_sp)
464     {
465         lldb::DynamicValueType  use_dynamic = frame_sp->CalculateTarget()->GetPreferDynamicValue();
466         value = FindVariable (name, use_dynamic);
467     }
468     return value;
469 }
470 
471 SBValue
472 SBFrame::FindVariable (const char *name, lldb::DynamicValueType use_dynamic)
473 {
474     VariableSP var_sp;
475     SBValue sb_value;
476     StackFrameSP frame_sp(GetFrameSP());
477     if (frame_sp && name && name[0])
478     {
479         VariableList variable_list;
480         Mutex::Locker api_locker (frame_sp->GetThread().GetProcess().GetTarget().GetAPIMutex());
481         SymbolContext sc (frame_sp->GetSymbolContext (eSymbolContextBlock));
482 
483         if (sc.block)
484         {
485             const bool can_create = true;
486             const bool get_parent_variables = true;
487             const bool stop_if_block_is_inlined_function = true;
488 
489             if (sc.block->AppendVariables (can_create,
490                                            get_parent_variables,
491                                            stop_if_block_is_inlined_function,
492                                            &variable_list))
493             {
494                 var_sp = variable_list.FindVariable (ConstString(name));
495             }
496         }
497 
498         if (var_sp)
499             *sb_value = ValueObjectSP (frame_sp->GetValueObjectForFrameVariable(var_sp, use_dynamic));
500 
501     }
502 
503     LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
504     if (log)
505         log->Printf ("SBFrame(%p)::FindVariable (name=\"%s\") => SBValue(%p)",
506                      frame_sp.get(), name, sb_value.get());
507 
508     return sb_value;
509 }
510 
511 SBValue
512 SBFrame::FindValue (const char *name, ValueType value_type)
513 {
514     SBValue value;
515     StackFrameSP frame_sp(GetFrameSP());
516     if (frame_sp)
517     {
518         lldb::DynamicValueType use_dynamic = frame_sp->CalculateTarget()->GetPreferDynamicValue();
519         value = FindValue (name, value_type, use_dynamic);
520     }
521     return value;
522 }
523 
524 SBValue
525 SBFrame::FindValue (const char *name, ValueType value_type, lldb::DynamicValueType use_dynamic)
526 {
527     SBValue sb_value;
528     StackFrameSP frame_sp(GetFrameSP());
529     if (frame_sp && name && name[0])
530     {
531         Mutex::Locker api_locker (frame_sp->GetThread().GetProcess().GetTarget().GetAPIMutex());
532 
533         switch (value_type)
534         {
535         case eValueTypeVariableGlobal:      // global variable
536         case eValueTypeVariableStatic:      // static variable
537         case eValueTypeVariableArgument:    // function argument variables
538         case eValueTypeVariableLocal:       // function local variables
539             {
540                 VariableList *variable_list = frame_sp->GetVariableList(true);
541 
542                 SymbolContext sc (frame_sp->GetSymbolContext (eSymbolContextBlock));
543 
544                 const bool can_create = true;
545                 const bool get_parent_variables = true;
546                 const bool stop_if_block_is_inlined_function = true;
547 
548                 if (sc.block && sc.block->AppendVariables (can_create,
549                                                            get_parent_variables,
550                                                            stop_if_block_is_inlined_function,
551                                                            variable_list))
552                 {
553                     ConstString const_name(name);
554                     const uint32_t num_variables = variable_list->GetSize();
555                     for (uint32_t i = 0; i < num_variables; ++i)
556                     {
557                         VariableSP variable_sp (variable_list->GetVariableAtIndex(i));
558                         if (variable_sp &&
559                             variable_sp->GetScope() == value_type &&
560                             variable_sp->GetName() == const_name)
561                         {
562                             *sb_value = ValueObjectSP (frame_sp->GetValueObjectForFrameVariable(variable_sp,
563                                                                                                    use_dynamic));
564                             break;
565                         }
566                     }
567                 }
568             }
569             break;
570 
571         case eValueTypeRegister:            // stack frame register value
572             {
573                 RegisterContextSP reg_ctx (frame_sp->GetRegisterContext());
574                 if (reg_ctx)
575                 {
576                     const uint32_t num_regs = reg_ctx->GetRegisterCount();
577                     for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx)
578                     {
579                         const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoAtIndex (reg_idx);
580                         if (reg_info &&
581                             ((reg_info->name && strcasecmp (reg_info->name, name) == 0) ||
582                              (reg_info->alt_name && strcasecmp (reg_info->alt_name, name) == 0)))
583                         {
584                             *sb_value = ValueObjectRegister::Create (frame_sp.get(), reg_ctx, reg_idx);
585                         }
586                     }
587                 }
588             }
589             break;
590 
591         case eValueTypeRegisterSet:         // A collection of stack frame register values
592             {
593                 RegisterContextSP reg_ctx (frame_sp->GetRegisterContext());
594                 if (reg_ctx)
595                 {
596                     const uint32_t num_sets = reg_ctx->GetRegisterSetCount();
597                     for (uint32_t set_idx = 0; set_idx < num_sets; ++set_idx)
598                     {
599                         const RegisterSet *reg_set = reg_ctx->GetRegisterSet (set_idx);
600                         if (reg_set &&
601                             ((reg_set->name && strcasecmp (reg_set->name, name) == 0) ||
602                              (reg_set->short_name && strcasecmp (reg_set->short_name, name) == 0)))
603                         {
604                             *sb_value = ValueObjectRegisterSet::Create (frame_sp.get(), reg_ctx, set_idx);
605                         }
606                     }
607                 }
608             }
609             break;
610 
611         case eValueTypeConstResult:         // constant result variables
612             {
613                 ConstString const_name(name);
614                 ClangExpressionVariableSP expr_var_sp (frame_sp->GetThread().GetProcess().GetTarget().GetPersistentVariables().GetVariable (const_name));
615                 if (expr_var_sp)
616                     *sb_value = expr_var_sp->GetValueObject();
617             }
618             break;
619 
620         default:
621             break;
622         }
623     }
624 
625     LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
626     if (log)
627         log->Printf ("SBFrame(%p)::FindVariableInScope (name=\"%s\", value_type=%i) => SBValue(%p)",
628                      frame_sp.get(), name, value_type, sb_value.get());
629 
630 
631     return sb_value;
632 }
633 
634 bool
635 SBFrame::operator == (const SBFrame &rhs) const
636 {
637     return GetFrameSP().get() == rhs.GetFrameSP().get();
638 }
639 
640 bool
641 SBFrame::operator != (const SBFrame &rhs) const
642 {
643     return GetFrameSP().get() != rhs.GetFrameSP().get();
644 }
645 
646 SBThread
647 SBFrame::GetThread () const
648 {
649     LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
650 
651     SBThread sb_thread;
652     ThreadSP thread_sp;
653     StackFrameSP frame_sp(GetFrameSP());
654     if (frame_sp)
655     {
656         Mutex::Locker api_locker (frame_sp->GetThread().GetProcess().GetTarget().GetAPIMutex());
657         thread_sp = frame_sp->GetThread().shared_from_this();
658         sb_thread.SetThread (thread_sp);
659     }
660 
661     if (log)
662     {
663         SBStream sstr;
664         sb_thread.GetDescription (sstr);
665         log->Printf ("SBFrame(%p)::GetThread () => SBThread(%p): %s", frame_sp.get(),
666                      thread_sp.get(), sstr.GetData());
667     }
668 
669     return sb_thread;
670 }
671 
672 const char *
673 SBFrame::Disassemble () const
674 {
675     const char *disassembly = NULL;
676     StackFrameSP frame_sp(GetFrameSP());
677     if (frame_sp)
678     {
679         Mutex::Locker api_locker (frame_sp->GetThread().GetProcess().GetTarget().GetAPIMutex());
680         disassembly = frame_sp->Disassemble();
681     }
682     LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
683 
684     if (log)
685         log->Printf ("SBFrame(%p)::Disassemble () => %s", frame_sp.get(), disassembly);
686 
687     return disassembly;
688 }
689 
690 
691 SBValueList
692 SBFrame::GetVariables (bool arguments,
693                        bool locals,
694                        bool statics,
695                        bool in_scope_only)
696 {
697     SBValueList value_list;
698     StackFrameSP frame_sp(GetFrameSP());
699     if (frame_sp)
700     {
701         lldb::DynamicValueType use_dynamic = frame_sp->CalculateTarget()->GetPreferDynamicValue();
702         value_list = GetVariables (arguments, locals, statics, in_scope_only, use_dynamic);
703     }
704     return value_list;
705 }
706 
707 SBValueList
708 SBFrame::GetVariables (bool arguments,
709                        bool locals,
710                        bool statics,
711                        bool in_scope_only,
712                        lldb::DynamicValueType  use_dynamic)
713 {
714     LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
715 
716     SBValueList value_list;
717     StackFrameSP frame_sp(GetFrameSP());
718 
719     if (log)
720         log->Printf ("SBFrame(%p)::GetVariables (arguments=%i, locals=%i, statics=%i, in_scope_only=%i)",
721                      frame_sp.get(),
722                      arguments,
723                      locals,
724                      statics,
725                      in_scope_only);
726 
727     if (frame_sp)
728     {
729 
730         size_t i;
731         VariableList *variable_list = NULL;
732         // Scope for locker
733         {
734             Mutex::Locker api_locker (frame_sp->GetThread().GetProcess().GetTarget().GetAPIMutex());
735             variable_list = frame_sp->GetVariableList(true);
736         }
737         if (variable_list)
738         {
739             const size_t num_variables = variable_list->GetSize();
740             if (num_variables)
741             {
742                 for (i = 0; i < num_variables; ++i)
743                 {
744                     VariableSP variable_sp (variable_list->GetVariableAtIndex(i));
745                     if (variable_sp)
746                     {
747                         bool add_variable = false;
748                         switch (variable_sp->GetScope())
749                         {
750                         case eValueTypeVariableGlobal:
751                         case eValueTypeVariableStatic:
752                             add_variable = statics;
753                             break;
754 
755                         case eValueTypeVariableArgument:
756                             add_variable = arguments;
757                             break;
758 
759                         case eValueTypeVariableLocal:
760                             add_variable = locals;
761                             break;
762 
763                         default:
764                             break;
765                         }
766                         if (add_variable)
767                         {
768                             if (in_scope_only && !variable_sp->IsInScope(frame_sp.get()))
769                                 continue;
770 
771                             value_list.Append(frame_sp->GetValueObjectForFrameVariable (variable_sp, use_dynamic));
772                         }
773                     }
774                 }
775             }
776         }
777     }
778 
779     if (log)
780     {
781         log->Printf ("SBFrame(%p)::GetVariables (...) => SBValueList(%p)", frame_sp.get(),
782                      value_list.get());
783     }
784 
785     return value_list;
786 }
787 
788 SBValueList
789 SBFrame::GetRegisters ()
790 {
791     LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
792 
793     SBValueList value_list;
794     StackFrameSP frame_sp(GetFrameSP());
795     if (frame_sp)
796     {
797         Mutex::Locker api_locker (frame_sp->GetThread().GetProcess().GetTarget().GetAPIMutex());
798         RegisterContextSP reg_ctx (frame_sp->GetRegisterContext());
799         if (reg_ctx)
800         {
801             const uint32_t num_sets = reg_ctx->GetRegisterSetCount();
802             for (uint32_t set_idx = 0; set_idx < num_sets; ++set_idx)
803             {
804                 value_list.Append(ValueObjectRegisterSet::Create (frame_sp.get(), reg_ctx, set_idx));
805             }
806         }
807     }
808 
809     if (log)
810         log->Printf ("SBFrame(%p)::Registers () => SBValueList(%p)", frame_sp.get(), value_list.get());
811 
812     return value_list;
813 }
814 
815 bool
816 SBFrame::GetDescription (SBStream &description)
817 {
818     Stream &strm = description.ref();
819 
820     StackFrameSP frame_sp(GetFrameSP());
821     if (frame_sp)
822     {
823         Mutex::Locker api_locker (frame_sp->GetThread().GetProcess().GetTarget().GetAPIMutex());
824         frame_sp->DumpUsingSettingsFormat (&strm);
825     }
826     else
827         strm.PutCString ("No value");
828 
829     return true;
830 }
831 
832 SBValue
833 SBFrame::EvaluateExpression (const char *expr)
834 {
835     SBValue result;
836     StackFrameSP frame_sp(GetFrameSP());
837     if (frame_sp)
838     {
839         lldb::DynamicValueType use_dynamic = frame_sp->CalculateTarget()->GetPreferDynamicValue();
840         result = EvaluateExpression (expr, use_dynamic);
841     }
842     return result;
843 }
844 
845 SBValue
846 SBFrame::EvaluateExpression (const char *expr, lldb::DynamicValueType fetch_dynamic_value)
847 {
848     LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
849 
850     LogSP expr_log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
851 
852     ExecutionResults exe_results;
853     SBValue expr_result;
854 
855     StackFrameSP frame_sp(GetFrameSP());
856     if (log)
857         log->Printf ("SBFrame(%p)::EvaluateExpression (expr=\"%s\")...", frame_sp.get(), expr);
858 
859     if (frame_sp)
860     {
861         Mutex::Locker api_locker (frame_sp->GetThread().GetProcess().GetTarget().GetAPIMutex());
862 
863 
864         StreamString frame_description;
865         frame_sp->DumpUsingSettingsFormat (&frame_description);
866 
867         Host::SetCrashDescriptionWithFormat ("SBFrame::EvaluateExpression (expr = \"%s\", fetch_dynamic_value = %u) %s",
868                                              expr, fetch_dynamic_value, frame_description.GetString().c_str());
869 
870         const bool coerce_to_id = false;
871         const bool unwind_on_error = true;
872         const bool keep_in_memory = false;
873 
874         exe_results = frame_sp->GetThread().GetProcess().GetTarget().EvaluateExpression(expr,
875                                                                                         frame_sp.get(),
876                                                                                         eExecutionPolicyOnlyWhenNeeded,
877                                                                                         coerce_to_id,
878                                                                                         unwind_on_error,
879                                                                                         keep_in_memory,
880                                                                                         fetch_dynamic_value,
881                                                                                         *expr_result);
882 
883         Host::SetCrashDescription (NULL);
884     }
885 
886     if (expr_log)
887         expr_log->Printf("** [SBFrame::EvaluateExpression] Expression result is %s, summary %s **",
888                          expr_result.GetValue(),
889                          expr_result.GetSummary());
890 
891     if (log)
892         log->Printf ("SBFrame(%p)::EvaluateExpression (expr=\"%s\") => SBValue(%p) (execution result=%d)", frame_sp.get(),
893                      expr,
894                      expr_result.get(),
895                      exe_results);
896 
897     return expr_result;
898 }
899 
900 bool
901 SBFrame::IsInlined()
902 {
903     StackFrameSP frame_sp(GetFrameSP());
904     if (frame_sp)
905     {
906         Block *block = frame_sp->GetSymbolContext(eSymbolContextBlock).block;
907         if (block)
908             return block->GetContainingInlinedBlock () != NULL;
909     }
910     return false;
911 }
912 
913 const char *
914 SBFrame::GetFunctionName()
915 {
916     const char *name = NULL;
917     StackFrameSP frame_sp(GetFrameSP());
918     if (frame_sp)
919     {
920         SymbolContext sc (frame_sp->GetSymbolContext(eSymbolContextFunction | eSymbolContextBlock | eSymbolContextSymbol));
921         if (sc.block)
922         {
923             Block *inlined_block = sc.block->GetContainingInlinedBlock ();
924             if (inlined_block)
925             {
926                 const InlineFunctionInfo* inlined_info = inlined_block->GetInlinedFunctionInfo();
927                 name = inlined_info->GetName().AsCString();
928             }
929         }
930 
931         if (name == NULL)
932         {
933             if (sc.function)
934                 name = sc.function->GetName().GetCString();
935         }
936 
937         if (name == NULL)
938         {
939             if (sc.symbol)
940                 name = sc.symbol->GetName().GetCString();
941         }
942     }
943     return name;
944 }
945 
946