Index: src/plugins/debuggergdb/cdb_commands.h
===================================================================
--- src/plugins/debuggergdb/cdb_commands.h	(revision 6930)
+++ src/plugins/debuggergdb/cdb_commands.h	(working copy)
@@ -16,6 +16,7 @@
 #include "debuggertree.h"
 #include "backtracedlg.h"
 
+static wxRegEx reProcessInf(_T("id:[ \t]+([A-Fa-f0-9]+)[ \t]+create"));
 static wxRegEx reWatch(_T("(\\+0x[A-Fa-f0-9]+ )"));
 static wxRegEx reBT1(_T("([0-9]+) ([A-Fa-f0-9]+) ([A-Fa-f0-9]+) ([^[]*)"));
 static wxRegEx reBT2(_T("\\[([A-z]:)(.*) @ ([0-9]+)\\]"));
@@ -174,6 +175,40 @@
 };
 
 /**
+  * Command to find the PID of the active child
+  */
+  class CdbCmd_GetPID : public DebuggerCmd
+{
+    public:
+        /** @param file The file to debug. */
+        CdbCmd_GetPID(DebuggerDriver* driver)
+            : DebuggerCmd(driver)
+        {
+            m_Cmd << _T("|.");
+        }
+        void ParseOutput(const wxString& output)
+        {
+            // Output:
+            // <decimal process num> id: <hex PID> create name: <process name>
+            wxArrayString lines = GetArrayFromString(output, _T('\n'));
+            for (unsigned int i = 0; i < lines.GetCount(); ++i)
+            {
+            	if (reProcessInf.Matches(lines[i]))
+				{
+					wxString hexID = reProcessInf.GetMatch(lines[i],1);
+
+					long pid;
+					if (hexID.ToLong(&pid,16))
+					{
+						m_pDriver->SetChildPID(pid);
+					}
+				}
+            }
+        }
+};
+
+
+/**
   * Command to add a breakpoint.
   */
 class CdbCmd_AddBreakpoint : public DebuggerCmd
Index: src/plugins/debuggergdb/cdb_driver.cpp
===================================================================
--- src/plugins/debuggergdb/cdb_driver.cpp	(revision 6930)
+++ src/plugins/debuggergdb/cdb_driver.cpp	(working copy)
@@ -15,8 +15,11 @@
 #include <globals.h>
 #include <infowindow.h>
 
-#define CDB_PROMPT _T("0:000>")
+#define ENABLE_WORKINGDIR_WORKAROUND
+#define CDB_STACKTRACE _T("ChildEBP")
+#define CDB_FRAMESWITCH _T("CBFrameSwitch")
 
+static wxRegEx rePrompt(_T("([0-9]+:){1,2}[0-9]+>"));
 static wxRegEx reBP(_T("Breakpoint ([0-9]+) hit"));
 // one stack frame (to access current file; is there another way???)
 //  # ChildEBP RetAddr
@@ -24,7 +27,8 @@
 static wxRegEx reFile(_T("[ \t]([A-z]+.*)[ \t]+\\[([A-z]:)(.*) @ ([0-9]+)\\]"));
 
 CDB_driver::CDB_driver(DebuggerGDB* plugin)
-    : DebuggerDriver(plugin)
+    : DebuggerDriver(plugin),
+    m_Debuggee(wxEmptyString)
 {
     //ctor
 }
@@ -63,8 +67,16 @@
     cmd << _T(' ') << debuggee;
 
     if (!m_WorkingDir.IsEmpty())
+	{
         wxSetWorkingDirectory(m_WorkingDir);
 
+#ifdef ENABLE_WORKINGDIR_WORKAROUND
+		// Because of the lack of ChDir functionality for a process which has already been launched,
+		// do a dodgy workaround by starting with a dummy version of the process, then starting in the right folder later.
+		m_Debuggee.assign(debuggee);
+#endif
+	}
+
     return cmd;
 }
 
@@ -104,7 +116,28 @@
 
 void CDB_driver::Prepare(ProjectBuildTarget* /*target*/, bool /*isConsole*/)
 {
-    // default initialization
+	// CDB outputs a lot of spam to begin with, which mucks up output parsing without a dummy command first
+	m_QueueBusy = true;
+	QueueCommand(new DebuggerCmd(this,_T(".echo Clear initial spam")));
+
+#ifdef ENABLE_WORKINGDIR_WORKAROUND
+	if (!m_Debuggee.IsEmpty())
+	{
+		// Workaround for setting the correct working dir:
+		wxString cmd = _T(".kill; .createdir ");
+		cmd << m_WorkingDir;
+		QueueCommand(new DebuggerCmd(this,cmd)); // Kill the process and CD to the right place
+
+		cmd = _T(".create ");
+		cmd << m_Debuggee << _T("; g");
+		QueueCommand(new DebuggerCmd(this,cmd)); // Restart the process in the correct directory
+
+		m_Debuggee.Clear();
+	}
+#endif
+
+	// Either way, get the PID of the child
+	QueueCommand(new CdbCmd_GetPID(this));
 }
 
 void CDB_driver::Start(bool /*breakOnEntry*/)
@@ -179,9 +212,11 @@
     QueueCommand(new CdbCmd_InfoRegisters(this, m_pCPURegisters));
 }
 
