<commit_before>// Copyright 2017 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef DBG_STACK_FRAME_H_
#define DBG_STACK_FRAME_H_

#include <memory>
#include <queue>
#include <sstream>
#include <string>
#include <tuple>

#include "breakpoint.pb.h"
#include "constants.h"
#include "cor.h"
#include "cordebug.h"
#include "dbg_object.h"
#include "document_index.h"

namespace google_cloud_debugger {

typedef std::tuple<std::string, std::shared_ptr<DbgObject>,
                   std::unique_ptr<std::ostringstream>>
    VariableTuple;

class DebuggerCallback;
class IEvalCoordinator;

// This class is represents a stack frame at a breakpoint.
// It is used to populate and print out variables and method arguments
// at a stack frame. It also stores useful debugging information like
// method name, class name, file name and line number.
class DbgStackFrame {
 public:
  // Populate method_name_, file_name_, line_number_ and breakpoint_id_.
  // Also populate local variables and method arguments into variables_
  // vectors.
  HRESULT Initialize(
      ICorDebugILFrame *il_frame,
      const std::vector<google_cloud_debugger_portable_pdb::LocalVariableInfo>
          &variable_infos,
      mdMethodDef method_token, IMetaDataImport *metadata_import);

  // Populates the StackFrame object with local variables, method arguments,
  // method name, class name, file name and line number.
  // This method may perform function evaluation using eval_coordinator.
  HRESULT PopulateStackFrame(
      google::cloud::diagnostics::debug::StackFrame *stack_frame,
      IEvalCoordinator *eval_coordinator) const;

  // Sets how deep an object will be inspected.
  void SetObjectInspectionDepth(int depth);

  // Sets the name of the file this stack frame is in.
  void SetFile(const std::string &file_name) { file_name_ = file_name; }

  // Sets the name of the module this stack frame is in.
  void SetModuleName(const std::vector<WCHAR> &module_name) {
    module_name_ = ConvertWCharPtrToString(module_name);
  }

  // Sets the name of the method this stack frame is in.
  void SetMethod(const std::vector<WCHAR> &method_name) {
    method_name_ = ConvertWCharPtrToString(method_name);
  }

  // Sets the name of the class this stack frame is in.
  void SetClass(const std::vector<WCHAR> &class_name) {
    class_name_ = ConvertWCharPtrToString(class_name);
  }

  // Sets the line number this stack frame is on.
  void SetLineNumber(std::uint32_t line_number) { line_number_ = line_number; }

  // Sets the virtual address of the function this stack frame is in.
  void SetFuncVirtualAddr(ULONG32 addr) { func_virtual_addr_ = addr; }

  // Gets the module this stack frame is in.
  std::string GetModule() const { return module_name_; }

  // Gets the short form of the module name with all the file path stripped.
  // For example, C:\Test\MyModule.dll becomes MyModule.dll.
  std::string GetShortModuleName() const;

  // Gets the name of the class of this stack frame.
  std::string GetClass() const { return class_name_; }

  // Gets the name of the method of this stack frame.
  std::string GetMethod() const { return method_name_; }

  // Gets the name of the file of this stack frame.
  std::string GetFile() const { return file_name_; }

  // Gets the line number this stack frame is on.
  std::uint32_t GetLineNumber() const { return line_number_; }

  // Gets the virtual address of the function this stack frame is in.
  ULONG32 GetFuncVirtualAddr() const { return func_virtual_addr_; }

  // Returns if this is just an empty frame with no information.
  bool IsEmpty() { return empty_; }

  // Sets whether this is an empty frame.
  void SetEmpty(bool empty) { empty_ = empty; }

 private:
  // Extract local variables from local_enum.
  // DbgBreakpoint object is used to get the variables' names.
  HRESULT ProcessLocalVariables(
      ICorDebugValueEnum *local_enum,
      const std::vector<google_cloud_debugger_portable_pdb::LocalVariableInfo>
          &variable_infos);

  // Extract method arguments from method_arg_enum.
  // DbgBreakpoint and IMetaDataImport objects are used
  // to get the variables' names.
  HRESULT ProcessMethodArguments(ICorDebugValueEnum *method_arg_enum,
                                 mdMethodDef method_token,
                                 IMetaDataImport *metadata_import);

  // Tuple that contains variable's name, variable's value and the error stream.
  std::vector<VariableTuple> variables_;

  // Tuple that contains method argument's name, value and the error stream.
  std::vector<VariableTuple> method_arguments_;

  // Determines how deep to inspect the object.
  int object_depth_ = kDefaultObjectEvalDepth;

  // Name of the method the variables are in.
  std::string method_name_;

  // Name of the module the variables are in.
  std::string module_name_;

  // Name of the class the variables are in.
  std::string class_name_;

  // Name of the file the variables are in.
  std::string file_name_;

  // Virtual address of the function this stack frame is in.
  ULONG32 func_virtual_addr_ = 0;

  // The line number where the variables are in.
  std::uint32_t line_number_ = 0;

  // True if this is an empty frame with no information.
  bool empty_ = false;

  // Maximum byte size of a stack frame proto.
  static const std::uint32_t kStackFrameSize = 15360;
};

}  //  namespace google_cloud_debugger

#endif  //  DBG_STACK_FRAME_H_<commit_msg>Fix comment about stack frame size<commit_after>// Copyright 2017 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef DBG_STACK_FRAME_H_
#define DBG_STACK_FRAME_H_

#include <memory>
#include <queue>
#include <sstream>
#include <string>
#include <tuple>

