blob: b9db36a511322f990873436544755f5f307cfbab [file] [log] [blame]
// Copyright 2018 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.
#ifndef SRC_DEVELOPER_DEBUG_ZXDB_CLIENT_STEP_INTO_THREAD_CONTROLLER_H_
#define SRC_DEVELOPER_DEBUG_ZXDB_CLIENT_STEP_INTO_THREAD_CONTROLLER_H_
#include <optional>
#include "src/developer/debug/zxdb/client/function_return_info.h"
#include "src/developer/debug/zxdb/client/step_mode.h"
#include "src/developer/debug/zxdb/client/step_thread_controller.h"
#include "src/developer/debug/zxdb/client/thread_controller.h"
#include "src/developer/debug/zxdb/common/address_ranges.h"
#include "src/developer/debug/zxdb/symbols/file_line.h"
namespace zxdb {
class StepOverThreadController;
class StepThreadController;
// Implements a user-level "step into" command. On top of the regular step into, this provides
// an option to skip function prologues.
//
// Function prologues are the code at the beginning of a function that sets up the stack frame,
// and function parameters and backtraces might not be correct in this address range. Therefore,
// we usually want to step through this prologue when stepping into a new function so that the
// state is valid when the user inspects it.
class StepIntoThreadController : public ThreadController {
public:
// Constructor for kSourceLine and kInstruction modes. It will initialize itself to the thread's
// current position when the thread is attached.
//
// The function_return callback (if supplied) will be issued when the "step into" terminates with
// the completion of the function.
explicit StepIntoThreadController(StepMode mode, FunctionReturnCallback function_return = {});
// Steps given the source file/line.
explicit StepIntoThreadController(const FileLine& line,
FunctionReturnCallback function_return = {});
// Constructor for a kAddressRange mode (the mode is implicit). Continues execution as long as the
// IP is in range.
explicit StepIntoThreadController(AddressRanges ranges,
FunctionReturnCallback function_return = {});
~StepIntoThreadController() override;
// Controls whether this class skips function prologues that it might step into. See class
// comment above. Defaults to true.
bool should_skip_prologue() const { return should_skip_prologue_; }
void set_should_skip_prologue(bool skip) { should_skip_prologue_ = skip; }
// ThreadController implementation.
void InitWithThread(Thread* thread, fit::callback<void(const Err&)> cb) override;
ContinueOp GetContinueOp() override;
StopOp OnThreadStop(debug_ipc::ExceptionType stop_type,
const std::vector<fxl::WeakPtr<Breakpoint>>& hit_breakpoints) override;
const char* GetName() const override { return "Step Into"; }
private:
bool should_skip_prologue_ = true;
FrameFingerprint original_frame_fingerprint_;
std::unique_ptr<StepThreadController> step_into_;
std::unique_ptr<StepOverThreadController> skip_prologue_;
};
} // namespace zxdb
#endif // SRC_DEVELOPER_DEBUG_ZXDB_CLIENT_STEP_INTO_THREAD_CONTROLLER_H_