Exemplo n.º 1
0
  bool DoExecute(Args &command, CommandReturnObject &result) override {
    // No need to check "thread" for validity as eCommandRequiresThread ensures
    // it is valid
    Thread *thread = m_exe_ctx.GetThreadPtr();

    uint32_t frame_idx = UINT32_MAX;
    if (m_options.relative_frame_offset != INT32_MIN) {
      // The one and only argument is a signed relative frame index
      frame_idx = thread->GetSelectedFrameIndex();
      if (frame_idx == UINT32_MAX)
        frame_idx = 0;

      if (m_options.relative_frame_offset < 0) {
        if (static_cast<int32_t>(frame_idx) >= -m_options.relative_frame_offset)
          frame_idx += m_options.relative_frame_offset;
        else {
          if (frame_idx == 0) {
            // If you are already at the bottom of the stack, then just warn and
            // don't reset the frame.
            result.AppendError("Already at the bottom of the stack.");
            result.SetStatus(eReturnStatusFailed);
            return false;
          } else
            frame_idx = 0;
        }
      } else if (m_options.relative_frame_offset > 0) {
        // I don't want "up 20" where "20" takes you past the top of the stack
        // to produce
        // an error, but rather to just go to the top.  So I have to count the
        // stack here...
        const uint32_t num_frames = thread->GetStackFrameCount();
        if (static_cast<int32_t>(num_frames - frame_idx) >
            m_options.relative_frame_offset)
          frame_idx += m_options.relative_frame_offset;
        else {
          if (frame_idx == num_frames - 1) {
            // If we are already at the top of the stack, just warn and don't
            // reset the frame.
            result.AppendError("Already at the top of the stack.");
            result.SetStatus(eReturnStatusFailed);
            return false;
          } else
            frame_idx = num_frames - 1;
        }
      }
    } else {
      if (command.GetArgumentCount() == 1) {
        const char *frame_idx_cstr = command.GetArgumentAtIndex(0);
        bool success = false;
        frame_idx =
            StringConvert::ToUInt32(frame_idx_cstr, UINT32_MAX, 0, &success);
        if (!success) {
          result.AppendErrorWithFormat("invalid frame index argument '%s'.",
                                       frame_idx_cstr);
          result.SetStatus(eReturnStatusFailed);
          return false;
        }
      } else if (command.GetArgumentCount() == 0) {
        frame_idx = thread->GetSelectedFrameIndex();
        if (frame_idx == UINT32_MAX) {
          frame_idx = 0;
        }
      } else {
        result.AppendErrorWithFormat(
            "too many arguments; expected frame-index, saw '%s'.\n",
            command.GetArgumentAtIndex(0));
        m_options.GenerateOptionUsage(
            result.GetErrorStream(), this,
            GetCommandInterpreter().GetDebugger().GetTerminalWidth());
        return false;
      }
    }

    bool success = thread->SetSelectedFrameByIndexNoisily(
        frame_idx, result.GetOutputStream());
    if (success) {
      m_exe_ctx.SetFrameSP(thread->GetSelectedFrame());
      result.SetStatus(eReturnStatusSuccessFinishResult);
    } else {
      result.AppendErrorWithFormat("Frame index (%u) out of range.\n",
                                   frame_idx);
      result.SetStatus(eReturnStatusFailed);
    }

    return result.Succeeded();
  }
Exemplo n.º 2
0
    bool
    DoExecute (Args& command,
             CommandReturnObject &result)
    {
        ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
        Thread *thread = exe_ctx.GetThreadPtr();
        if (thread)
        {
            uint32_t frame_idx = UINT32_MAX;
            if (m_options.relative_frame_offset != INT32_MIN)
            {
                // The one and only argument is a signed relative frame index
                frame_idx = thread->GetSelectedFrameIndex ();
                if (frame_idx == UINT32_MAX)
                    frame_idx = 0;
                
                if (m_options.relative_frame_offset < 0)
                {
                    if (frame_idx >= -m_options.relative_frame_offset)
                        frame_idx += m_options.relative_frame_offset;
                    else
                    {
                        if (frame_idx == 0)
                        {
                            //If you are already at the bottom of the stack, then just warn and don't reset the frame.
                            result.AppendError("Already at the bottom of the stack");
                            result.SetStatus(eReturnStatusFailed);
                            return false;
                        }
                        else
                            frame_idx = 0;
                    }
                }
                else if (m_options.relative_frame_offset > 0)
                {
                    // I don't want "up 20" where "20" takes you past the top of the stack to produce
                    // an error, but rather to just go to the top.  So I have to count the stack here...
                    const uint32_t num_frames = thread->GetStackFrameCount();
                    if (num_frames - frame_idx > m_options.relative_frame_offset)
                        frame_idx += m_options.relative_frame_offset;
                    else
                    {
                        if (frame_idx == num_frames - 1)
                        {
                            //If we are already at the top of the stack, just warn and don't reset the frame.
                            result.AppendError("Already at the top of the stack");
                            result.SetStatus(eReturnStatusFailed);
                            return false;
                        }
                        else
                            frame_idx = num_frames - 1;
                    }
                }
            }
            else 
            {
                if (command.GetArgumentCount() == 1)
                {
                    const char *frame_idx_cstr = command.GetArgumentAtIndex(0);
                    frame_idx = Args::StringToUInt32 (frame_idx_cstr, UINT32_MAX, 0);
                }
                else if (command.GetArgumentCount() == 0)
                {
                    frame_idx = thread->GetSelectedFrameIndex ();
                    if (frame_idx == UINT32_MAX)
                    {
                        frame_idx = 0;
                    }
                }
                else
                {
                    result.AppendError ("invalid arguments.\n");
                    m_options.GenerateOptionUsage (result.GetErrorStream(), this);
                }
            }

            const bool broadcast = true;
            bool success = thread->SetSelectedFrameByIndex (frame_idx, broadcast);
            if (success)
            {
                exe_ctx.SetFrameSP(thread->GetSelectedFrame ());
                StackFrame *frame = exe_ctx.GetFramePtr();
                if (frame)
                {
                    bool already_shown = false;
                    SymbolContext frame_sc(frame->GetSymbolContext(eSymbolContextLineEntry));
                    if (m_interpreter.GetDebugger().GetUseExternalEditor() && frame_sc.line_entry.file && frame_sc.line_entry.line != 0)
                    {
                        already_shown = Host::OpenFileInExternalEditor (frame_sc.line_entry.file, frame_sc.line_entry.line);
                    }

                    bool show_frame_info = true;
                    bool show_source = !already_shown;
                    if (frame->GetStatus (result.GetOutputStream(), show_frame_info, show_source))
                    {
                        result.SetStatus (eReturnStatusSuccessFinishResult);
                        return result.Succeeded();
                    }
                }
            }
            result.AppendErrorWithFormat ("Frame index (%u) out of range.\n", frame_idx);
        }
        else
        {
            result.AppendError ("no current thread");
        }
        result.SetStatus (eReturnStatusFailed);
        return false;
    }