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