SBFrame is now threadsafe using some extra tricks. One issue is that stack
frames might go away (the object itself, not the actual logical frame) when
we are single stepping due to the way we currently sometimes end up flushing
frames when stepping in/out/over. They later will come back to life 
represented by another object yet they have the same StackID. Now when you get
a lldb::SBFrame object, it will track the frame it is initialized with until 
the thread goes away or the StackID no longer exists in the stack for the 
thread it was created on. It uses a weak_ptr to both the frame and thread and
also stores the StackID. These three items allow us to determine when the
stack frame object has gone away (the weak_ptr will be NULL) and allows us to
find the correct frame again. In our test suite we had such cases where we
were just getting lucky when something like this happened:

1 - stop at breakpoint
2 - get first frame in thread where we stopped
3 - run an expression that causes the program to JIT and run code
4 - run more expressions on the frame from step 2 which was very very luckily
    still around inside a shared pointer, yet, not part of the current 
    thread (a new stack frame object had appeared with the same stack ID and
    depth). 
    
We now avoid all such issues and properly keep up to date, or we start 
returning errors when the frame doesn't exist and always responds with
invalid answers.

Also fixed the UserSettingsController  (not going to rewrite this just yet)
so that it doesn't crash on shutdown. Using weak_ptr's came in real handy to
track when the master controller has already gone away and this allowed me to
pull out the previous NotifyOwnerIsShuttingDown() patch as it is no longer 
needed.




git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@149231 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/API/SBValue.cpp b/source/API/SBValue.cpp
index 858b8f1..b72c8f1 100644
--- a/source/API/SBValue.cpp
+++ b/source/API/SBValue.cpp
@@ -88,6 +88,8 @@
     
     if (m_opaque_sp.get())
         sb_error.SetError(m_opaque_sp->GetError());
+    else
+        sb_error.SetErrorString("error: invalid value");
     
     return sb_error;
 }
@@ -833,46 +835,44 @@
 lldb::SBTarget
 SBValue::GetTarget()
 {
-    SBTarget result;
+    SBTarget sb_target;
+    TargetSP target_sp;
     if (m_opaque_sp)
     {
-        if (m_opaque_sp->GetUpdatePoint().GetTargetSP())
-        {
-            result = SBTarget(lldb::TargetSP(m_opaque_sp->GetUpdatePoint().GetTargetSP()));
-        }
+        target_sp = m_opaque_sp->GetUpdatePoint().GetTargetSP();
+        sb_target.SetSP (target_sp);
     }
     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
     if (log)
     {
-        if (result.get() == NULL)
+        if (target_sp.get() == NULL)
             log->Printf ("SBValue(%p)::GetTarget () => NULL", m_opaque_sp.get());
         else
-            log->Printf ("SBValue(%p)::GetTarget () => %p", m_opaque_sp.get(), result.get());
+            log->Printf ("SBValue(%p)::GetTarget () => %p", m_opaque_sp.get(), target_sp.get());
     }
-    return result;
+    return sb_target;
 }
 
 lldb::SBProcess
 SBValue::GetProcess()
 {
-    SBProcess result;
+    SBProcess sb_process;
+    ProcessSP process_sp;
     if (m_opaque_sp)
     {
-        Target* target = m_opaque_sp->GetUpdatePoint().GetTargetSP().get();
-        if (target)
-        {
-            result = SBProcess(lldb::ProcessSP(target->GetProcessSP()));
-        }
+        process_sp = m_opaque_sp->GetUpdatePoint().GetProcessSP();
+        if (process_sp)
+            sb_process.SetSP (process_sp);
     }
     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
     if (log)
     {
-        if (result.get() == NULL)
+        if (process_sp.get() == NULL)
             log->Printf ("SBValue(%p)::GetProcess () => NULL", m_opaque_sp.get());
         else
-            log->Printf ("SBValue(%p)::GetProcess () => %p", m_opaque_sp.get(), result.get());
+            log->Printf ("SBValue(%p)::GetProcess () => %p", m_opaque_sp.get(), process_sp.get());
     }
-    return result;
+    return sb_process;
 }
 
 lldb::SBThread
@@ -902,23 +902,25 @@
 lldb::SBFrame
 SBValue::GetFrame()
 {
-    SBFrame result;
+    SBFrame sb_frame;
+    StackFrameSP frame_sp;
     if (m_opaque_sp)
     {
         if (m_opaque_sp->GetExecutionContextScope())
         {
-            result.SetFrame (m_opaque_sp->GetExecutionContextScope()->CalculateStackFrame()->shared_from_this());
+            frame_sp = m_opaque_sp->GetExecutionContextScope()->CalculateStackFrame()->shared_from_this();
+            sb_frame.SetFrameSP (frame_sp);
         }
     }
     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
     if (log)
     {
-        if (result.get() == NULL)
+        if (frame_sp.get() == NULL)
             log->Printf ("SBValue(%p)::GetFrame () => NULL", m_opaque_sp.get());
         else
-            log->Printf ("SBValue(%p)::GetFrame () => %p", m_opaque_sp.get(), result.get());
+            log->Printf ("SBValue(%p)::GetFrame () => %p", m_opaque_sp.get(), frame_sp.get());
     }
-    return result;
+    return sb_frame;
 }
 
 
@@ -1191,17 +1193,25 @@
     SBWatchpoint sb_wp_empty;
 
     // If the SBValue is not valid, there's no point in even trying to watch it.
-    if (!IsValid() || !GetFrame().IsValid())
+    if (!IsValid())
         return sb_wp_empty;
 
     // Read and Write cannot both be false.
     if (!read && !write)
         return sb_wp_empty;
-
+    
     // If we are watching the pointee, check that the SBValue is a pointer type.
     if (watch_pointee && !GetType().IsPointerType())
         return sb_wp_empty;
 
+    TargetSP target_sp (GetTarget().GetSP());
+    if (!target_sp)
+        return sb_wp_empty;
+    
+    StackFrameSP frame_sp (GetFrame().GetFrameSP());
+    if (!frame_sp)
+        return sb_wp_empty;
+    
     addr_t addr;
     size_t size;
     if (watch_pointee) {
@@ -1218,12 +1228,11 @@
 
     uint32_t watch_type = (read ? LLDB_WATCH_TYPE_READ : 0) |
         (write ? LLDB_WATCH_TYPE_WRITE : 0);
-    WatchpointSP wp_sp = GetFrame().m_opaque_sp->GetThread().GetProcess().GetTarget().
-        CreateWatchpoint(addr, size, watch_type);
+    WatchpointSP wp_sp = target_sp->CreateWatchpoint(addr, size, watch_type);
 
     if (wp_sp) {
         // StackFrame::GetInScopeVariableList(true) to get file globals as well.
-        VariableListSP var_list_sp(GetFrame().m_opaque_sp->GetInScopeVariableList(true));
+        VariableListSP var_list_sp(frame_sp->GetInScopeVariableList(true));
         VariableSP var_sp = var_list_sp->FindVariable(ConstString(GetName()));
         if (var_sp && var_sp->GetDeclaration().GetFile()) {
             StreamString ss;