浏览代码

* fixed various debugger crashes after r29993 - read all information from
ExecAsyncOutput *before* calling DebuggerScreen, because DebuggerScreen may
call gdb commands, which will clear ExecAsyncOutput (or replace it with
something entirely different)

git-svn-id: trunk@30002 -

nickysn 10 年之前
父节点
当前提交
ec71e47b83
共有 1 个文件被更改,包括 27 次插入14 次删除
  1. 27 14
      ide/gdbmiint.pas

+ 27 - 14
ide/gdbmiint.pas

@@ -301,6 +301,9 @@ var
   Line: LongInt;
   FileName: string = '';
   LineNumber: LongInt = 0;
+  Addr: CORE_ADDR;
+  BreakpointNo: LongInt;
+  ExitCode: LongInt;
 begin
 Ignore:
   GDB.WaitForProgramStop;
@@ -341,25 +344,34 @@ Ignore:
     'end-stepping-range',
     'function-finished':
       begin
+        if StopReason = 'breakpoint-hit' then
+          BreakpointNo := GDB.ExecAsyncOutput.Parameters['bkptno'].AsLongInt
+        else if StopReason = 'watchpoint-trigger' then
+          BreakpointNo := GDB.ExecAsyncOutput.Parameters['wpt'].AsTuple['number'].AsLongInt
+        else if StopReason = 'access-watchpoint-trigger' then
+          BreakpointNo := GDB.ExecAsyncOutput.Parameters['hw-awpt'].AsTuple['number'].AsLongInt
+        else if StopReason = 'read-watchpoint-trigger' then
+          BreakpointNo := GDB.ExecAsyncOutput.Parameters['hw-rwpt'].AsTuple['number'].AsLongInt
+        else
+          BreakpointNo := -1;
+
+        Addr := GDB.ExecAsyncOutput.Parameters['frame'].AsTuple['addr'].AsPtrInt;
+        if Assigned(GDB.ExecAsyncOutput.Parameters['frame'].AsTuple['fullname']) then
+          FileName := GDB.ExecAsyncOutput.Parameters['frame'].AsTuple['fullname'].AsString;
+        if Assigned(GDB.ExecAsyncOutput.Parameters['frame'].AsTuple['line']) then
+          LineNumber := GDB.ExecAsyncOutput.Parameters['frame'].AsTuple['line'].AsLongInt;
+
         { this resets stop_breakpoint_number to zero, so it's important to set it *afterwards* }
+        { this also kills GDB.ExecAsyncOutput, because it may execute other gdb commands, so
+          make sure we have read all parameters that we need to local variables before that }
         DebuggerScreen;
 
         { now, set stop_breakpoint_number (if applicable) }
-        if StopReason = 'breakpoint-hit' then
-          stop_breakpoint_number := GDB.ExecAsyncOutput.Parameters['bkptno'].AsLongInt;
-        if StopReason = 'watchpoint-trigger' then
-          stop_breakpoint_number := GDB.ExecAsyncOutput.Parameters['wpt'].AsTuple['number'].AsLongInt;
-        if StopReason = 'access-watchpoint-trigger' then
-          stop_breakpoint_number := GDB.ExecAsyncOutput.Parameters['hw-awpt'].AsTuple['number'].AsLongInt;
-        if StopReason = 'read-watchpoint-trigger' then
-          stop_breakpoint_number := GDB.ExecAsyncOutput.Parameters['hw-rwpt'].AsTuple['number'].AsLongInt;
+        if BreakpointNo <> -1 then
+          stop_breakpoint_number := BreakpointNo;
 
         Debuggee_started := True;
-        current_pc := GDB.ExecAsyncOutput.Parameters['frame'].AsTuple['addr'].AsPtrInt;
-        if Assigned(GDB.ExecAsyncOutput.Parameters['frame'].AsTuple['fullname']) then
-          FileName := GDB.ExecAsyncOutput.Parameters['frame'].AsTuple['fullname'].AsString;
-        if Assigned(GDB.ExecAsyncOutput.Parameters['frame'].AsTuple['line']) then
-          LineNumber := GDB.ExecAsyncOutput.Parameters['frame'].AsTuple['line'].AsLongInt;
+        current_pc := Addr;
         DoSelectSourceLine(FileName, LineNumber);
       end;
     'exited-signalled':
@@ -376,10 +388,11 @@ Ignore:
       end;
     'exited':
       begin
+        ExitCode := GDB.ExecAsyncOutput.Parameters['exit-code'].AsLongInt;
         DebuggerScreen;
         current_pc := 0;
         Debuggee_started := False;
-        DoEndSession(GDB.ExecAsyncOutput.Parameters['exit-code'].AsLongInt);
+        DoEndSession(ExitCode);
       end;
     'exited-normally':
       begin