<rdar://problem/9959501>

More KDP debugging process. We can not set breakpoints, hit them, resume, step and detach while running.

llvm-svn: 164584
diff --git a/lldb/source/Plugins/Process/Utility/StopInfoMachException.cpp b/lldb/source/Plugins/Process/Utility/StopInfoMachException.cpp
index bc313f7..87c9962 100644
--- a/lldb/source/Plugins/Process/Utility/StopInfoMachException.cpp
+++ b/lldb/source/Plugins/Process/Utility/StopInfoMachException.cpp
@@ -242,6 +242,9 @@
 }
 
 
+
+
+
 StopInfoSP
 StopInfoMachException::CreateStopReasonWithMachException 
 (
@@ -250,11 +253,14 @@
     uint32_t exc_data_count,
     uint64_t exc_code,
     uint64_t exc_sub_code,
-    uint64_t exc_sub_sub_code
+    uint64_t exc_sub_sub_code,
+    bool pc_already_adjusted,
+    bool adjust_pc_if_needed
 )
 {
     if (exc_type != 0)
     {
+        uint32_t pc_decrement = 0;
         ExecutionContext exe_ctx (thread.shared_from_this());
         Target *target = exe_ctx.GetTargetPtr();
         const llvm::Triple::ArchType cpu = target ? target->GetArchitecture().GetMachine() : llvm::Triple::UnknownArch;
@@ -300,6 +306,7 @@
         case 6: // EXC_BREAKPOINT
             {
                 bool is_software_breakpoint = false;
+                bool is_trace_if_software_breakpoint_missing = false;
                 switch (cpu)
                 {
                 case llvm::Triple::x86:
@@ -323,9 +330,16 @@
                             return StopInfo::CreateStopReasonWithWatchpointID(thread, wp_sp->GetID());
                         }
                     }
-                    else if (exc_code == 2) // EXC_I386_BPT
+                    else if (exc_code == 2 ||   // EXC_I386_BPT
+                             exc_code == 3)     // EXC_I386_BPTFLT
                     {
+                        // KDP returns EXC_I386_BPTFLT for trace breakpoints
+                        if (exc_code == 3)
+                            is_trace_if_software_breakpoint_missing = true;
+
                         is_software_breakpoint = true;
+                        if (!pc_already_adjusted)
+                            pc_decrement = 1;
                     }
                     break;
 
@@ -353,8 +367,11 @@
                         // EXC_ARM_DA_DEBUG seems to be reused for EXC_BREAKPOINT as well as EXC_BAD_ACCESS
                         return StopInfo::CreateStopReasonToTrace(thread);
                     }
-                    else
-                        is_software_breakpoint = exc_code == 1; // EXC_ARM_BREAKPOINT
+                    else if (exc_code == 1)
+                    {
+                        is_software_breakpoint = true;
+                        is_trace_if_software_breakpoint_missing = true;
+                    }
                     break;
 
                 default:
@@ -363,14 +380,22 @@
 
                 if (is_software_breakpoint)
                 {
-                    addr_t pc = thread.GetRegisterContext()->GetPC();
+                    RegisterContextSP reg_ctx_sp (thread.GetRegisterContext());
+                    addr_t pc = reg_ctx_sp->GetPC() - pc_decrement;
+
                     ProcessSP process_sp (thread.CalculateProcess());
 
                     lldb::BreakpointSiteSP bp_site_sp;
                     if (process_sp)
                         bp_site_sp = process_sp->GetBreakpointSiteList().FindByAddress(pc);
-                    if (bp_site_sp)
+                    if (bp_site_sp && bp_site_sp->IsEnabled())
                     {
+                        // Update the PC if we were asked to do so, but only do
+                        // so if we find a breakpoint that we know about cause
+                        // this could be a trap instruction in the code
+                        if (pc_decrement > 0 && adjust_pc_if_needed)
+                            reg_ctx_sp->SetPC (pc);
+
                         // If the breakpoint is for this thread, then we'll report the hit, but if it is for another thread,
                         // we can just report no reason.  We don't need to worry about stepping over the breakpoint here, that
                         // will be taken care of when the thread resumes and notices that there's a breakpoint under the pc.
@@ -379,7 +404,8 @@
                         else
                             return StopInfoSP();
                     }
-                    else if (cpu == llvm::Triple::arm)
+                    
+                    if (is_trace_if_software_breakpoint_missing)
                     {
                         return StopInfo::CreateStopReasonToTrace (thread);
                     }