Diff of /cmajor++/Cm/Cm.Debugger/Command.cpp [r570] .. [r571] Maximize Restore

  Switch to side-by-side view

--- a/cmajor++/Cm/Cm.Debugger/Command.cpp
+++ b/cmajor++/Cm/Cm.Debugger/Command.cpp
@@ -40,6 +40,8 @@
         "show libraries                 show debuggable libraries\n"
         "set debug library <lib> on     enable debugging library <lib>\n"
         "set debug library <lib> off    disable debugging library <lib>\n"
+        "set break on throw on          enable break when exception is thrown\n"
+        "set break on throw off         disable break when exception is thrown\n"
         "<empty line>                   repeat last command\n"
         << "\n";
     WriteOutput(s.str(), OutputKind::reply);
@@ -181,7 +183,14 @@
     SourcePos currentPos = debugInfo.CurrentPos();
     if (!currentPos.IsNull())
     {
-        next = currentPos.Next();
+        if (currentPos.Node()->Kind() == Cm::Core::CfgNodeKind::throwNode)
+        {
+            next = debugInfo.CatchPos();
+        }
+        else
+        {
+            next = currentPos.Next();
+        }
     }
     if (next.empty() && debugInfo.PosStackIsEmpty())
     {
@@ -196,13 +205,17 @@
         SourcePos funCallRetPos = debugInfo.PopPos();
         if (!funCallRetPos.IsMain())
         {
-            SharedGdbBreakReplyPtr reply = gdb.Break(funCallRetPos.FunCallCFileLine());
-            if (reply->NoSourceFile())
-            {
-                throw std::runtime_error("break reply: no source file '" + funCallRetPos.CFileLine().SourceFilePath() + "'");
-            }
-            BreakpointPtr bp(new Breakpoint(BreakpointKind::temp, debugInfo.GetNextTempBreakpointNumber(), funCallRetPos, reply->BreakpointNumber(), reply->GetSourceFileLine()));
-            debugInfo.AddBreakpoint(bp);
+            const SourceFileLine& cFileLine = funCallRetPos.FunCallCFileLine();
+            if (!cFileLine.IsEmpty())
+            {
+                SharedGdbBreakReplyPtr reply = gdb.Break(funCallRetPos.FunCallCFileLine());
+                if (reply->NoSourceFile())
+                {
+                    throw std::runtime_error("break reply: no source file '" + funCallRetPos.CFileLine().SourceFilePath() + "'");
+                }
+                BreakpointPtr bp(new Breakpoint(BreakpointKind::temp, debugInfo.GetNextTempBreakpointNumber(), funCallRetPos, reply->BreakpointNumber(), reply->GetSourceFileLine()));
+                debugInfo.AddBreakpoint(bp);
+            }
         }
     }
     std::vector<SourceFileLine> cbrk;
@@ -324,13 +337,17 @@
         SourcePos funCallRetPos = debugInfo.PopPos();
         if (!funCallRetPos.IsMain())
         {
-            SharedGdbBreakReplyPtr reply = gdb.Break(funCallRetPos.FunCallCFileLine());
-            if (reply->NoSourceFile())
-            {
-                throw std::runtime_error("break reply: no source file '" + funCallRetPos.CFileLine().SourceFilePath() + "'");
-            }
-            BreakpointPtr bp(new Breakpoint(BreakpointKind::temp, debugInfo.GetNextTempBreakpointNumber(), funCallRetPos, reply->BreakpointNumber(), reply->GetSourceFileLine()));
-            debugInfo.AddBreakpoint(bp);
+            const SourceFileLine& cFileLine = funCallRetPos.FunCallCFileLine();
+            if (!cFileLine.IsEmpty())
+            {
+                SharedGdbBreakReplyPtr reply = gdb.Break(cFileLine);
+                if (reply->NoSourceFile())
+                {
+                    throw std::runtime_error("break reply: no source file '" + funCallRetPos.CFileLine().SourceFilePath() + "'");
+                }
+                BreakpointPtr bp(new Breakpoint(BreakpointKind::temp, debugInfo.GetNextTempBreakpointNumber(), funCallRetPos, reply->BreakpointNumber(), reply->GetSourceFileLine()));
+                debugInfo.AddBreakpoint(bp);
+            }
         }
     }
     std::vector<SourceFileLine> cbrk;
