Exemple #1
0
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public static void RequireOk(MiResultRecord resultRecord, string command)
        {
            if (resultRecord == null)
            {
                throw new ArgumentNullException("resultRecord");
            }
            else if (!CheckOk(resultRecord))
            {
                if (resultRecord.HasField("msg"))
                {
                    string errorReason = resultRecord ["msg"] [0].GetString();

                    throw new InvalidOperationException(string.Format("'{0}' failed with error: {1}", command, errorReason));
                }
                else
                {
                    throw new InvalidOperationException(string.Format("'{0}' failed with unspecified error", command));
                }
            }
        }
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    private void OnClientResultRecord (MiResultRecord resultRecord)
    {
      LoggingUtils.PrintFunction ();

      switch (resultRecord.Class)
      {
        case "done":
        case "running": // same behaviour (backward compatibility)
        {
          // 
          // "^done" [ "," results ]: The synchronous operation was successful, results are the return values.
          // 

          try
          {
            if (resultRecord.HasField ("reason"))
            {
              int stoppedIndex = resultRecord ["reason"].Count - 1;

              MiResultValue stoppedReason = resultRecord ["reason"] [stoppedIndex];

              switch (stoppedReason.GetString ())
              {
                case "exited":
                case "exited-normally":
                case "exited-signalled":
                {
                  if (m_interruptOperationCompleted != null)
                  {
                    m_interruptOperationCompleted.Set ();
                  }

                  ThreadPool.QueueUserWorkItem (delegate (object state)
                  {
                    try
                    {
                      LoggingUtils.RequireOk (Engine.Detach (NativeProgram.DebugProgram));
                    }
                    catch (Exception e)
                    {
                      LoggingUtils.HandleException (e);
                    }
                  });

                  break;
                }

                default:
                {
                  throw new NotImplementedException ();
                }
              }
            }
          }
          catch (Exception e)
          {
            LoggingUtils.HandleException (e);
          }

          break;
        }

        case "connected":
        {
          // 
          // ^connected: GDB has connected to a remote target.
          // 

          try
          {
            // 
            // If notifications are unsupported, we should assume that we need to refresh breakpoints when connected.
            //

            if (!GdbClient.GetClientFeatureSupported ("breakpoint-notifications"))
            {
              Engine.BreakpointManager.SetDirty (true);
            }

            Engine.BreakpointManager.RefreshBreakpoints ();
          }
          catch (Exception e)
          {
            LoggingUtils.HandleException (e);
          }

          break;
        }
        
        case "error":
        {
          // 
          // "^error" "," c-string: The operation failed. The c-string contains the corresponding error message.
          // 

          break;
        }
        
        case "exit":
        {
          // 
          // ^exit: GDB has terminated.
          // 

          break;
        }
      }
    }
Exemple #3
0
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public static bool CheckOk(MiResultRecord resultRecord)
        {
            return((resultRecord != null) && (!resultRecord.IsError()));
        }