-void CDB_driver::SwitchToFrame(size_t /*number*/)
+void CDB_driver::SwitchToFrame(size_t number)
 {
-    NOT_IMPLEMENTED();
+	wxString cmd = _T(".echo "); // Echo in our trace token to tell ParseOutput to update the frame.
+	cmd << CDB_FRAMESWITCH << _T("; .frame ") << number;
+    QueueCommand(new DebuggerCmd(this, cmd));
 }
 
 void CDB_driver::SetVarValue(const wxString& /*var*/, const wxString& /*value*/)
@@ -268,26 +303,32 @@
 {
     m_Cursor.changed = false;
     static wxString buffer;
+
     buffer << output << _T('\n');
 
     m_pDBG->DebugLog(output);
 
-    int idx = buffer.First(CDB_PROMPT);
-    if (idx != wxNOT_FOUND)
-    {
+	if (rePrompt.Matches(buffer))
+	{
+		int idx = buffer.First(rePrompt.GetMatch(buffer));
+		cbAssert(idx != wxNOT_FOUND);
+
         m_ProgramIsStopped = true;
         m_QueueBusy = false;
         DebuggerCmd* cmd = CurrentCommand();
         if (cmd)
         {
-//            Log(_T("Command parsing output: ") + buffer.Left(idx));
-            RemoveTopCommand(false);
             buffer.Remove(idx);
             if (buffer[buffer.Length() - 1] == _T('\n'))
                 buffer.Remove(buffer.Length() - 1);
-            cmd->ParseOutput(buffer.Left(idx));
-            delete cmd;
-            RunQueue();
+
+
+			//Log(_T("* Command: ") + cmd->m_Cmd);
+			//Log(_T("* Parsing output: \n") + buffer.Left(idx));
+			RemoveTopCommand(false);
+			cmd->ParseOutput(buffer.Left(idx));
+			delete cmd;
+			RunQueue();
         }
     }
     else
@@ -331,6 +372,27 @@
             break;
         }
 
+        else if (lines[i].Contains(_T("Break instruction exception")))
+        {
+        	// Code breakpoint
+            m_pDBG->BringAppToFront();
+            if (IsWindowReallyShown(m_pBacktrace))
+            {
+                // don't ask; it's already shown
+                // just grab the user's attention
+                Backtrace();
+            }
+            else
+            {
+                // show the backtrace window
+                CodeBlocksDockEvent evt(cbEVT_SHOW_DOCK_WINDOW);
+                evt.pWindow = m_pBacktrace;
+                Manager::Get()->ProcessEvent(evt);
+                Backtrace();
+            }
+            break;
+        }
+
         // Breakpoint 0 hit
         // >   38:     if (!RegisterClassEx (&wincl))
         else if (reBP.Matches(lines[i]))
@@ -357,20 +419,43 @@
             NotifyCursorChanged();
         }
         // one stack frame (to access current file; is there another way???)
-        else if (lines[i].Contains(_T("ChildEBP")))
+        else if (lines[i].Contains(CDB_STACKTRACE))
         {
             if (reFile.Matches(lines[i + 1]))
             {
-                ++i; // we 're interested in the next line
-                m_Cursor.address = reFile.GetMatch(lines[i], 1);
-                m_Cursor.file = reFile.GetMatch(lines[i], 2) + reFile.GetMatch(lines[i], 3);
-//                if (m_Cursor.file.Last() == _T(' '))
-//                    m_Cursor.file.RemoveLast(); // see regex reFile for the reason
-                reFile.GetMatch(lines[i], 4).ToLong(&m_Cursor.line);
-                m_Cursor.changed = true;
-                NotifyCursorChanged();
+            	ParseStackFrame(lines[i + 1], true);
             }
         }
+        else if (lines[i].Contains(CDB_FRAMESWITCH))
+        {
+           if (reFile.Matches(lines[i + 1]))
+            {
+            	ParseStackFrame(lines[i + 1], false);
+            }
+        }
     }
     buffer.Clear();
 }
+
+void CDB_driver::ParseStackFrame(const wxString& frame, bool updateBacktrace)
+{
+	m_Cursor.address = reFile.GetMatch(frame, 1);
+	m_Cursor.file = reFile.GetMatch(frame, 2) + reFile.GetMatch(frame, 3);
+//                if (m_Cursor.file.Last() == _T(' '))
+//                    m_Cursor.file.RemoveLast(); // see regex reFile for the reason
+	reFile.GetMatch(frame, 4).ToLong(&m_Cursor.line);
+	m_Cursor.changed = true;
+
+	if (updateBacktrace)
+	{
+		NotifyCursorChanged();
+	}
+	else
+	{
+		// Disable backtrace while we update the cursor or it will reset the current frame.
+		BacktraceDlg* backtrace = m_pBacktrace;
+		m_pBacktrace = 0;
+		NotifyCursorChanged();
+		m_pBacktrace = backtrace;
+	}
+}
Index: src/plugins/debuggergdb/cdb_driver.h
===================================================================
--- src/plugins/debuggergdb/cdb_driver.h	(revision 6930)
+++ src/plugins/debuggergdb/cdb_driver.h	(working copy)
@@ -47,8 +47,13 @@
         virtual void EvaluateSymbol(const wxString& symbol, const wxRect& tipRect);
         virtual void UpdateWatches(bool doLocals, bool doArgs, DebuggerTree* tree);
         virtual void ParseOutput(const wxString& output);
+
+        void ParseStackFrame(const wxString& frame, bool updateBacktrace);
+
     protected:
     private:
+    	wxString m_Debuggee;
+    	int m_Frame;
 };
 
 #endif // CDB_DRIVER_H