@@ -442,13 +459,17 @@
         SourcePos funCallRetPos = debugInfo.PopPos();
         if (!funCallRetPos.IsMain())
         {
-            SharedGdbBreakReplyPtr reply = gdb.Break(funCallRetPos.FunCallCFileLine());
-            if (reply->NoSourceFile())
-            {
-                throw std::runtime_error("break reply: no source file '" + funCallRetPos.CFileLine().SourceFilePath() + "'");
-            }
-            BreakpointPtr bp(new Breakpoint(BreakpointKind::temp, debugInfo.GetNextTempBreakpointNumber(), funCallRetPos, reply->BreakpointNumber(), reply->GetSourceFileLine()));
-            debugInfo.AddBreakpoint(bp);
+            const SourceFileLine& cFileLine = funCallRetPos.FunCallCFileLine();
+            if (!cFileLine.IsEmpty())
+            {
+                SharedGdbBreakReplyPtr reply = gdb.Break(funCallRetPos.FunCallCFileLine());
+                if (reply->NoSourceFile())
+                {
+                    throw std::runtime_error("break reply: no source file '" + funCallRetPos.CFileLine().SourceFilePath() + "'");
+                }
+                BreakpointPtr bp(new Breakpoint(BreakpointKind::temp, debugInfo.GetNextTempBreakpointNumber(), funCallRetPos, reply->BreakpointNumber(), reply->GetSourceFileLine()));
+                debugInfo.AddBreakpoint(bp);
+            }
         }
     }
     SharedGdbContinueReplyPtr continueReply;
@@ -659,7 +680,7 @@
     }
     std::stringstream s;
     s << "breakpoints:\n";
-    const std::vector<BreakpointPtr>& bps = debugInfo.GetBreakpoints();
+    const std::vector<BreakpointPtr>& bps = debugInfo.GetUserBreakpoints();
     for (BreakpointPtr bp : bps)
     {
         s << bp->ToString() << "\n";
@@ -716,4 +737,44 @@
     }
 }
 
+SetBreakOnThrowCommand::SetBreakOnThrowCommand(bool enabled_): enabled(enabled_)
+{
+}
+
+void SetBreakOnThrowCommand::Execute(DebugInfo& debugInfo, Gdb& gdb, InputReader& inputReader, Shell& shell)
+{
+    if (debugInfo.GetState() == State::idle)
+    {
+        throw std::runtime_error("not started");
+    }
+    std::stringstream s;
+    if (enabled)
+    {
+        for (SourcePos throwPos : debugInfo.ThrowPos())
+        {
+            SourceFileLine cFileLine = throwPos.CFileLine();
+            SharedGdbBreakReplyPtr reply = gdb.Break(cFileLine);
+            if (!reply->NoSourceFile())
+            {
+                BreakpointPtr bp(new Breakpoint(BreakpointKind::throw_, debugInfo.GetNextUserBreakpointNumber(), throwPos, reply->BreakpointNumber(), reply->GetSourceFileLine()));
+                debugInfo.AddBreakpoint(bp);
+            }
+        }
+        s << "break on throw enabled\n";
+    }
+    else
+    {
+        for (BreakpointPtr throwBp : debugInfo.GetThrowBreakpoints())
+        {
+            if (!throwBp->Hidden())
+            {
+                SharedGdbClearReplyPtr clearReply = gdb.Clear(throwBp->GetGdbPos());
+            }
+            debugInfo.RemoveBreakpoint(throwBp);
+        }
+        s << "break on throw disabled\n";
+    }
+    WriteOutput(s.str(), OutputKind::reply);
+}
+
 } } // namespace Cm::Debugger