Exemple #4
0
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public static MiRecord ParseGdbOutputRecord(string streamOutput)
        {
            if (string.IsNullOrEmpty(streamOutput))
            {
                return(null);
            }

            //
            // Process any leading 'async-record' or 'result-record' token.
            //

            int streamIndex = 0;

            if (streamOutput.StartsWith("(gdb)"))
            {
                //
                // GDB prompt. Waiting for input.
                //

                return(new MiPromptRecord());
            }
            else if (streamOutput [streamIndex] == '~')
            {
                //
                // Console stream record. Clears leading '~" and trailing '\\n"' characters.
                //

                ++streamIndex;

                StringBuilder consoleStreamBuilder = new StringBuilder(streamOutput.Trim(new char [] { '~', '\"' }));

                //consoleStreamBuilder.Replace ("\\n", "\n");

                return(new MiStreamRecord(MiStreamRecord.StreamType.Console, consoleStreamBuilder.ToString()));
            }
            else if (streamOutput [streamIndex] == '@')
            {
                //
                // Target stream record. Clears leading '@" and trailing '\\n"' characters.
                //

                ++streamIndex;

                StringBuilder targetStreamBuilder = new StringBuilder(streamOutput.Trim(new char [] { '@', '\"' }));

                //targetStreamBuilder.Replace ("\\n", "\n");

                return(new MiStreamRecord(MiStreamRecord.StreamType.Target, targetStreamBuilder.ToString()));
            }
            else if (streamOutput [streamIndex] == '&')
            {
                //
                // Log stream record. Clears leading '&" and trailing '\\n"' characters.
                //

                ++streamIndex;

                StringBuilder logStreamBuilder = new StringBuilder(streamOutput.Trim(new char [] { '&', '\"' }));

                //logStreamBuilder.Replace ("\\n", "\n");

                return(new MiStreamRecord(MiStreamRecord.StreamType.Log, logStreamBuilder.ToString()));
            }
            else
            {
                //
                // The following record types have associated key-pair data; identify the type and build a result collection.
                //

                string recordData = streamOutput.Substring(streamIndex);

                int bufferStartPos = 0;

                int bufferCurrentPos = bufferStartPos;

                char type = '^';

                uint token = 0;

                while (bufferCurrentPos < streamOutput.Length)
                {
                    if (((bufferCurrentPos + 1) >= streamOutput.Length) || (streamOutput [bufferCurrentPos + 1] == ','))
                    {
                        string clazz = recordData.Substring(bufferStartPos, (bufferCurrentPos + 1) - bufferStartPos);

                        string data = string.Empty;

                        if (((bufferCurrentPos + 1) < streamOutput.Length) && (streamOutput [bufferCurrentPos + 1] == ','))
                        {
                            data = recordData.Substring(bufferCurrentPos + 2);
                        }

                        MiRecord resultRecord = null;

                        List <MiResultValue> values = new List <MiResultValue> ();

                        try
                        {
                            ParseAllResults(data, ref values);
                        }
                        catch (Exception e)
                        {
                            LoggingUtils.HandleException(e);
                        }
                        finally
                        {
                            switch (type)
                            {
                            case '^': resultRecord = new MiResultRecord(token, clazz, values); break;

                            case '*': resultRecord = new MiAsyncRecord(MiAsyncRecord.AsyncType.Exec, token, clazz, values); break;

                            case '+': resultRecord = new MiAsyncRecord(MiAsyncRecord.AsyncType.Status, token, clazz, values); break;

                            case '=': resultRecord = new MiAsyncRecord(MiAsyncRecord.AsyncType.Notify, token, clazz, values); break;
                            }
                        }

                        return(resultRecord);
                    }
                    else if ((recordData [bufferCurrentPos] == '^') || (recordData [bufferCurrentPos] == '*') || (recordData [bufferCurrentPos] == '+') || (recordData [bufferCurrentPos] == '='))
                    {
                        type = recordData [bufferCurrentPos];

                        string stringToken = recordData.Substring(bufferStartPos, bufferCurrentPos);

                        if (!string.IsNullOrWhiteSpace(stringToken))
                        {
                            uint.TryParse(stringToken, out token);
                        }

                        bufferStartPos = ++bufferCurrentPos;
                    }

                    ++bufferCurrentPos;
                }

                return(null);
            }
        }
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    public static void RequireOk (MiResultRecord resultRecord, string command)
    {
      if (resultRecord == null)
      {
        throw new ArgumentNullException ("resultRecord");
      }
      else if (!CheckOk (resultRecord))
      {
        if (resultRecord.HasField ("msg"))
        {
          string errorReason = resultRecord ["msg"] [0].GetString ();

          throw new InvalidOperationException (string.Format ("'{0}' failed with error: {1}", command, errorReason));
        }
        else
        {
          throw new InvalidOperationException (string.Format ("'{0}' failed with unspecified error", command));
        }
      }
    }
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    public static bool CheckOk (MiResultRecord resultRecord)
    {
      return ((resultRecord != null) && (!resultRecord.IsError ()));
    }
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    public static MiRecord ParseGdbOutputRecord (string streamOutput)
    {
      if (string.IsNullOrEmpty (streamOutput))
      {
        return null;
      }

      // 
      // Process any leading 'async-record' or 'result-record' token.
      // 

      int streamIndex = 0;

      if (streamOutput.StartsWith ("(gdb)"))
      {
        // 
        // GDB prompt. Waiting for input.
        // 

        return new MiPromptRecord ();
      }
      else if (streamOutput [streamIndex] == '~')
      {
        // 
        // Console stream record. Clears leading '~" and trailing '\\n"' characters.
        // 

        ++streamIndex;

        StringBuilder consoleStreamBuilder = new StringBuilder (streamOutput.Trim (new char [] { '~', '\"' }));

        //consoleStreamBuilder.Replace ("\\n", "\n");

        return new MiStreamRecord (MiStreamRecord.StreamType.Console, consoleStreamBuilder.ToString ());
      }
      else if (streamOutput [streamIndex] == '@')
      {
        // 
        // Target stream record. Clears leading '@" and trailing '\\n"' characters.
        // 

        ++streamIndex;

        StringBuilder targetStreamBuilder = new StringBuilder (streamOutput.Trim (new char [] { '@', '\"' }));

        //targetStreamBuilder.Replace ("\\n", "\n");

        return new MiStreamRecord (MiStreamRecord.StreamType.Target, targetStreamBuilder.ToString ());
      }
      else if (streamOutput [streamIndex] == '&')
      {
        // 
        // Log stream record. Clears leading '&" and trailing '\\n"' characters.
        // 

        ++streamIndex;

        StringBuilder logStreamBuilder = new StringBuilder (streamOutput.Trim (new char [] { '&', '\"' }));

        //logStreamBuilder.Replace ("\\n", "\n");

        return new MiStreamRecord (MiStreamRecord.StreamType.Log, logStreamBuilder.ToString ());
      }
      else
      {
        // 
        // The following record types have associated key-pair data; identify the type and build a result collection.
        // 

        string recordData = streamOutput.Substring (streamIndex);

        int bufferStartPos = 0;

        int bufferCurrentPos = bufferStartPos;

        char type = '^';

        uint token = 0;

        while (bufferCurrentPos < streamOutput.Length)
        {
          if (((bufferCurrentPos + 1) >= streamOutput.Length) || (streamOutput [bufferCurrentPos + 1] == ','))
          {
            string clazz = recordData.Substring (bufferStartPos, (bufferCurrentPos + 1) - bufferStartPos);

            string data = string.Empty;

            if (((bufferCurrentPos + 1) < streamOutput.Length) && (streamOutput [bufferCurrentPos + 1] == ','))
            {
              data = recordData.Substring (bufferCurrentPos + 2);
            }

            MiRecord resultRecord = null;

            List<MiResultValue> values = new List<MiResultValue> ();

            try
            {
              ParseAllResults (data, ref values);
            }
            catch (Exception e)
            {
              LoggingUtils.HandleException (e);
            }
            finally
            {
              switch (type)
              {
                case '^': resultRecord = new MiResultRecord (token, clazz, values); break;
                case '*': resultRecord = new MiAsyncRecord (MiAsyncRecord.AsyncType.Exec, token, clazz, values); break;
                case '+': resultRecord = new MiAsyncRecord (MiAsyncRecord.AsyncType.Status, token, clazz, values); break;
                case '=': resultRecord = new MiAsyncRecord (MiAsyncRecord.AsyncType.Notify, token, clazz, values); break;
              }
            }

            return resultRecord;
          }
          else if ((recordData [bufferCurrentPos] == '^') || (recordData [bufferCurrentPos] == '*') || (recordData [bufferCurrentPos] == '+') || (recordData [bufferCurrentPos] == '='))
          {
            type = recordData [bufferCurrentPos];

            string stringToken = recordData.Substring (bufferStartPos, bufferCurrentPos);

            if (!string.IsNullOrWhiteSpace (stringToken))
            {
              uint.TryParse (stringToken, out token);
            }

            bufferStartPos = ++bufferCurrentPos;
          }

          ++bufferCurrentPos;
        }

        return null;
      }
    }