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 lldb::SBValue
459 SBFrame::GetValueForVariablePath (const char *var_path)
460 {
461     SBValue sb_value;
462     StackFrameSP frame_sp(GetFrameSP());
463     if (frame_sp)
464     {
465         lldb::DynamicValueType  use_dynamic = frame_sp->CalculateTarget()->GetPreferDynamicValue();
466         sb_value = GetValueForVariablePath (var_path, use_dynamic);
467     }
468     return sb_value;
469 }
470 
471 lldb::SBValue
472 SBFrame::GetValueForVariablePath (const char *var_path, DynamicValueType use_dynamic)
473 {
474     SBValue sb_value;
475     StackFrameSP frame_sp(GetFrameSP());
476     if (frame_sp && var_path && var_path[0])
477     {
478         Mutex::Locker api_locker (frame_sp->GetThread().GetProcess().GetTarget().GetAPIMutex());
479         VariableSP var_sp;
480         Error error;
481         ValueObjectSP value_sp (frame_sp->GetValueForVariableExpressionPath (var_path,
482                                                                              use_dynamic,
483                                                                              StackFrame::eExpressionPathOptionCheckPtrVsMember,
484                                                                              var_sp,
485                                                                              error));
486         sb_value.SetSP(value_sp);
487     }
488     return sb_value;
489 }
490 
491 SBValue
492 SBFrame::FindVariable (const char *name)
493 {
494     SBValue value;
495     StackFrameSP frame_sp(GetFrameSP());
496     if (frame_sp)
497     {
498         lldb::DynamicValueType  use_dynamic = frame_sp->CalculateTarget()->GetPreferDynamicValue();
499         value = FindVariable (name, use_dynamic);
500     }
501     return value;
502 }
503 
504 
505 SBValue
506 SBFrame::FindVariable (const char *name, lldb::DynamicValueType use_dynamic)
507 {
508     VariableSP var_sp;
509     SBValue sb_value;
510     ValueObjectSP value_sp;
511     StackFrameSP frame_sp(GetFrameSP());
512     if (frame_sp && name && name[0])
513     {
514         VariableList variable_list;
515         Mutex::Locker api_locker (frame_sp->GetThread().GetProcess().GetTarget().GetAPIMutex());
516         SymbolContext sc (frame_sp->GetSymbolContext (eSymbolContextBlock));
517 
518         if (sc.block)
519         {
520             const bool can_create = true;
521             const bool get_parent_variables = true;
522             const bool stop_if_block_is_inlined_function = true;
523 
524             if (sc.block->AppendVariables (can_create,
525                                            get_parent_variables,
526                                            stop_if_block_is_inlined_function,
527                                            &variable_list))
528             {
529                 var_sp = variable_list.FindVariable (ConstString(name));
530             }
531         }
532 
533         if (var_sp)
534         {
535             value_sp = frame_sp->GetValueObjectForFrameVariable(var_sp, use_dynamic);
536             sb_value.SetSP(value_sp);
537         }
538 
539     }
540 
541     LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
542     if (log)
543         log->Printf ("SBFrame(%p)::FindVariable (name=\"%s\") => SBValue(%p)",
544                      frame_sp.get(), name, value_sp.get());
545 
546     return sb_value;
547 }
548 
549 SBValue
550 SBFrame::FindValue (const char *name, ValueType value_type)
551 {
552     SBValue value;
553     StackFrameSP frame_sp(GetFrameSP());
554     if (frame_sp)
555     {
556         lldb::DynamicValueType use_dynamic = frame_sp->CalculateTarget()->GetPreferDynamicValue();
557         value = FindValue (name, value_type, use_dynamic);
558     }
559     return value;
560 }
561 
562 SBValue
563 SBFrame::FindValue (const char *name, ValueType value_type, lldb::DynamicValueType use_dynamic)
564 {
565     SBValue sb_value;
566     ValueObjectSP value_sp;
567     StackFrameSP frame_sp(GetFrameSP());
568     if (frame_sp && name && name[0])
569     {
570         Mutex::Locker api_locker (frame_sp->GetThread().GetProcess().GetTarget().GetAPIMutex());
571 
572         switch (value_type)
573         {
574         case eValueTypeVariableGlobal:      // global variable
575         case eValueTypeVariableStatic:      // static variable
576         case eValueTypeVariableArgument:    // function argument variables
577         case eValueTypeVariableLocal:       // function local variables
578             {
579                 VariableList *variable_list = frame_sp->GetVariableList(true);
580 
581                 SymbolContext sc (frame_sp->GetSymbolContext (eSymbolContextBlock));
582 
583                 const bool can_create = true;
584                 const bool get_parent_variables = true;
585                 const bool stop_if_block_is_inlined_function = true;
586 
587                 if (sc.block && sc.block->AppendVariables (can_create,
588                                                            get_parent_variables,
589                                                            stop_if_block_is_inlined_function,
590                                                            variable_list))
591                 {
592                     ConstString const_name(name);
593                     const uint32_t num_variables = variable_list->GetSize();
594                     for (uint32_t i = 0; i < num_variables; ++i)
595                     {
596                         VariableSP variable_sp (variable_list->GetVariableAtIndex(i));
597                         if (variable_sp &&
598                             variable_sp->GetScope() == value_type &&
599                             variable_sp->GetName() == const_name)
600                         {
601                             value_sp = frame_sp->GetValueObjectForFrameVariable (variable_sp, use_dynamic);
602                             sb_value.SetSP (value_sp);
603                             break;
604                         }
605                     }
606                 }
607             }
608             break;
609 
610         case eValueTypeRegister:            // stack frame register value
611             {
612                 RegisterContextSP reg_ctx (frame_sp->GetRegisterContext());
613                 if (reg_ctx)
614                 {
615                     const uint32_t num_regs = reg_ctx->GetRegisterCount();
616                     for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx)
617                     {
618                         const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoAtIndex (reg_idx);
619                         if (reg_info &&
620                             ((reg_info->name && strcasecmp (reg_info->name, name) == 0) ||
621                              (reg_info->alt_name && strcasecmp (reg_info->alt_name, name) == 0)))
622                         {
623                             value_sp = ValueObjectRegister::Create (frame_sp.get(), reg_ctx, reg_idx);
624                             sb_value.SetSP (value_sp);
625                             break;
626                         }
627                     }
628                 }
629             }
630             break;
631 
632         case eValueTypeRegisterSet:         // A collection of stack frame register values
633             {
634                 RegisterContextSP reg_ctx (frame_sp->GetRegisterContext());
635                 if (reg_ctx)
636                 {
637                     const uint32_t num_sets = reg_ctx->GetRegisterSetCount();
638                     for (uint32_t set_idx = 0; set_idx < num_sets; ++set_idx)
639                     {
640                         const RegisterSet *reg_set = reg_ctx->GetRegisterSet (set_idx);
641                         if (reg_set &&
642                             ((reg_set->name && strcasecmp (reg_set->name, name) == 0) ||
643                              (reg_set->short_name && strcasecmp (reg_set->short_name, name) == 0)))
644                         {
645                             value_sp = ValueObjectRegisterSet::Create (frame_sp.get(), reg_ctx, set_idx);
646                             sb_value.SetSP (value_sp);
647                             break;
648                         }
649                     }
650                 }
651             }
652             break;
653 
654         case eValueTypeConstResult:         // constant result variables
655             {
656                 ConstString const_name(name);
657                 ClangExpressionVariableSP expr_var_sp (frame_sp->GetThread().GetProcess().GetTarget().GetPersistentVariables().GetVariable (const_name));
658                 if (expr_var_sp)
659                 {
660                     value_sp = expr_var_sp->GetValueObject();
661                     sb_value.SetSP (value_sp);
662                 }
663             }
664             break;
665 
666         default:
667             break;
668         }
669     }
670 
671     LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
672     if (log)
673         log->Printf ("SBFrame(%p)::FindVariableInScope (name=\"%s\", value_type=%i) => SBValue(%p)",
674                      frame_sp.get(), name, value_type, value_sp.get());
675 
676 
677     return sb_value;
678 }
679 
680 bool
681 SBFrame::operator == (const SBFrame &rhs) const
682 {
683     return GetFrameSP().get() == rhs.GetFrameSP().get();
684 }
685 
686 bool
687 SBFrame::operator != (const SBFrame &rhs) const
688 {
689     return GetFrameSP().get() != rhs.GetFrameSP().get();
690 }
691 
692 SBThread
693 SBFrame::GetThread () const
694 {
695     LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
696 
697     SBThread sb_thread;
698     ThreadSP thread_sp;
699     StackFrameSP frame_sp(GetFrameSP());
700     if (frame_sp)
701     {
702         Mutex::Locker api_locker (frame_sp->GetThread().GetProcess().GetTarget().GetAPIMutex());
703         thread_sp = frame_sp->GetThread().shared_from_this();
704         sb_thread.SetThread (thread_sp);
705     }
706 
707     if (log)
708     {
709         SBStream sstr;
710         sb_thread.GetDescription (sstr);
711         log->Printf ("SBFrame(%p)::GetThread () => SBThread(%p): %s", frame_sp.get(),
712                      thread_sp.get(), sstr.GetData());
713     }
714 
715     return sb_thread;
716 }
717 
718 const char *
719 SBFrame::Disassemble () const
720 {
721     const char *disassembly = NULL;
722     StackFrameSP frame_sp(GetFrameSP());
723     if (frame_sp)
724     {
725         Mutex::Locker api_locker (frame_sp->GetThread().GetProcess().GetTarget().GetAPIMutex());
726         disassembly = frame_sp->Disassemble();
727     }
728     LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
729 
730     if (log)
731         log->Printf ("SBFrame(%p)::Disassemble () => %s", frame_sp.get(), disassembly);
732 
733     return disassembly;
734 }
735 
736 
737 SBValueList
738 SBFrame::GetVariables (bool arguments,
739                        bool locals,
740                        bool statics,
741                        bool in_scope_only)
742 {
743     SBValueList value_list;
744     StackFrameSP frame_sp(GetFrameSP());
745     if (frame_sp)
746     {
747         lldb::DynamicValueType use_dynamic = frame_sp->CalculateTarget()->GetPreferDynamicValue();
748         value_list = GetVariables (arguments, locals, statics, in_scope_only, use_dynamic);
749     }
750     return value_list;
751 }
752 
753 SBValueList
754 SBFrame::GetVariables (bool arguments,
755                        bool locals,
756                        bool statics,
757                        bool in_scope_only,
758                        lldb::DynamicValueType  use_dynamic)
759 {
760     LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
761 
762     SBValueList value_list;
763     StackFrameSP frame_sp(GetFrameSP());
764 
765     if (log)
766         log->Printf ("SBFrame(%p)::GetVariables (arguments=%i, locals=%i, statics=%i, in_scope_only=%i)",
767                      frame_sp.get(),
768                      arguments,
769                      locals,
770                      statics,
771                      in_scope_only);
772 
773     if (frame_sp)
774     {
775 
776         size_t i;
777         VariableList *variable_list = NULL;
778         // Scope for locker
779         {
780             Mutex::Locker api_locker (frame_sp->GetThread().GetProcess().GetTarget().GetAPIMutex());
781             variable_list = frame_sp->GetVariableList(true);
782         }
783         if (variable_list)
784         {
785             const size_t num_variables = variable_list->GetSize();
786             if (num_variables)
787             {
788                 for (i = 0; i < num_variables; ++i)
789                 {
790                     VariableSP variable_sp (variable_list->GetVariableAtIndex(i));
791                     if (variable_sp)
792                     {
793                         bool add_variable = false;
794                         switch (variable_sp->GetScope())
795                         {
796                         case eValueTypeVariableGlobal:
797                         case eValueTypeVariableStatic:
798                             add_variable = statics;
799                             break;
800 
801                         case eValueTypeVariableArgument:
802                             add_variable = arguments;
803                             break;
804 
805                         case eValueTypeVariableLocal:
806                             add_variable = locals;
807                             break;
808 
809                         default:
810                             break;
811                         }
812                         if (add_variable)
813                         {
814                             if (in_scope_only && !variable_sp->IsInScope(frame_sp.get()))
815                                 continue;
816 
817                             value_list.Append(frame_sp->GetValueObjectForFrameVariable (variable_sp, use_dynamic));
818                         }
819                     }
820                 }
821             }
822         }
823     }
824 
825     if (log)
826     {
827         log->Printf ("SBFrame(%p)::GetVariables (...) => SBValueList(%p)", frame_sp.get(),
828                      value_list.get());
829     }
830 
831     return value_list;
832 }
833 
834 SBValueList
835 SBFrame::GetRegisters ()
836 {
837     LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
838 
839     SBValueList value_list;
840     StackFrameSP frame_sp(GetFrameSP());
841     if (frame_sp)
842     {
843         Mutex::Locker api_locker (frame_sp->GetThread().GetProcess().GetTarget().GetAPIMutex());
844         RegisterContextSP reg_ctx (frame_sp->GetRegisterContext());
845         if (reg_ctx)
846         {
847             const uint32_t num_sets = reg_ctx->GetRegisterSetCount();
848             for (uint32_t set_idx = 0; set_idx < num_sets; ++set_idx)
849             {
850                 value_list.Append(ValueObjectRegisterSet::Create (frame_sp.get(), reg_ctx, set_idx));
851             }
852         }
853     }
854 
855     if (log)
856         log->Printf ("SBFrame(%p)::Registers () => SBValueList(%p)", frame_sp.get(), value_list.get());
857 
858     return value_list;
859 }
860 
861 bool
862 SBFrame::GetDescription (SBStream &description)
863 {
864     Stream &strm = description.ref();
865 
866     StackFrameSP frame_sp(GetFrameSP());
867     if (frame_sp)
868     {
869         Mutex::Locker api_locker (frame_sp->GetThread().GetProcess().GetTarget().GetAPIMutex());
870         frame_sp->DumpUsingSettingsFormat (&strm);
871     }
872     else
873         strm.PutCString ("No value");
874 
875     return true;
876 }
877 
878 SBValue
879 SBFrame::EvaluateExpression (const char *expr)
880 {
881     SBValue result;
882     StackFrameSP frame_sp(GetFrameSP());
883     if (frame_sp)
884     {
885         lldb::DynamicValueType use_dynamic = frame_sp->CalculateTarget()->GetPreferDynamicValue();
886         result = EvaluateExpression (expr, use_dynamic);
887     }
888     return result;
889 }
890 
891 SBValue
892 SBFrame::EvaluateExpression (const char *expr, lldb::DynamicValueType fetch_dynamic_value)
893 {
894     LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
895 
896     LogSP expr_log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
897 
898     ExecutionResults exe_results;
899     SBValue expr_result;
900     ValueObjectSP expr_value_sp;
901 
902     StackFrameSP frame_sp(GetFrameSP());
903     if (log)
904         log->Printf ("SBFrame(%p)::EvaluateExpression (expr=\"%s\")...", frame_sp.get(), expr);
905 
906     if (frame_sp)
907     {
908         Mutex::Locker api_locker (frame_sp->GetThread().GetProcess().GetTarget().GetAPIMutex());
909 
910 
911         StreamString frame_description;
912         frame_sp->DumpUsingSettingsFormat (&frame_description);
913 
914         Host::SetCrashDescriptionWithFormat ("SBFrame::EvaluateExpression (expr = \"%s\", fetch_dynamic_value = %u) %s",
915                                              expr, fetch_dynamic_value, frame_description.GetString().c_str());
916 
917         const bool coerce_to_id = false;
918         const bool unwind_on_error = true;
919         const bool keep_in_memory = false;
920 
921         exe_results = frame_sp->GetThread().GetProcess().GetTarget().EvaluateExpression(expr,
922                                                                                         frame_sp.get(),
923                                                                                         eExecutionPolicyOnlyWhenNeeded,
924                                                                                         coerce_to_id,
925                                                                                         unwind_on_error,
926                                                                                         keep_in_memory,
927                                                                                         fetch_dynamic_value,
928                                                                                         expr_value_sp);
929         expr_result.SetSP(expr_value_sp);
930         Host::SetCrashDescription (NULL);
931     }
932 
933     if (expr_log)
934         expr_log->Printf("** [SBFrame::EvaluateExpression] Expression result is %s, summary %s **",
935                          expr_result.GetValue(),
936                          expr_result.GetSummary());
937 
938     if (log)
939         log->Printf ("SBFrame(%p)::EvaluateExpression (expr=\"%s\") => SBValue(%p) (execution result=%d)", frame_sp.get(),
940                      expr,
941                      expr_value_sp.get(),
942                      exe_results);
943 
944     return expr_result;
945 }
946 
947 bool
948 SBFrame::IsInlined()
949 {
950     StackFrameSP frame_sp(GetFrameSP());
951     if (frame_sp)
952     {
953         Block *block = frame_sp->GetSymbolContext(eSymbolContextBlock).block;
954         if (block)
955             return block->GetContainingInlinedBlock () != NULL;
956     }
957     return false;
958 }
959 
960 const char *
961 SBFrame::GetFunctionName()
962 {
963     const char *name = NULL;
964     StackFrameSP frame_sp(GetFrameSP());
965     if (frame_sp)
966     {
967         SymbolContext sc (frame_sp->GetSymbolContext(eSymbolContextFunction | eSymbolContextBlock | eSymbolContextSymbol));
968         if (sc.block)
969         {
970             Block *inlined_block = sc.block->GetContainingInlinedBlock ();
971             if (inlined_block)
972             {
973                 const InlineFunctionInfo* inlined_info = inlined_block->GetInlinedFunctionInfo();
974                 name = inlined_info->GetName().AsCString();
975             }
976         }
977 
978         if (name == NULL)
979         {
980             if (sc.function)
981                 name = sc.function->GetName().GetCString();
982         }
983 
984         if (name == NULL)
985         {
986             if (sc.symbol)
987                 name = sc.symbol->GetName().GetCString();
988         }
989     }
990     return name;
991 }
992 
993