#include "breakpoint.pb.h"
#include "constants.h"
#include "cor.h"
#include "cordebug.h"
#include "dbg_object.h"
#include "document_index.h"

namespace google_cloud_debugger {

typedef std::tuple<std::string, std::shared_ptr<DbgObject>,
                   std::unique_ptr<std::ostringstream>>
    VariableTuple;

class DebuggerCallback;
class IEvalCoordinator;

// This class is represents a stack frame at a breakpoint.
// It is used to populate and print out variables and method arguments
// at a stack frame. It also stores useful debugging information like
// method name, class name, file name and line number.
class DbgStackFrame {
 public:
  // Populate method_name_, file_name_, line_number_ and breakpoint_id_.
  // Also populate local variables and method arguments into variables_
  // vectors.
  HRESULT Initialize(
      ICorDebugILFrame *il_frame,
      const std::vector<google_cloud_debugger_portable_pdb::LocalVariableInfo>
          &variable_infos,
      mdMethodDef method_token, IMetaDataImport *metadata_import);

  // Populates the StackFrame object with local variables, method arguments,
  // method name, class name, file name and line number.
  // This method may perform function evaluation using eval_coordinator.
  HRESULT PopulateStackFrame(
      google::cloud::diagnostics::debug::StackFrame *stack_frame,
      IEvalCoordinator *eval_coordinator) const;

  // Sets how deep an object will be inspected.
  void SetObjectInspectionDepth(int depth);

  // Sets the name of the file this stack frame is in.
  void SetFile(const std::string &file_name) { file_name_ = file_name; }

  // Sets the name of the module this stack frame is in.
  void SetModuleName(const std::vector<WCHAR> &module_name) {
    module_name_ = ConvertWCharPtrToString(module_name);
  }

  // Sets the name of the method this stack frame is in.
  void SetMethod(const std::vector<WCHAR> &method_name) {
    method_name_ = ConvertWCharPtrToString(method_name);
  }

  // Sets the name of the class this stack frame is in.
  void SetClass(const std::vector<WCHAR> &class_name) {
    class_name_ = ConvertWCharPtrToString(class_name);
  }

  // Sets the line number this stack frame is on.
  void SetLineNumber(std::uint32_t line_number) { line_number_ = line_number; }

  // Sets the virtual address of the function this stack frame is in.
  void SetFuncVirtualAddr(ULONG32 addr) { func_virtual_addr_ = addr; }

  // Gets the module this stack frame is in.
  std::string GetModule() const { return module_name_; }

  // Gets the short form of the module name with all the file path stripped.
  // For example, C:\Test\MyModule.dll becomes MyModule.dll.
  std::string GetShortModuleName() const;

  // Gets the name of the class of this stack frame.
  std::string GetClass() const { return class_name_; }

  // Gets the name of the method of this stack frame.
  std::string GetMethod() const { return method_name_; }

  // Gets the name of the file of this stack frame.
  std::string GetFile() const { return file_name_; }

  // Gets the line number this stack frame is on.
  std::uint32_t GetLineNumber() const { return line_number_; }

  // Gets the virtual address of the function this stack frame is in.
  ULONG32 GetFuncVirtualAddr() const { return func_virtual_addr_; }

  // Returns if this is just an empty frame with no information.
  bool IsEmpty() { return empty_; }

  // Sets whether this is an empty frame.
  void SetEmpty(bool empty) { empty_ = empty; }

 private:
  // Extract local variables from local_enum.
  // DbgBreakpoint object is used to get the variables' names.
  HRESULT ProcessLocalVariables(
      ICorDebugValueEnum *local_enum,
      const std::vector<google_cloud_debugger_portable_pdb::LocalVariableInfo>
          &variable_infos);

  // Extract method arguments from method_arg_enum.
  // DbgBreakpoint and IMetaDataImport objects are used
  // to get the variables' names.
  HRESULT ProcessMethodArguments(ICorDebugValueEnum *method_arg_enum,
                                 mdMethodDef method_token,
                                 IMetaDataImport *metadata_import);

  // Tuple that contains variable's name, variable's value and the error stream.
  std::vector<VariableTuple> variables_;

  // Tuple that contains method argument's name, value and the error stream.
  std::vector<VariableTuple> method_arguments_;

  // Determines how deep to inspect the object.
  int object_depth_ = kDefaultObjectEvalDepth;

  // Name of the method the variables are in.
  std::string method_name_;

  // Name of the module the variables are in.
  std::string module_name_;

  // Name of the class the variables are in.
  std::string class_name_;

  // Name of the file the variables are in.
  std::string file_name_;

  // Virtual address of the function this stack frame is in.
  ULONG32 func_virtual_addr_ = 0;

  // The line number where the variables are in.
  std::uint32_t line_number_ = 0;

  // True if this is an empty frame with no information.
  bool empty_ = false;

  // Maximum size of a stack frame proto in bytes (15360 bytes = 15kb).
  // For a breakpoint, we process a maximum of 4 stack frames with variables,
  // and the overall maximum size of a breakpoint is 64kb. So we give
  // each stack frame 15kb.
  static const std::uint32_t kStackFrameSize = 15360;
};

}  //  namespace google_cloud_debugger

#endif  //  DBG_STACK_FRAME_H_
{'fraction_non_alphanumeric': 0.08020730503455084, 'fraction_numerical': 0.0057584731819677526, 'mean_word_length': 3.6119119878603945, 'pattern_counts': {'":': 0, '<': 33, '<?xml version=': 0, '>': 33, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5440315', 'n_tokens_mistral': 3531, 'n_tokens_neox': 3396, 'n_words': 1340}