<commit_before>// Copyright 2020 Google LLC
//
// 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.

#include "string.h"
#include "LLDBBreakpointLocation.h"

#include <lldb/API/SBProcess.h>
#include <lldb/API/SBThread.h>
#include <msclr\marshal_cppstd.h>

#include "LLDBAddress.h"
#include "LLDBBreakpoint.h"
#include "lldb/API/SBAddress.h"
#include "lldb-eval/api.h"

namespace YetiVSI {
namespace DebugEngine {

LLDBBreakpointLocation::LLDBBreakpointLocation(
    lldb::SBBreakpointLocation location) {
  breakpointLocation_ = MakeUniquePtr<lldb::SBBreakpointLocation>(location);
}

void LLDBBreakpointLocation::SetEnabled(bool enabled) {
  breakpointLocation_->SetEnabled(enabled);
}

SbBreakpoint ^ LLDBBreakpointLocation::GetBreakpoint() {
  lldb::SBBreakpoint breakpoint = breakpointLocation_->GetBreakpoint();
  if (!breakpoint.IsValid()) {
    return nullptr;
  }
  return gcnew LLDBBreakpoint(breakpoint);
}

int LLDBBreakpointLocation::GetId() { return breakpointLocation_->GetID(); }

unsigned long long LLDBBreakpointLocation::GetLoadAddress() {
  return breakpointLocation_->GetLoadAddress();
}

SbAddress ^ LLDBBreakpointLocation::GetAddress() {
  lldb::SBAddress address = breakpointLocation_->GetAddress();
  if (address.IsValid()) {
    return gcnew LLDBAddress(address);
  } else {
    return nullptr;
  }
}

bool LldbEvalCallback(void* baton, lldb::SBProcess& process,
                      lldb::SBThread& thread,
                      lldb::SBBreakpointLocation& location) {
  const std::string* condition = static_cast<std::string*>(baton);
  lldb::SBError error;
  auto result = lldb_eval::EvaluateExpression(thread.GetSelectedFrame(),
                                              condition->c_str(), error);
  if (error.Fail()) {
    return false;
  }
  return result.GetValueAsUnsigned(0);
}

void LLDBBreakpointLocation::SetCondition(System::String^ condition) {
  auto conditionStr = msclr::interop::marshal_as<std::string>(condition);
  callbackBaton_ = MakeUniquePtr<std::string>(conditionStr);
  breakpointLocation_->SetCallback(LldbEvalCallback, (*callbackBaton_).Get());
}

void LLDBBreakpointLocation::SetIgnoreCount(unsigned int ignoreCount) {
  breakpointLocation_->SetIgnoreCount(ignoreCount);
}

uint32_t LLDBBreakpointLocation::GetHitCount() {
  return breakpointLocation_->GetHitCount();
}

}  // namespace DebugEngine
}  // namespace YetiVSI
<commit_msg>[Debugger] Fix conditional breakpoint with lldb-eval<commit_after>// Copyright 2020 Google LLC
//
// 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.

#include "string.h"
#include "LLDBBreakpointLocation.h"

#include <lldb/API/SBProcess.h>
#include <lldb/API/SBThread.h>
#include <msclr\marshal_cppstd.h>

#include "LLDBAddress.h"
#include "LLDBBreakpoint.h"
#include "lldb/API/SBAddress.h"
#include "lldb-eval/api.h"

namespace YetiVSI {
namespace DebugEngine {

LLDBBreakpointLocation::LLDBBreakpointLocation(
    lldb::SBBreakpointLocation location) {
  breakpointLocation_ = MakeUniquePtr<lldb::SBBreakpointLocation>(location);
}

void LLDBBreakpointLocation::SetEnabled(bool enabled) {
  breakpointLocation_->SetEnabled(enabled);
}

SbBreakpoint ^ LLDBBreakpointLocation::GetBreakpoint() {
  lldb::SBBreakpoint breakpoint = breakpointLocation_->GetBreakpoint();
  if (!breakpoint.IsValid()) {
    return nullptr;
  }
  return gcnew LLDBBreakpoint(breakpoint);
}

int LLDBBreakpointLocation::GetId() { return breakpointLocation_->GetID(); }

unsigned long long LLDBBreakpointLocation::GetLoadAddress() {
  return breakpointLocation_->GetLoadAddress();
}

SbAddress ^ LLDBBreakpointLocation::GetAddress() {
  lldb::SBAddress address = breakpointLocation_->GetAddress();
  if (address.IsValid()) {
    return gcnew LLDBAddress(address);
  } else {
    return nullptr;
  }
}

bool LldbEvalCallback(void* baton, lldb::SBProcess& process,
                      lldb::SBThread& thread,
                      lldb::SBBreakpointLocation& location) {
  const std::string* condition = static_cast<std::string*>(baton);
  lldb::SBError error;
  auto result = lldb_eval::EvaluateExpression(thread.GetSelectedFrame(),
                                              condition->c_str(), error);

  // We return true when an error occurs in the evaluation in order to match the behavior
  // of Visual Studio. A conditional breakpoint should only be skipped when the condition
  // is successfully evaluated and the result of the evaluation is false.
  if (error.Fail()) {
    return true;
  }
  return result.GetValueAsUnsigned(1);
}

void LLDBBreakpointLocation::SetCondition(System::String^ condition) {
  auto conditionStr = msclr::interop::marshal_as<std::string>(condition);
  callbackBaton_ = MakeUniquePtr<std::string>(conditionStr);
  breakpointLocation_->SetCallback(LldbEvalCallback, (*callbackBaton_).Get());
}

void LLDBBreakpointLocation::SetIgnoreCount(unsigned int ignoreCount) {
  breakpointLocation_->SetIgnoreCount(ignoreCount);
}

uint32_t LLDBBreakpointLocation::GetHitCount() {
  return breakpointLocation_->GetHitCount();
}

}  // namespace DebugEngine
}  // namespace YetiVSI

{'fraction_non_alphanumeric': 0.11085564132041387, 'fraction_numerical': 0.003613072754146822, 'mean_word_length': 4.675675675675675, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 35, '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': '5392451', 'n_tokens_mistral': 1809, 'n_tokens_neox': 1786, 'n_words': 441}