blob: 435441fafc9f500a73833175f79b0528c76b337e [file] [log] [blame]
// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/developer/debug/zxdb/console/commands/verb_steps.h"
#include <gtest/gtest.h>
#include "src/developer/debug/zxdb/client/mock_frame.h"
#include "src/developer/debug/zxdb/client/mock_remote_api.h"
#include "src/developer/debug/zxdb/client/substatement.h"
#include "src/developer/debug/zxdb/console/console_test.h"
namespace zxdb {
namespace {
class VerbSteps : public ConsoleTest {};
} // namespace
TEST_F(VerbSteps, Test) {
constexpr TargetPointer kLineBegin = 0x10000;
std::vector<std::unique_ptr<Frame>> frames;
frames.push_back(std::make_unique<MockFrame>(
&session(), thread(), Location(Location::State::kSymbolized, kLineBegin), 0x2000));
InjectExceptionWithStack(ConsoleTest::kProcessKoid, ConsoleTest::kThreadKoid,
debug_ipc::ExceptionType::kSingleStep, std::move(frames), true);
// Don't care about the stop notification.
loop().RunUntilNoTasks();
console().FlushOutputEvents();
std::vector<SubstatementCall> substatements;
constexpr TargetPointer kCall1At = kLineBegin + 4;
constexpr TargetPointer kCall1To = 0x20000;
SubstatementCall& ss1 = substatements.emplace_back();
ss1.call_addr = kCall1At;
ss1.call_dest = kCall1To;
constexpr TargetPointer kCall2At = kCall1At + 4;
constexpr TargetPointer kCall2To = 0x20020;
SubstatementCall& ss2 = substatements.emplace_back();
ss2.call_addr = kCall2At;
ss2.call_dest = kCall2To;
// This should show the menu with the above options.
RunVerbStepsWithSubstatements(thread(), substatements);
// We didn't supply any symbols so the destinations aren't symbolized.
auto event = console().GetOutputEvent();
EXPECT_EQ(MockConsole::OutputEvent::Type::kOutput, event.type);
EXPECT_EQ(
" 1 0x20000\n"
" 2 0x20020\n"
" quit\n",
event.output.AsString());
ASSERT_TRUE(console().SendModalReply("2"));
// That should continue.
EXPECT_EQ(1, mock_remote_api()->GetAndResetResumeCount());
// Here we test sending a totally different address outside of the step range and check that
// execution stopped. We assume the normal execution of the step controller for this is tested
// by its own test.
frames.push_back(std::make_unique<MockFrame>(
&session(), thread(), Location(Location::State::kSymbolized, kLineBegin + 0x1000), 0x2000));
InjectExceptionWithStack(ConsoleTest::kProcessKoid, ConsoleTest::kThreadKoid,
debug_ipc::ExceptionType::kSingleStep, std::move(frames), true);
// 0 resume count means stop.
EXPECT_EQ(0, mock_remote_api()->GetAndResetResumeCount());
}
} // namespace zxdb